'use server'; import axios from 'axios'; import path from 'path'; // Google Drive folder IDs const FEMALE_VOICES_FOLDER_ID = '1AWocbgIzGOjA8nBo18WJyTPvDZueN1hH'; const MAIN_FOLDER_ID = '1AWocbgIzGOjA8nBo18WJyTPvDZueN1hH'; // Parent folder containing MALE_VOICES and FEMALE_VOICES interface DriveFile { id: string; name: string; mimeType: string; } interface DriveFolder { id: string; name: string; files: DriveFile[]; } /** * Get direct download URL for a Google Drive file */ function getGoogleDriveDirectLink(fileId: string): string { return `https://drive.google.com/uc?export=download&id=${fileId}`; } /** * Fetch files from a Google Drive folder */ async function fetchFilesFromFolder(folderId: string): Promise { try { // Use the Google Drive API to list files in the folder // Note: This would typically require authentication with an API key in production // This is a simplified example that assumes public folder access const response = await axios.get( `https://www.googleapis.com/drive/v3/files?q='${folderId}'+in+parents&fields=files(id,name,mimeType)` ); const files = response.data.files; return { id: folderId, name: folderId, // Using ID as name since we can't get folder name directly files: files }; } catch (error) { console.error('Error fetching files from Google Drive:', error); return null; } } /** * Fetch all voice folders and audio files from Google Drive */ export async function fetchDriveAudioFiles(): Promise<[string, string, string, boolean][] | null> { const audioPairs: [string, string, string, boolean][] = []; try { // Fetch main folder to get MALE_VOICES and FEMALE_VOICES folders const mainFolder = await fetchFilesFromFolder(MAIN_FOLDER_ID); if (!mainFolder) { console.error('Could not fetch main folder from Google Drive'); return null; } // Find MALE_VOICES and FEMALE_VOICES folders const maleFolderObj = mainFolder.files.find(file => file.mimeType === 'application/vnd.google-apps.folder' && file.name === 'MALE_VOICES' ); const femaleFolderObj = mainFolder.files.find(file => file.mimeType === 'application/vnd.google-apps.folder' && file.name === 'FEMALE_VOICES' ); // Process both folders const foldersToProcess = []; if (maleFolderObj) foldersToProcess.push(maleFolderObj); if (femaleFolderObj) foldersToProcess.push(femaleFolderObj); // If we couldn't find specific folders, try to process all folders in the main directory if (foldersToProcess.length === 0) { foldersToProcess.push(...mainFolder.files.filter(file => file.mimeType === 'application/vnd.google-apps.folder' )); } // Process each voice folder for (const folderObj of foldersToProcess) { const folderContents = await fetchFilesFromFolder(folderObj.id); if (!folderContents) continue; // Look for voice folders inside MALE_VOICES and FEMALE_VOICES const voiceFolders = folderContents.files.filter(file => file.mimeType === 'application/vnd.google-apps.folder' ); // If no voice subfolders, check if the current folder itself contains audio files if (voiceFolders.length === 0) { await processVoiceFolder(folderObj, folderContents.files, audioPairs); } else { // Process each voice subfolder for (const voiceFolder of voiceFolders) { const voiceFiles = await fetchFilesFromFolder(voiceFolder.id); if (!voiceFiles) continue; await processVoiceFolder(voiceFolder, voiceFiles.files, audioPairs); } } } return audioPairs.length > 0 ? audioPairs : null; } catch (error) { console.error('Error fetching audio files from Google Drive:', error); return null; } } // Helper function to process a voice folder async function processVoiceFolder( folder: DriveFile, files: DriveFile[], audioPairs: [string, string, string, boolean][] ) { // Look for improved.wav and raw.wav in the folder const improvedFile = files.find(file => file.name === 'improved.wav'); const rawFile = files.find(file => file.name === 'raw.wav'); if (improvedFile && rawFile) { // Extract voice name from folder name const voiceName = folder.name; // Randomly determine order presentation (but track original files) const shouldSwap = Math.random() > 0.5; // Get direct download URLs const improvedUrl = getGoogleDriveDirectLink(improvedFile.id); const rawUrl = getGoogleDriveDirectLink(rawFile.id); // If we swap, raw becomes shown first (A), but we track this with boolean if (shouldSwap) { audioPairs.push([rawUrl, improvedUrl, voiceName, true]); // swapped = true } else { audioPairs.push([improvedUrl, rawUrl, voiceName, false]); // swapped = false } } }