全部產品
Search
文件中心

Alibaba Cloud Model Studio:Paraformer即時語音辨識Java SDK

更新時間:Mar 21, 2026

本文介紹Paraformer即時語音辨識Java SDK的參數和介面細節。

重要

本文檔僅適用於“中國內地(北京)”地區。如需使用模型,需使用“中國內地(北京)”地區的API Key

使用者指南:關於模型介紹和選型建議請參見即時語音辨識-Fun-ASR/Gummy/Paraformer

前提條件

  • 已開通服務並擷取API Key。請配置API Key到環境變數(準備下線,併入配置 API Key),而非寫入程式碼在代碼中,防範因代碼泄露導致的安全風險。

    說明

    當您需要為第三方應用或使用者提供臨時存取權限,或者希望嚴格控制敏感性資料訪問、刪除等高風險操作時,建議使用臨時鑒權Token

    與長期有效 API Key 相比,臨時鑒權 Token 具備時效性短(60秒)、安全性高的特點,適用於臨時調用情境,能有效降低API Key泄露的風險。

    使用方式:在代碼中,將原本用於鑒權的 API Key 替換為擷取到的臨時鑒權 Token 即可。

  • 安裝最新版DashScope SDK

模型列表

paraformer-realtime-v2

paraformer-realtime-8k-v2

適用情境

直播、會議等情境

電話客服、語音信箱等 8kHz 音訊識別情境

採樣率

任意

8kHz

語種

中文(包含中文普通話和各種方言)、英文、日語、韓語、德語、法語、俄語

支援的中文方言:上海話、吳語、閩南語、東北話、甘肅話、貴州話、河南話、湖北話、湖南話、江西話、寧夏話、山西話、陝西話、山東話、四川話、天津話、雲南話、粵語

中文

標點符號預測

✅ 預設支援,無需配置

✅ 預設支援,無需配置

逆文本正則化(ITN)

✅ 預設支援,無需配置

✅ 預設支援,無需配置

指定待識別語種

✅ 通過language_hints參數指定

情感識別

✅ (點擊查看使用方式)

情感識別遵循如下約束:

  • 僅限paraformer-realtime-8k-v2模型。

  • 必須關閉語義斷句(可通過請求參數semantic_punctuation_enabled控制)。語義斷句預設為關閉狀態。

  • 只有在即時識別結果(RecognitionResult)isSentenceEnd方法返回結果為true時才顯示情感識別結果。

情感識別結果擷取方式:調用單句資訊(Sentence)getEmoTaggetEmoConfidence方法分別擷取當前句子的情感和情感信賴度。

快速開始

Recognition類提供了非流式調用和雙向流式調用介面。請根據實際需求選擇合適的調用方式:

  • 非流式調用:針對本地檔案進行識別,並一次性返回完整的處理結果。適合處理錄製好的音頻。

  • 雙向流式調用:可直接對音頻流進行識別,並即時輸出結果。音頻流可以來自外部裝置(如麥克風)或從本地檔案讀取。適合需要即時反饋的情境。

非流式調用

提交單個語音即時轉寫任務,通過傳入本地檔案的方式同步阻塞地拿到轉寫結果。

image

執行個體化Recognition類,調用call方法綁定請求參數和待識別檔案,進行識別並最終擷取識別結果。

點擊查看完整樣本

樣本中用到的音頻為:asr_example.wav

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;

import java.io.File;

public class Main {
    public static void main(String[] args) {
        // 建立Recognition執行個體
        Recognition recognizer = new Recognition();
        // 建立RecognitionParam
        RecognitionParam param =
                RecognitionParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將apiKey替換為自己的API Key
                        // .apiKey("yourApikey")
                        .model("paraformer-realtime-v2")
                        .format("wav")
                        .sampleRate(16000)
                        // “language_hints”只支援paraformer-realtime-v2模型
                        .parameter("language_hints", new String[]{"zh", "en"})
                        .build();

        try {
            System.out.println("識別結果:" + recognizer.call(param, new File("asr_example.wav")));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 任務結束後關閉 WebSocket 串連
            recognizer.getDuplexApi().close(1000, "bye");
        }
        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
        System.exit(0);
    }
}

