Spaces:
Sleeping
Sleeping
File size: 4,959 Bytes
8c85576 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | '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<DriveFolder | null> {
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
}
}
} |