You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js调用Google Cloud Speech-to-Text API遇错求助

Google Cloud Speech-to-Text API v2 Node.js 问题排查

问题背景

我是Google Cloud新手,创建了集成Speech-to-Text API的项目并关联账单账户,参考控制台内Node.js快速入门教程操作,修正教程代码后运行遇到错误。


第一个错误:RESOURCE_PROJECT_INVALID

运行代码后出现以下错误:

node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: 3 INVALID_ARGUMENT: Invalid resource field value in the request.
    at callErrorFromStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client.js:192:76)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
for call at
    at ServiceClientImpl.makeUnaryRequest (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client.js:160:32)
    at ServiceClientImpl.<anonymous> (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/@google-cloud/speech/build/src/v2/speech_client.js:318:29
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
    at repeat (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/retries.js:80:25)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/retries.js:119:13
    at OngoingCallPromise.call (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/call.js:67:27)
    at NormalApiCaller.call (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/normalApiCaller.js:34:19)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/createApiCall.js:108:30
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 3,
  details: 'Invalid resource field value in the request.',
  metadata: Metadata {
    internalRepr: Map(2) {
      'google.rpc.errorinfo-bin' => [
        Buffer(127) [Uint8Array] [
           10,  24,  82,  69,  83,  79,  85,  82,  67,  69,  95,  80,
           82,  79,  74,  69,  67,  84,  95,  73,  78,  86,  65,  76,
           73,  68,  18,  14, 103, 111, 111, 103, 108, 101,  97, 112,
          105, 115,  46,  99, 111, 109,  26,  32,  10,   7, 115, 101,
          114, 118, 105,  99, 101,  18,  21, 115, 112, 101, 101,  99,
          104,  46, 103, 111, 111, 103, 108, 101,  97, 112, 105, 115,
           46,  99, 111, 109,  26,  49,  10,   6, 109, 101, 116, 104,
          111, 100,  18,  39, 103, 111, 111, 103, 108, 101,  46,  99,
          108, 111, 117, 100,
          ... 27 more items
        ]
      ],
      'grpc-status-details-bin' => [
        Buffer(222) [Uint8Array] [
            8,   3,  18,  44,  73, 110, 118,  97, 108, 105, 100,  32,
          114, 101, 115, 111, 117, 114,  99, 101,  32, 102, 105, 101,
          108, 100,  32, 118,  97, 108, 117, 101,  32, 105, 110,  32,
          116, 104, 101,  32, 114, 101, 113, 117, 101, 115, 116,  46,
           26, 171,   1,  10,  40, 116, 121, 112, 101,  46, 103, 111,
          111, 103, 108, 101,  97, 112, 105, 115,  46,  99, 111, 109,
           47, 103, 111, 111, 103, 108, 101,  46, 114, 112,  99,  46,
           69, 114, 114, 111, 114,  73, 110, 102, 111,  18, 127,  10,
           24,  82,  69,  83,
          ... 122 more items
        ]
      ]
    },
    options: {}
  },
  note: 'Exception occurred in retry method that was not classified as transient',
  statusDetails: [
    ErrorInfo {
      metadata: {
        service: 'speech.googleapis.com',
        method: 'google.cloud.speech.v2.Speech.Recognize'
      },
      reason: 'RESOURCE_PROJECT_INVALID',
      domain: 'googleapis.com'
    }
  ],
  reason: 'RESOURCE_PROJECT_INVALID',
  domain: 'googleapis.com',
  errorInfoMetadata: {
    service: 'speech.googleapis.com',
    method: 'google.cloud.speech.v2.Speech.Recognize'
  }
}

已执行gcloud auth application-default set-quota-project $PROJECT_ID设置配额项目,Windows系统下执行相同步骤也出现相同错误。

初始代码:

const speech = require('@google-cloud/speech').v2;
const https = require('https');

const client = new speech.SpeechClient();
const projectId = '<ProjectId>';
var recognizerName;

const fileUrl = 'https://storage.googleapis.com/cloud-samples-data/speech/brooklyn_bridge.wav';

async function createRecognizer() {
  const recognizerRequest = {
    parent: `projects/${projectId}/locations/global`,
    recognizerId: 'en123',
    recognizer: {
      languageCodes: ['en-US'],
      model: 'latest_long',
    },
  };

  const operation = await client.createRecognizer(recognizerRequest);
  const recognizer = operation[0].result;
  recognizerName = recognizer.name;
  console.log(`Created new recognizer: ${recognizerName}`);
}

async function getUrlData(url) {
  return new Promise((resolve) => {
      https.get(url, response => {
          var body = '';
          var i = 0;
          response.on('data', chunk => {
              i++;
              body += chunk;
          });
          response.on('end', () => {
              resolve(Buffer.from(body).toString('base64'));
          });
      });
  });
}

