使用Google Cloud Text-to-Speech PHP客户端调用长音频合成API时遇项目不匹配错误求助
问题描述
我尝试使用Google Cloud Text-to-Speech API的PHP客户端从文本生成长音频,已经创建了服务账号并配置了存储桶权限,但运行代码时遇到了项目不匹配的错误。
我的PHP代码如下:
require_once 'vendor/autoload.php'; putenv('GOOGLE_APPLICATION_CREDENTIALS=C:\Users\Name\Projects\google-text-to-speech\project-219819-da3fdd6a76ad.json'); use Google\Cloud\TextToSpeech\V1\AudioConfig; use Google\Cloud\TextToSpeech\V1\AudioEncoding; use Google\Cloud\TextToSpeech\V1\Client\TextToSpeechLongAudioSynthesizeClient; use Google\Cloud\TextToSpeech\V1\SsmlVoiceGender; use Google\Cloud\TextToSpeech\V1\SynthesisInput; use Google\Cloud\TextToSpeech\V1\SynthesizeLongAudioRequest; use Google\Cloud\TextToSpeech\V1\VoiceSelectionParams; try { $client = new TextToSpeechLongAudioSynthesizeClient(); $synthesisInputText = (new SynthesisInput()) ->setText('Hola, ¿cómo estás? gracias por venir.'); $voice = (new VoiceSelectionParams()) ->setLanguageCode('es-ES') ->setName('es-ES-Standard-A') ->setSsmlGender(SsmlVoiceGender::FEMALE); $effectsProfileId = 'handset-class-device'; $audioConfig = (new AudioConfig()) ->setAudioEncoding(AudioEncoding::LINEAR16) ->setSpeakingRate(0.75) ->setEffectsProfileId(array($effectsProfileId)); $request = (new SynthesizeLongAudioRequest()) ->setParent('projects/project/locations/global') ->setOutputGcsUri('gs://bucket/audios/ejemplo.mp3') ->setInput($synthesisInputText) ->setVoice($voice) ->setAudioConfig($audioConfig); $response = $client->synthesizeLongAudio($request); $audioContent = $response->getAudioContent(); file_put_contents('output-long.mp3', $audioContent); echo '<audio src="output.mp3" controls />' . PHP_EOL; $textToSpeechClient->close(); } catch(Exception $e) { echo $e->getMessage(); }
运行后出现的错误:
{ "message": "Unable to perform long audio synthesis. Neither the client project number: 863009906802 nor ID: project-219819 matches the resource project: bucket", "code": 3, "status": "INVALID_ARGUMENT", "details": [] }
请问有什么解决思路吗?
回答
看起来你遇到的是调用长音频合成API的项目与输出存储桶所属项目不匹配的核心问题,结合错误提示和代码细节,我来帮你梳理解决步骤:
1. 错误原因定位
错误信息明确指出,你当前使用的客户端项目(编号863009906802/IDproject-219819)和输出存储桶gs://bucket所属的GCP项目不一致。Google长音频合成API对输出存储桶有严格的项目关联要求,优先推荐确保两者属于同一个项目。
2. 具体修复步骤
(1)确认存储桶的所属项目
打开Google Cloud控制台的Cloud Storage面板,找到你的bucket存储桶,查看它的「项目」属性,记下对应的项目ID(类似my-gcp-project-12345)或项目编号(一串数字)。
(2)修正代码中的Parent参数
把代码里的setParent('projects/project/locations/global')替换为存储桶所属项目的正确标识:
- 若使用项目ID:
projects/你的项目ID/locations/global - 若使用项目编号:
projects/863009906802/locations/global(错误提示里的项目编号可以先尝试)
修正后的示例:
$request = (new SynthesizeLongAudioRequest()) ->setParent('projects/your-project-id/locations/global') ->setOutputGcsUri('gs://bucket/audios/ejemplo.mp3') // ...其他参数不变
(3)验证服务账号权限
确保你使用的服务账号(对应project-219819-da3fdd6a76ad.json)满足以下任一条件:
- 属于存储桶所属的项目,且拥有
texttospeech.synthesizer(调用API权限)和storage.objects.create(写入存储桶权限) - 已被授予存储桶
gs://bucket/audios/路径的「Storage Object Creator」角色
3. 代码中的额外误区修正
除了项目匹配问题,你的代码还有两个容易踩坑的点:
- 音频编码与文件名不匹配:你设置的
AudioEncoding::LINEAR16对应WAV格式,但输出文件名是ejemplo.mp3。如果需要生成MP3格式,应将编码改为AudioEncoding::MP3。 - 长音频合成API的异步特性:这个API是异步执行的,调用
synthesizeLongAudio后不会直接返回音频内容($response->getAudioContent()会是空值)。正确的做法是轮询操作状态,完成后从GCS桶下载文件:
$operation = $client->synthesizeLongAudio($request); // 等待操作完成(生产环境建议用轮询而非阻塞等待) $operation->pollUntilComplete(); if ($operation->operationSucceeded()) { echo "音频已成功生成并保存到 gs://bucket/audios/ejemplo.mp3"; // 这里可以添加从GCS下载文件到本地的逻辑 } else { $error = $operation->getError(); echo "生成失败:" . $error->getMessage(); }
备注:内容来源于stack exchange,提问作者grankan