雙向流式調用:基於回調

提交單個語音即時轉寫任務,通過實現回調介面的方式流式輸出即時識別結果。

  1. 啟動流式語音辨識

    執行個體化Recognition類,調用call方法綁定請求參數回調介面(ResultCallback)並啟動流式語音辨識。

  2. 串流

    迴圈調用Recognition類sendAudioFrame方法,將從本地檔案或裝置(如麥克風)讀取的二進位音頻流分段發送至服務端。

    在發送音頻資料的過程中,服務端會通過回調介面(ResultCallback)onEvent方法,將識別結果即時返回給用戶端。

    建議每次發送的音頻時間長度約為100毫秒,資料大小保持在1KB至16KB之間。

  3. 結束處理

    調用Recognition類stop方法結束語音辨識。

    該方法會阻塞當前線程,直到回調介面(ResultCallback)onComplete或者onError回調觸發後才會釋放線程阻塞。

點擊查看完整樣本

識別傳入麥克風的語音

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.common.ResultCallback;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask());
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }
}

class RealtimeRecognitionTask implements Runnable {
    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                // 若沒有將API Key配置到環境變數中,需將apiKey替換為自己的API Key
                // .apiKey("yourApikey")
                .model("paraformer-realtime-v2")
                .format("wav")
                .sampleRate(16000)
                // “language_hints”只支援paraformer-realtime-v2模型
                .parameter("language_hints", new String[]{"zh", "en"})
                .build();
        Recognition recognizer = new Recognition();

        ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
            @Override
            public void onEvent(RecognitionResult result) {
                if (result.isSentenceEnd()) {
                    System.out.println("Final Result: " + result.getSentence().getText());
                } else {
                    System.out.println("Intermediate Result: " + result.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println("Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("RecognitionCallback error: " + e.getMessage());
            }
        };
        try {
            recognizer.call(param, callback);
            // 建立音頻格式
            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
            // 根據格式匹配預設錄音裝置
            TargetDataLine targetDataLine =
                    AudioSystem.getTargetDataLine(audioFormat);
            targetDataLine.open(audioFormat);
            // 開始錄音
            targetDataLine.start();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            long start = System.currentTimeMillis();
            // 錄音50s並進行即時轉寫
            while (System.currentTimeMillis() - start < 50000) {
                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                if (read > 0) {
                    buffer.limit(read);
                    // 將錄音音頻資料發送給流式識別服務
                    recognizer.sendAudioFrame(buffer);
                    buffer = ByteBuffer.allocate(1024);
                    // 錄音速率有限,防止cpu佔用過高,休眠一小會兒
                    Thread.sleep(20);
                }
            }
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 任務結束後關閉 Websocket 串連
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}

識別本地語音檔案

樣本中用到的音頻為:asr_example.wav

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.common.ResultCallback;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask(Paths.get(System.getProperty("user.dir"), "asr_example.wav")));
        executorService.shutdown();

        // wait for all tasks to complete
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }
}

class RealtimeRecognitionTask implements Runnable {
    private Path filepath;

    public RealtimeRecognitionTask(Path filepath) {
        this.filepath = filepath;
    }

    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                // 若沒有將API Key配置到環境變數中,需將apiKey替換為自己的API Key
                // .apiKey("yourApikey")
                .model("paraformer-realtime-v2")
                .format("wav")
                .sampleRate(16000)
                // “language_hints”只支援paraformer-realtime-v2模型
                .parameter("language_hints", new String[]{"zh", "en"})
                .build();
        Recognition recognizer = new Recognition();