async function transcribeFile() {
  const content = await getUrlData(fileUrl);
  const transcriptionRequest = {
    recognizer: recognizerName,
    config: {
      autoDecodingConfig: {},
    },
    content: content,
  };

  const response = await client.recognize(transcriptionRequest); // <=== 错误发生在此行
  for (const result of response[0].results) {
    console.log(`Transcript: ${result.alternatives[0].transcript}`);
  }
}

createRecognizer();
transcribeFile();

尝试修改后出现第二个错误:音频编码不支持

修改recognizerName为完整路径projects/${projectId}/locations/global/recognizers/${recognizerId}后,代码如下:

const projectId = '<ProjectId>';
const recognizerId = 'en123';
const fileUrl = 'https://storage.googleapis.com/cloud-samples-data/speech/brooklyn_bridge.wav';

// ... 其他函数不变

async function transcribeFile() {
  const recognizerName = `projects/${projectId}/locations/global/recognizers/${recognizerId}`;
  const content = await getUrlData(fileUrl);
  const transcriptionRequest = {
    recognizer: recognizerName,
    config: {
      autoDecodingConfig: {},
    },
    content: content,
  };

  const response = await client.recognize(transcriptionRequest); // <=== 错误发生在此行
  for (const result of response[0].results) {
    console.log(`Transcript: ${result.alternatives[0].transcript}`);
  }
}

createRecognizer();
transcribeFile();

出现新错误:

Error: 3 INVALID_ARGUMENT: Audio data does not appear to be in a supported encoding. If you believe this to be incorrect, try explicitly specifying the decoding parameters.
    at callErrorFromStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client.js:192:76)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    at Object.onReceiveStatus (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
for call at
    at ServiceClientImpl.makeUnaryRequest (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/client.js:160:32)
    at ServiceClientImpl.<anonymous> (/home/<Google-Account>/speech-to-text-nodejs/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/@google-cloud/speech/build/src/v2/speech_client.js:318:29
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/timeout.js:44:16
    at repeat (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/retries.js:80:25)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/retries.js:119:13
    at OngoingCallPromise.call (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/call.js:67:27)
    at NormalApiCaller.call (/home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/normalCalls/normalApiCaller.js:34:19)
    at /home/<Google-Account>/speech-to-text-nodejs/node_modules/google-gax/build/src/createApiCall.js:108:30
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 3,
  details: 'Audio data does not appear to be in a supported encoding. If you believe this to be incorrect, try explicitly specifying the decoding parameters.',
  metadata: Metadata { internalRepr: Map(0) {}, options: {} },
  note: 'Exception occurred in retry method that was not classified as transient'
}

问题原因及解决方法

第一个错误(RESOURCE_PROJECT_INVALID)的原因

初始代码中createRecognizer()和transcribeFile()是并行执行的,transcribeFile()尝试使用recognizerName时,createRecognizer()可能还未完成创建操作,导致recognizerName未被正确赋值,传递给API的资源字段无效。

解决方法:
确保createRecognizer()执行完成后再调用transcribeFile(),修改主函数调用逻辑:

// 替换原来的 createRecognizer(); transcribeFile();
async function run() {
  await createRecognizer();
  await transcribeFile();
}

run().catch(console.error);

第二个错误(音频编码不支持)的原因

getUrlData()函数中,将音频数据以字符串拼接的方式处理chunk,会破坏二进制音频数据的格式,导致转成base64后无法被API识别。

解决方法:
修改getUrlData()函数,用Buffer数组存储二进制数据,避免字符串拼接导致的格式损坏:

async function getUrlData(url) {
  return new Promise((resolve, reject) => {
    https.get(url, response => {
      const chunks = [];
      response.on('data', chunk => {
        chunks.push(chunk);
      });
      response.on('end', () => {
        const buffer = Buffer.concat(chunks);
        resolve(buffer.toString('base64'));
      });
      response.on('error', reject);
    }).on('error', reject);
  });
}

额外注意事项

  1. 确保项目已启用Speech-to-Text API,可在Google Cloud控制台的API库中确认。
  2. 若自动解码仍有问题,可在请求中显式指定音频编码参数,替换autoDecodingConfig:
config: {
  explicitDecodingConfig: {
    encoding: 'LINEAR16',
    sampleRateHertz: 16000,
    languageCodes: ['en-US']
  }
}

(注:brooklyn_bridge.wav的编码为LINEAR16,采样率16000Hz)


内容的提问来源于stack exchange,提问作者cmd770

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:04:02