1-
21import dotenv from 'dotenv' ;
2+ import { initializeApp } from 'firebase/app' ;
3+ import { getStorage , ref , uploadBytes , getDownloadURL } from 'firebase/storage' ;
4+ import { getFirebaseConfig } from './firebase-config.js' ;
35dotenv . config ( ) ;
46
7+ // Initialize Firebase when needed
8+ let firebaseApp ;
9+ let storage ;
10+
11+ function initializeFirebase ( ) {
12+ if ( ! firebaseApp ) {
13+ firebaseApp = initializeApp ( getFirebaseConfig ( ) ) ;
14+ storage = getStorage ( firebaseApp ) ;
15+ }
16+ return { firebaseApp, storage } ;
17+ }
18+
19+ // Generate a unique filename with timestamp and random string
20+ const generateUniqueFilename = ( originalName ) => {
21+ const timestamp = Date . now ( ) ;
22+ const randomString = Math . random ( ) . toString ( 36 ) . substring ( 2 , 8 ) ;
23+ const fileExtension = originalName ?. split ( '.' ) . pop ( ) || 'audio' ;
24+ return `audio_${ timestamp } _${ randomString } .${ fileExtension } ` ;
25+ } ;
26+
27+ // Function to upload base64 data to Firebase Storage
28+ async function uploadBase64ToFirebase ( base64Data , mimeType = 'audio/mpeg' ) {
29+ const { storage } = initializeFirebase ( ) ;
30+
31+ // Strip the data URL prefix if present
32+ const base64WithoutPrefix = base64Data . replace ( / ^ d a t a : .* ; b a s e 6 4 , / , '' ) ;
33+
34+ // Convert base64 to a Blob
35+ const byteCharacters = atob ( base64WithoutPrefix ) ;
36+ const byteArrays = [ ] ;
37+
38+ for ( let offset = 0 ; offset < byteCharacters . length ; offset += 512 ) {
39+ const slice = byteCharacters . slice ( offset , offset + 512 ) ;
40+ const byteNumbers = new Array ( slice . length ) ;
41+ for ( let i = 0 ; i < slice . length ; i ++ ) {
42+ byteNumbers [ i ] = slice . charCodeAt ( i ) ;
43+ }
44+ const byteArray = new Uint8Array ( byteNumbers ) ;
45+ byteArrays . push ( byteArray ) ;
46+ }
47+
48+ const blob = new Blob ( byteArrays , { type : mimeType } ) ;
49+
50+ // Create a reference with a unique filename
51+ const filename = generateUniqueFilename ( 'upload' ) ;
52+ const fileRef = ref ( storage , `temp_audio/${ filename } ` ) ;
53+
54+ // Upload the blob
55+ const snapshot = await uploadBytes ( fileRef , blob ) ;
56+ console . log ( 'Uploaded a blob to Firebase Storage' ) ;
57+
58+ // Get download URL
59+ const downloadURL = await getDownloadURL ( snapshot . ref ) ;
60+ return { url : downloadURL , ref : `temp_audio/${ filename } ` } ;
61+ }
62+
563export async function handler ( event , context ) {
664 if ( event . httpMethod !== 'POST' ) {
765 return {
@@ -11,17 +69,41 @@ export async function handler(event, context) {
1169 }
1270
1371 try {
14- const { audioData, options } = JSON . parse ( event . body ) ;
72+ const { audioData, audioUrl , options } = JSON . parse ( event . body ) ;
1573
16- // Format input parameters like in your server
74+ // Format input parameters
1775 const inputParams = {
1876 task : options . task || 'transcribe' ,
19- audio : audioData ,
2077 batch_size : options . batch_size || 64 ,
2178 return_timestamps : options . return_timestamps || true ,
2279 diarize : options . diarize || false ,
2380 } ;
2481
82+ // Set audio source - check file size by base64 length
83+ let finalAudioUrl = audioUrl ;
84+
85+ // If no URL is provided but we have base64 data, check if it's large
86+ if ( ! audioUrl && audioData ) {
87+ // Estimate size of base64 (rough estimate: base64 size * 0.75 = binary size)
88+ const estimatedSizeInMB = ( audioData . length * 0.75 ) / ( 1024 * 1024 ) ;
89+
90+ if ( estimatedSizeInMB > 1 ) {
91+ // Large file detected, upload to Firebase
92+ console . log ( `Large audio file detected (${ estimatedSizeInMB . toFixed ( 2 ) } MB), uploading to Firebase` ) ;
93+ const uploadResult = await uploadBase64ToFirebase ( audioData ) ;
94+ finalAudioUrl = uploadResult . url ;
95+ console . log ( 'Uploaded to Firebase, URL:' , finalAudioUrl ) ;
96+ } else {
97+ // Small file, use base64 directly
98+ inputParams . audio = audioData ;
99+ }
100+ }
101+
102+ // If we have a URL (either provided or from Firebase upload), use it
103+ if ( finalAudioUrl ) {
104+ inputParams . audio = finalAudioUrl ;
105+ }
106+
25107 // Only include language if it's not "None" (auto-detect)
26108 if ( options . language !== "None" ) {
27109 inputParams . language = options . language ;
@@ -55,11 +137,17 @@ export async function handler(event, context) {
55137 } ;
56138 }
57139
140+ // If we used Firebase, include the reference in the response for later cleanup
141+ if ( finalAudioUrl && finalAudioUrl !== audioUrl ) {
142+ data . firebaseRef = `Used Firebase Storage for large file` ;
143+ }
144+
58145 return {
59146 statusCode : 200 ,
60147 body : JSON . stringify ( data )
61148 } ;
62149 } catch ( error ) {
150+ console . error ( 'Error in transcribe function:' , error ) ;
63151 return {
64152 statusCode : 500 ,
65153 body : JSON . stringify ( { error : error . message || 'Unknown error' } )
0 commit comments