Some checks failed
Publish Docker image / Push Docker image to Docker Hub (push) Failing after 7m12s
130 lines
3.7 KiB
JavaScript
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
|
|
};
|