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

Azure Function(JavaScript)无法返回语音识别结果的问题

Azure Function语音转译无法返回结果问题排查与修复

问题现象

  • 事件处理器可正常触发,音频流确认能被转译,但函数返回204状态码,无resultText内容
  • 在sessionStopped事件外部返回时,得到空字符串,无法获取预期的转译文本

原代码示例

app.http('jsTranslateVMSpanishToEnglish', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        
        // create the push stream we need for the speech sdk.
        var format = sdk.AudioStreamFormat.getWaveFormatPCM(48000, 16, 1); 
        var pushStream = sdk.AudioInputStream.createPushStream(format);
        var resultText = '';

        var blobName = JSON.parse(await request.text()).body.BlobName;
        context.log("BlobName: " + blobName);
        
        var stream = blobService.createReadStream(containerName, blobName)
            .on('error', function (error) {
                context.log(error);
            }).on('data', function(arrayBuffer) {
                pushStream.write(arrayBuffer.slice());
            }).on('end', function() {
                pushStream.close();
            });

        context.log("Now recognizing from: " + blobName);
        
        // now create the audio-config pointing to our stream and
        // the speech config specifying the language.
        var audioConfig = sdk.AudioConfig.fromStreamInput(pushStream);
        var speechConfig = sdk.SpeechConfig.fromSubscription(subscriptionKey, serviceRegion);
        
        // setting the recognition language to English.
        speechConfig.speechRecognitionLanguage = "en-US";
        
        // create the speech recognizer.
        var recognizer = new sdk.SpeechRecognizer(speechConfig, audioConfig);
        
        if(recognizer == undefined) {
            context.log("ERROR: recognizer is undefined");
        }
        else {
            context.log("recognizer is defined");
            // start the recognizer and wait for a result.
            recognizer.startContinuousRecognitionAsync();
            
            recognizer.recognized = (reco, e) => {
                try {
                    const res = e.result;
                    resultText += res.text;
                } catch (error) {
                    context.log(error);
                }
            };

            recognizer.sessionStopped = (reco, e) => {
                reco.stopContinuousRecognitionAsync();
                reco.close();
                // 此处return无法传递到handler的返回值
                return { body: resultText };
            };
        }
    }
});

问题根源

  1. 异步流程未等待:handler是异步函数,但代码未等待语音识别流程完成就提前结束,导致返回空结果或204状态码
  2. 事件回调返回无效:sessionStopped事件中的return无法传递给handler的返回值,因为回调是独立的执行上下文

修复代码

app.http('jsTranslateVMSpanishToEnglish', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        // create the push stream we need for the speech sdk.
        var format = sdk.AudioStreamFormat.getWaveFormatPCM(48000, 16, 1); 
        var pushStream = sdk.AudioInputStream.createPushStream(format);
        var resultText = '';

        var blobName = JSON.parse(await request.text()).body.BlobName;
        context.log("BlobName: " + blobName);

        // 等待Blob流读取完成
        await new Promise((resolve, reject) => {
            blobService.createReadStream(containerName, blobName)
                .on('error', function (error) {
                    context.log(error);
                    reject(error);
                }).on('data', function(arrayBuffer) {
                    pushStream.write(arrayBuffer.slice());
                }).on('end', function() {
                    pushStream.close();
                    resolve();
                });
        });

        context.log("Now recognizing from: " + blobName);
        
        var audioConfig = sdk.AudioConfig.fromStreamInput(pushStream);
        var speechConfig = sdk.SpeechConfig.fromSubscription(subscriptionKey, serviceRegion);
        speechConfig.speechRecognitionLanguage = "en-US";
        
        var recognizer = new sdk.SpeechRecognizer(speechConfig, audioConfig);
        
        if(recognizer == undefined) {
            context.log("ERROR: recognizer is undefined");
            return { body: "Recognizer initialization failed" };
        }

        context.log("recognizer is defined");

        // 用Promise包裹语音识别流程,等待识别完成
        return new Promise((resolve, reject) => {
            recognizer.recognized = (reco, e) => {
                try {
                    const res = e.result;
                    if (res.text) {
                        resultText += res.text + ' ';
                    }
                } catch (error) {
                    context.log(error);
                }
            };

            recognizer.sessionStopped = (reco, e) => {
                reco.stopContinuousRecognitionAsync();
                reco.close();
                resolve({ body: resultText.trim() });
            };

            recognizer.canceled = (reco, e) => {
                context.log(`Recognition canceled: ${e.errorDetails}`);
                reco.stopContinuousRecognitionAsync();
                reco.close();
                resolve({ body: resultText.trim() });
            };

            recognizer.startContinuousRecognitionAsync();
        });
    }
});

关键改动说明

  • 用Promise包裹Blob流读取,确保音频数据全部写入pushStream后再启动识别
  • 用另一个Promise封装语音识别流程,在sessionStopped和canceled事件中resolve结果,让handler等待识别完成后返回
  • 处理canceled事件,避免异常情况下无返回结果
  • 对resultText做trim处理,去除多余空格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:00:36