我刚开始做一个小演示,用JS转换从前端捕获的音频作为音频/webm,然后在Laravel应用程序中发送后端。我猜有JS库可以处理转换,但我宁愿使用服务器端解决方案与FFMPEG,我正在做的。
后端代码如下。它似乎是在玩弄我正在使用的PHP编写器包与Laravel的一个也在那里。我宁愿用这个,因为我有其他PHP应用程序不是Laravel。
问题:
-
使用FFMpeg库,是否有一种方法可以将转换后的.mp3文件捕获为脚本中的PHP变量,而不是将其保存到文件系统中,然后稍后再读取它?
-
对于OpenAI调用,我也想在那里捕获异常。我只是在这里放了一个占位符。
protected function whisper(Request $request) { $yourApiKey = getenv('OPENAI_API_KEY'); $client = OpenAI::client($yourApiKey); $file = $request->file('file'); $mimeType = $request->file('file')->getMimeType(); $audioContents = $file->getContent(); try { FFMpeg::open($file) ->export() ->toDisk('public') ->inFormat(new FFMpegFormatAudioMp3) ->save('song_converted.mp3'); } catch (EncodingException $exception) { $command = $exception->getCommand(); $errorLog = $exception->getErrorOutput(); } $mp3 = Storage::disk('public')->path('song_converted.mp3'); try { $response = $client->audio()->transcribe([ 'model' => 'whisper-1', 'file' => fopen($mp3, 'r'), 'response_format' => 'verbose_json', ]); } catch (EncodingException $exception) { $command = $exception->getCommand(); $errorLog = $exception->getErrorOutput(); } echo json_encode($response); }
我不认为你可以直接得到Whisper API的流输出到一个变量中。但我认为你的意思是:
- 将来自Whisper的流响应存储在内存中;或
- 存储在无需管理的文件中。
幸运的是,OpenAI客户端库似乎接受指针资源(即fopen返回变量)。最接近的方法是使用php://temp读写流。PHP将检查它的大小是否大于2MB(可配置),它将创建一个临时文件用于存储。
如果这是:
- 如果流很小,PHP将使用内存处理所有内容。
- 如果它很大,您不必自己管理生成的临时文件。PHP会在使用后删除临时文件。
$mp3 = fopen('php://temp');
$response = $client->audio()->transcribe([
'model' => 'whisper-1',
'file' => fopen($mp3, 'w+'),
'response_format' => 'verbose_json',
]);
则可以倒带$mp3
流并读取/流出。例如:
// Move the pointer back to the beginning of the temporary storage.
rewind($mp3);
// Directly copy the stream chunk-by-chunk to the
// output buffer / output stream
$output = fopen('php://output', 'w');
stream_copy_to_stream($mp3, $output, 1024);
对于Laravel,你可能需要这样的东西:
rewind($mp3);
return response()->stream(fn() => echo stream_get_contents($mp3));