        String threadName = Thread.currentThread().getName();

        ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
            @Override
            public void onEvent(RecognitionResult message) {
                if (message.isSentenceEnd()) {

                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Final Result:" + message.getSentence().getText());
                } else {
                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Intermediate Result: " + message.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println(TimeUtils.getTimestamp()+" "+
                        "[" + threadName + "] RecognitionCallback error: " + e.getMessage());
            }
        };

        try {
            recognizer.call(param, callback);
            // Please replace the path with your audio file path
            System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Input file_path is: " + this.filepath);
            // Read file and send audio by chunks
            FileInputStream fis = new FileInputStream(this.filepath.toFile());
            // chunk size set to 1 seconds for 16KHz sample rate
            byte[] buffer = new byte[3200];
            int bytesRead;
            // Loop to read chunks of the file
            while ((bytesRead = fis.read(buffer)) != -1) {
                ByteBuffer byteBuffer;
                // Handle the last chunk which might be smaller than the buffer size
                System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] bytesRead: " + bytesRead);
                if (bytesRead < buffer.length) {
                    byteBuffer = ByteBuffer.wrap(buffer, 0, bytesRead);
                } else {
                    byteBuffer = ByteBuffer.wrap(buffer);
                }

                recognizer.sendAudioFrame(byteBuffer);
                buffer = new byte[3200];
                Thread.sleep(100);
            }
            System.out.println(TimeUtils.getTimestamp()+" "+LocalDateTime.now());
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 任務結束後關閉 Websocket 串連
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "["
                        + threadName
                        + "][Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}

雙向流式調用:基於Flowable

提交單個語音即時轉寫任務,通過實現工作流程(Flowable)的方式流式輸出即時識別結果。

Flowable 是一個用於工作流程和商務程序管理的開源架構,它基於 Apache 2.0 許可證發布。關於Flowable的使用,請參見Flowable API詳情

點擊查看完整樣本

直接調用Recognition類streamCall方法開始識別。

streamCall方法返回一個Flowable<RecognitionResult>執行個體,您可以調用Flowable執行個體的blockingForEachsubscribe等方法處理識別結果。識別結果封裝在RecognitionResult中。

streamCall方法需要傳入兩個參數:

  • RecognitionParam執行個體(請求參數):通過它可以設定語音辨識所需的模型、採樣率、音頻格式等參數。

  • Flowable<ByteBuffer>執行個體:您需要建立一個Flowable<ByteBuffer>類型的執行個體,並在其中實現解析音頻流的方法。

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;
import java.nio.ByteBuffer;

public class Main {
    public static void main(String[] args) throws NoApiKeyException {
        // 建立一個Flowable<ByteBuffer>
        Flowable<ByteBuffer> audioSource =
                Flowable.create(
                        emitter -> {
                            new Thread(
                                    () -> {
                                        try {
                                            // 建立音頻格式
                                            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
                                            // 根據格式匹配預設錄音裝置
                                            TargetDataLine targetDataLine =
                                                    AudioSystem.getTargetDataLine(audioFormat);
                                            targetDataLine.open(audioFormat);
                                            // 開始錄音
                                            targetDataLine.start();
                                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                                            long start = System.currentTimeMillis();
                                            // 錄音50s並進行即時轉寫
                                            while (System.currentTimeMillis() - start < 50000) {
                                                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                                                if (read > 0) {
                                                    buffer.limit(read);
                                                    // 將錄音音頻資料發送給流式識別服務
                                                    emitter.onNext(buffer);
                                                    buffer = ByteBuffer.allocate(1024);
                                                    // 錄音速率有限,防止cpu佔用過高,休眠一小會兒
                                                    Thread.sleep(20);
                                                }
                                            }
                                            // 通知結束轉寫
                                            emitter.onComplete();
                                        } catch (Exception e) {
                                            emitter.onError(e);
                                        }
                                    })
                                    .start();
                        },
                        BackpressureStrategy.BUFFER);

        // 建立Recognizer
        Recognition recognizer = new Recognition();
        // 建立RecognitionParam,audioFrames參數中傳入上面建立的Flowable<ByteBuffer>
        RecognitionParam param = RecognitionParam.builder()
                // 若沒有將API Key配置到環境變數中,需將apiKey替換為自己的API Key
                // .apiKey("yourApikey")
                .model("paraformer-realtime-v2")
                .format("pcm")
                .sampleRate(16000)
                // “language_hints”只支援paraformer-realtime-v2模型
                .parameter("language_hints", new String[]{"zh", "en"})
                .build();

        // 流式調用介面
        recognizer
                .streamCall(param, audioSource)
                .blockingForEach(
                        result -> {
                            // Subscribe to the output result
                            if (result.isSentenceEnd()) {
                                System.out.println("Final Result: " + result.getSentence().getText());
                            } else {
                                System.out.println("Intermediate Result: " + result.getSentence().getText());
                            }
                        });
        // 任務結束後關閉 Websocket 串連
        recognizer.getDuplexApi().close(1000, "bye");
        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
        System.exit(0);
    }
}

