Liedkampf/server/youtube-api.js

130 lines
3.7 KiB
JavaScript

const { google } = require('googleapis');
const axios = require('axios');
// You would need to obtain a YouTube API key from Google Cloud Console
// For now, we'll use a placeholder - you'll need to replace this with your actual API key
const API_KEY = process.env.YOUTUBE_API_KEY || 'NO';
// Initialize the YouTube API client
const youtube = google.youtube({
version: 'v3',
auth: API_KEY
});
/**
* Extract YouTube video ID from various formats of YouTube links
* @param {string} url - YouTube URL in any format
* @returns {string|null} YouTube video ID or null if invalid
*/
function extractVideoId(url) {
if (!url) return null;
// Handle different YouTube URL formats
const patterns = [
/(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?v=([^&]+)/,
/(?:https?:\/\/)?(?:www\.)?youtube\.com\/embed\/([^/?]+)/,
/(?:https?:\/\/)?(?:www\.)?youtu\.be\/([^/?]+)/
];
for (const pattern of patterns) {
const match = url.match(pattern);
if (match && match[1]) {
return match[1];
}
}
return null;
}
/**
* Get video metadata from YouTube API
* @param {string} videoId - YouTube video ID
* @returns {Promise<Object>} Video metadata including title and channel
*/
async function getVideoMetadata(videoId) {
try {
// Try using the googleapis library first
try {
const response = await youtube.videos.list({
part: 'snippet',
id: videoId
});
const video = response.data.items[0];
if (video && video.snippet) {
return {
title: video.snippet.title,
artist: video.snippet.channelTitle,
thumbnail: video.snippet.thumbnails.default.url
};
}
} catch (googleApiError) {
console.log('Google API error, falling back to alternative method:', googleApiError.message);
// If googleapis fails (e.g., due to API key issues), fall back to a simplified approach
const response = await axios.get(`https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoId}&format=json`);
if (response.data) {
const title = response.data.title || '';
// Try to extract artist from title (common format is "Artist - Title")
const parts = title.split(' - ');
const artist = parts.length > 1 ? parts[0] : response.data.author_name;
return {
title: parts.length > 1 ? parts.slice(1).join(' - ') : title,
artist: artist,
thumbnail: response.data.thumbnail_url
};
}
}
// If all methods fail, return default values
return {
title: 'Unknown Title',
artist: 'Unknown Artist',
thumbnail: null
};
} catch (error) {
console.error('Error fetching video metadata:', error.message);
return {
title: 'Unknown Title',
artist: 'Unknown Artist',
thumbnail: null
};
}
}
/**
* Search for songs on YouTube
* @param {string} query - Search query for YouTube
* @returns {Promise<Array>} List of search results
*/
async function searchYouTube(query) {
try {
const response = await youtube.search.list({
part: 'snippet',
q: query,
type: 'video',
maxResults: 5,
videoCategoryId: '10' // Category ID for Music
});
return response.data.items.map(item => ({
id: item.id.videoId,
title: item.snippet.title,
artist: item.snippet.channelTitle,
thumbnail: item.snippet.thumbnails.default.url,
youtubeLink: `https://www.youtube.com/watch?v=${item.id.videoId}`
}));
} catch (error) {
console.error('Error searching YouTube:', error.message);
return [];
}
}
module.exports = {
extractVideoId,
getVideoMetadata,
searchYouTube
};