如何将FFMpeg转换结果存入PHP变量而非文件系统对接Whisper API?
问题解答:Laravel中FFmpeg音频转换与OpenAI异常处理
问题1:将FFmpeg转换后的MP3直接存入PHP变量
可以通过内存流实现,无需写入文件系统。利用PHP内置的php://temp临时流,让FFmpeg将转换后的音频写入该流,再读取流内容到变量中,全程不涉及磁盘操作。
实现思路:
- 创建指向
php://temp的SplFileObject内存流 - 通过FFmpeg的
export()->to()方法将音频写入内存流 - 重置流指针后读取完整内容到变量
问题2:完善OpenAI调用的异常捕获
OpenAI PHP客户端抛出的异常均属于OpenAI\Exceptions\OpenAIException子类,需针对性捕获不同场景的错误:
AuthenticationException:API密钥无效/未授权RateLimitException:请求频率超限BadRequestException:请求参数格式错误ServerException:OpenAI服务端故障
捕获后需返回明确的错误响应,替代原占位逻辑。
优化后的完整代码
use OpenAI\Exceptions\OpenAIException; use OpenAI\Exceptions\AuthenticationException; use OpenAI\Exceptions\RateLimitException; use OpenAI\Exceptions\BadRequestException; use FFMpeg\Exception\EncodingException; protected function whisper(Request $request) { $yourApiKey = getenv('OPENAI_API_KEY'); $client = OpenAI::client($yourApiKey); $file = $request->file('file'); $mp3Content = null; // FFmpeg转换音频到内存变量 try { // 创建内存临时流 $tempStream = new \SplFileObject('php://temp', 'w+'); FFMpeg::open($file) ->export() ->inFormat(new \FFMpeg\Format\Audio\Mp3) ->to($tempStream); // 重置流指针并读取内容 $tempStream->rewind(); $mp3Content = $tempStream->fread($tempStream->getSize()); } catch (EncodingException $exception) { return response()->json([ 'error' => '音频转换失败', 'command' => $exception->getCommand(), 'error_log' => $exception->getErrorOutput() ], 500); } if (!$mp3Content) { return response()->json(['error' => '音频转换后内容为空'], 500); } // OpenAI Whisper调用及异常处理 try { // 将内存MP3内容转为临时文件句柄(OpenAI要求传入可读取的文件资源) $tempFile = tmpfile(); fwrite($tempFile, $mp3Content); fseek($tempFile, 0); $response = $client->audio()->transcribe([ 'model' => 'whisper-1', 'file' => $tempFile, 'response_format' => 'verbose_json', ]); fclose($tempFile); // 关闭临时文件,系统自动清理 return response()->json($response); } catch (AuthenticationException $e) { return response()->json(['error' => 'OpenAI API密钥无效'], 401); } catch (RateLimitException $e) { return response()->json(['error' => '请求过于频繁,请稍后重试'], 429); } catch (BadRequestException $e) { return response()->json(['error' => '请求参数错误:'.$e->getMessage()], 400); } catch (OpenAIException $e) { return response()->json(['error' => 'OpenAI服务调用失败:'.$e->getMessage()], 500); } catch (\Exception $e) { return response()->json(['error' => '未知错误:'.$e->getMessage()], 500); } }
内容的提问来源于stack exchange,提问作者SScotti
相关产品推荐
相关产品推荐