高並發調用

在DashScope Java SDK中,採用了OkHttp3的串連池技術,以減少重複建立串連的開銷。詳情請參見即時語音辨識高並發情境

請求參數

通過RecognitionParam的鏈式方法配置模型、採樣率、音頻格式等參數。配置完成的參數對象傳入Recognition類call/streamCall方法中使用。

點擊查看樣本

RecognitionParam param = RecognitionParam.builder()
  .model("paraformer-realtime-v2")
  .format("pcm")
  .sampleRate(16000)
  // “language_hints”只支援paraformer-realtime-v2模型
  .parameter("language_hints", new String[]{"zh", "en"})
  .build();

參數

類型

預設值

是否必須

說明

model

String

-

用於即時語音辨識的模型。詳情請參見模型列表

sampleRate

Integer

-

設定待識別音頻採樣率(單位Hz)。

因模型而異:

  • paraformer-realtime-v2支援任意採樣率。

  • paraformer-realtime-8k-v2僅支援8000Hz採樣率。

format

String

-

設定待識別音頻格式。

支援的音頻格式:pcm、wav、mp3、opus、speex、aac、amr。

重要

opus/speex:必須使用Ogg封裝;

wav:必須為PCM編碼;

amr:僅支援AMR-NB類型。

disfluencyRemovalEnabled

boolean

false

設定是否過濾語氣詞:

  • true:過濾語氣詞

  • false(預設):不過濾語氣詞

language_hints

String[]

["zh", "en"]

設定待識別語言代碼。如果無法提前確定語種,可不設定,模型會自動識別語種。

目前支援的語言代碼:

  • zh: 中文

  • en: 英文

  • ja: 日語

  • yue: 粵語

  • ko: 韓語

  • de:德語

  • fr:法語

  • ru:俄語

該參數僅對支援多語言的模型生效(參見模型列表)。

說明

language_hints需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("language_hints", new String[]{"zh", "en"})
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("language_hints", new String[]{"zh", "en"}))
 .build();

semantic_punctuation_enabled

boolean

false

設定是否開啟語義斷句,預設關閉。

  • true:開啟語義斷句,關閉VAD(Voice Activity Detection,語音活動檢測)斷句。

  • false(預設):開啟VAD(Voice Activity Detection,語音活動檢測)斷句,關閉語義斷句。

語義斷句準確性更高,適合會議轉寫情境;VAD(Voice Activity Detection,語音活動檢測)斷句延遲較低,適合互動情境。

通過調整semantic_punctuation_enabled參數,可以靈活切換語音辨識的斷句方式以適應不同情境需求。

該參數僅在模型為v2及更高版本時生效。

說明

semantic_punctuation_enabled需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("semantic_punctuation_enabled", true)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("semantic_punctuation_enabled", true))
 .build();

max_sentence_silence

Integer

800

設定VAD(Voice Activity Detection,語音活動檢測)斷句的靜音時間長度閾值(單位為ms)。

當一段語音後的靜音時間長度超過該閾值時,系統會判定該句子已結束。

參數範圍為200ms至6000ms,預設值為800ms。

該參數僅在semantic_punctuation_enabled參數為false(VAD斷句)且模型為v2及更高版本時生效。

說明

max_sentence_silence需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("max_sentence_silence", 800)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("max_sentence_silence", 800))
 .build();

multi_threshold_mode_enabled

boolean

false

該開關開啟時(true)可以防止VAD斷句切割過長。預設關閉。

該參數僅在semantic_punctuation_enabled參數為false(VAD斷句)且模型為v2及更高版本時生效。

說明

multi_threshold_mode_enabled需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("multi_threshold_mode_enabled", true)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("multi_threshold_mode_enabled", true))
 .build();

punctuation_prediction_enabled

boolean

true

設定是否在識別結果中自動添加標點:

  • true(預設):是

  • false:否

該參數僅在模型為v2及更高版本時生效。

說明

punctuation_prediction_enabled需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("punctuation_prediction_enabled", false)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("punctuation_prediction_enabled", false))
 .build();

heartbeat

boolean

false

當需要與服務端保持長串連時,可通過該開關進行控制:

  • true:在持續發送靜音音訊情況下,可保持與服務端的串連不中斷。

  • false(預設):即使持續發送靜音音頻,串連也將在60秒後因逾時而斷開。

    靜音音頻指的是在音頻檔案或資料流中沒有聲音訊號的內容。靜音音頻可以通過多種方法產生,例如使用音頻編輯軟體如Audacity或Adobe Audition,或者通過命令列工具如FFmpeg。

該參數僅在模型為v2及更高版本時生效。

說明

使用該欄位時,SDK版本不能低於2.19.1。

heartbeat需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("heartbeat", true)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("heartbeat", true))
 .build();

inverse_text_normalization_enabled

boolean

true

設定是否開啟ITN(Inverse Text Normalization,逆文本正則化)。

預設開啟(true)。開啟後,中文數字將轉換為阿拉伯數字。

該參數僅在模型為v2及更高版本時生效。

說明

inverse_text_normalization_enabled需要通過RecognitionParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameter("inverse_text_normalization_enabled", false)
 .build();

通過parameters設定

RecognitionParam param = RecognitionParam.builder()
 .model("paraformer-realtime-v2")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("inverse_text_normalization_enabled", false))
 .build();

apiKey

String

-

使用者API Key。

關鍵介面

Recognition

Recognition通過“import com.alibaba.dashscope.audio.asr.recognition.Recognition;”方式引入。它的關鍵介面如下:

介面/方法

參數

傳回值

描述

public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback)

基於回調形式的流式即時識別,該方法不會阻塞當前線程。

public String call(RecognitionParam param, File file)

識別結果

基於本地檔案的非流式調用,該方法會阻塞當前線程直到全部音頻讀完,該方法要求所識別檔案具有可讀許可權。

public Flowable<RecognitionResult> streamCall(RecognitionParam param, Flowable<ByteBuffer> audioFrame)
  • param請求參數

  • audioFrameFlowable<ByteBuffer>執行個體

Flowable<RecognitionResult>

基於Flowable的流式即時識別。

public void sendAudioFrame(ByteBuffer audioFrame)
  • audioFrame:二進位音頻流,為ByteBuffer類型

推送音頻,每次推送的音頻流不宜過大或過小,建議每包音頻時間長度為100ms左右,大小在1KB~16KB之間。

識別結果通過回調介面(ResultCallback)的onEvent方法擷取。

public void stop()

停止即時識別。

該方法會阻塞當前線程,直到回調執行個體ResultCallbackonComplete或者onError被調用之後才會解除對當前線程的阻塞。

recognizer.getDuplexApi().close(int code, String reason)

code: WebSocket關閉碼(Close Code)

reason:關閉原因

這兩個參數可參考The WebSocket Protocol文檔進行配置

true

在任務結束後,無論是否出現異常都需要關閉WebSocket串連,避免造成串連泄漏。關於如何複用串連提升效率請參考即時語音辨識高並發情境

public String getLastRequestId()

requestId

擷取當前任務的requestId,在調用callstreamingCall開始新任務之後可以使用。

說明

該方法自2.18.0版本及以後的SDK中才開始提供。

public long getFirstPackageDelay()

首包延遲

擷取首包延遲,從發送第一包音頻到收到首包識別結果延遲,在任務完成後使用。

說明

該方法自2.18.0版本及以後的SDK中才開始提供。

public long getLastPackageDelay()

尾包延遲

獲得尾包延遲,發送stop指令到最後一包識別結果下發耗時,在任務完成後使用。

說明

該方法自2.18.0版本及以後的SDK中才開始提供。

回調介面(ResultCallback

雙向流式調用時,服務端會通過回調的方式,將關鍵流程資訊和資料返回給用戶端。您需要實現回調方法,處理服務端返回的資訊或者資料。

回調方法的實現,通過繼承抽象類別ResultCallback完成,繼承該抽象類別時,您可以指定泛型為RecognitionResultRecognitionResult封裝了伺服器返回的資料結構。

由於Java支援串連複用,因此沒有onCloseonOpen

樣本

ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
    @Override
    public void onEvent(RecognitionResult result) {
        System.out.println("RequestId為:" + result.getRequestId());
        // 在此實現處理語音辨識結果的邏輯
    }

    @Override
    public void onComplete() {
        System.out.println("任務完成");
    }

    @Override
    public void onError(Exception e) {
        System.out.println("任務失敗:" + e.getMessage());
    }
};

介面/方法

參數

傳回值

描述

public void onEvent(RecognitionResult result)

result即時識別結果(RecognitionResult)

當服務有回複時會被回調。

public void onComplete()

任務完成後該介面被回調。

public void onError(Exception e)

e:異常資訊

發生異常時該介面被回調。

響應結果

即時識別結果(RecognitionResult

RecognitionResult代表一次即時識別的結果。

介面/方法

參數

傳回值

描述

public String getRequestId()

requestId

擷取requestId。

public boolean isSentenceEnd()

是否是完整句子,即產生斷句

判斷給定句子是否已經結束。

public Sentence getSentence()

單句資訊(Sentence)

擷取單句資訊,包括時間戳記和文本資訊等。

單句資訊(Sentence

介面/方法

參數

傳回值

描述

public Long getBeginTime()

句子開始時間,單位為ms

返回句子開始時間。

public Long getEndTime()

句子結束時間,單位為ms

返回句子結束時間。

public String getText()

識別文本

返回識別文本。

public List<Word> getWords()

字時間戳記資訊(Word)的List集合

返回字時間戳記資訊。

public String getEmoTag()

當前句子的情感

返回當前句子的情感:

  • positive:正面情感,如開心、滿意

  • negative:負面情感,如憤怒、沉悶

  • neutral:無明顯情感

情感識別遵循如下約束:

  • 僅限paraformer-realtime-8k-v2模型。

  • 必須關閉語義斷句(可通過請求參數semantic_punctuation_enabled控制)。語義斷句預設為關閉狀態。

  • 只有在即時識別結果(RecognitionResult)isSentenceEnd方法返回結果為true時才顯示情感識別結果。

public Double getEmoConfidence()

當前句子識別情感的信賴度

返回當前句子識別情感的信賴度,取值範圍:[0.0,1.0],值越大表示信賴度越高。

情感識別遵循如下約束:

  • 僅限paraformer-realtime-8k-v2模型。

  • 必須關閉語義斷句(可通過請求參數semantic_punctuation_enabled控制)。語義斷句預設為關閉狀態。

  • 只有在即時識別結果(RecognitionResult)isSentenceEnd方法返回結果為true時才顯示情感識別結果。

字時間戳記資訊(Word

介面/方法

參數

傳回值

描述

public long getBeginTime()

字開始時間,單位為ms

返回字開始時間。

public long getEndTime()

字結束時間,單位為ms

返回字結束時間。

public String getText()

返回識別的字。

public String getPunctuation()

標點

返回標點。

錯誤碼

如遇報錯問題,請參見錯誤資訊進行排查。

若問題仍未解決,請加入開發人員群反饋遇到的問題,並提供Request ID,以便進一步排查問題。

更多樣本

更多樣本,請參見GitHub

常見問題

功能特性

Q:在長時間靜默的情況下,如何保持與服務端長串連?

將請求參數heartbeat設定為true,並持續向服務端發送靜音音頻。

靜音音頻指的是在音頻檔案或資料流中沒有聲音訊號的內容。靜音音頻可以通過多種方法產生,例如使用音頻編輯軟體如Audacity或Adobe Audition,或者通過命令列工具如FFmpeg。

Q:如何將音頻格式轉換為滿足要求的格式?

可使用FFmpeg工具,更多用法請參見FFmpeg官網。

# 基礎轉換命令(萬能模板)
# -i,作用:輸入檔案路徑,常用值樣本:audio.wav
# -c:a,作用:音頻編碼器,常用值樣本:aac, libmp3lame, pcm_s16le
# -b:a,作用:位元速率(音質控制),常用值樣本:192k, 320k
# -ar,作用:採樣率,常用值樣本:44100 (CD), 48000, 16000
# -ac,作用:聲道數,常用值樣本:1(單聲道), 2(立體聲)
# -y,作用:覆蓋已存在檔案(無需值)
ffmpeg -i input_audio.ext -c:a 編碼器名 -b:a 位元速率 -ar 採樣率 -ac 聲道數 output.ext

# 例如:WAV → MP3(保持原始品質)
ffmpeg -i input.wav -c:a libmp3lame -q:a 0 output.mp3
# 例如:MP3 → WAV(16bit PCM標準格式)
ffmpeg -i input.mp3 -c:a pcm_s16le -ar 44100 -ac 2 output.wav
# 例如:M4A → AAC(提取/轉換蘋果音頻)
ffmpeg -i input.m4a -c:a copy output.aac  # 直接提取不重編碼
ffmpeg -i input.m4a -c:a aac -b:a 256k output.aac  # 重編碼提高品質
# 例如:FLAC無損 → Opus(高壓縮)
ffmpeg -i input.flac -c:a libopus -b:a 128k -vbr on output.opus

Q:是否支援查看每句話對應的時間範圍?

支援。語音辨識結果中會包含每句話的開始時間戳和結束時間戳記,可通過它們確定每句話的時間範圍。

Q:如何識別本地檔案(錄音檔案)?

識別本地檔案有兩種方式:

  • 直接傳入本地檔案路徑:此種方式在最終識別結束後擷取完整識別結果,不適合即時反饋的情境。

    參見非流式調用,在Recognition類call方法中傳入檔案路徑對錄音檔案直接進行識別。

  • 將本地檔案轉成二進位流進行識別:此種方式一邊識別檔案一邊流式擷取識別結果,適合即時反饋的情境。

故障排查

Q:無法識別語音(無識別結果)是什麼原因?

  1. 請檢查請求參數中的音頻格式(format)和採樣率(sampleRate/sample_rate)設定是否正確且符合參數約束。以下為常見錯誤樣本:

    • 音頻副檔名為 .wav,但實際為 MP3 格式,而請求參數 format 設定為 mp3(參數設定錯誤)。

    • 音頻採樣率為 3600Hz,但請求參數 sampleRate/sample_rate 設定為 48000(參數設定錯誤)。

    可以使用ffprobe工具擷取音訊容器、編碼、採樣率、聲道等資訊:

    ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
  2. 使用paraformer-realtime-v2模型時,請檢查language_hints設定的語言是否與音頻實際語言一致。

    例如:音頻實際為中文,但language_hints設定為en(英文)。