日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

移動端IOS推流

本文介紹了如何使用阿里云智能語音服務提供的iOS NUI SDK,包括SDK下載安裝、關鍵接口及代碼示例。

前提條件

SDK關鍵接口

  • nui_initialize:初始化SDK。

    /**
     * 初始化SDK,SDK為單例,請先釋放后再次進行初始化。請勿在UI線程調用,可能引起阻塞。
     * @param parameters: 初始化參數(shù),參考如下說明。
     * @param level: log打印級別,值越小打印越多
     * @param save_log: 是否保存log為文件,存儲目錄為parameter中的debug_path字段值。注意,log文件無上限,請注意持續(xù)存儲導致磁盤存滿。
     * @return 參見錯誤碼
     */
    -(NuiResultCode) nui_initialize:(const char *)parameters
                           logLevel:(NuiSdkLogLevel)level
                            saveLog:(BOOL)save_log;
    • parameters詳細說明:

      參數(shù)

      類型

      是否必選

      說明

      workspace

      String

      工作目錄路徑,SDK從該路徑讀取配置文件。

      app_key

      String

      必須填“default”。

      token

      String

      必須填“default”。

      url

      String

      創(chuàng)建聽悟實時記錄任務時返回的會議MeetingJoinUrl作為音頻流推送地址,在后續(xù)實時音頻流識別時通過該地址進行推流。

      service_mode

      String

      必須填“1”,表示啟用在線功能。

      device_id

      String

      設備標識,唯一表示一臺設備(如Mac地址/SN/UniquePsuedoID等)。

      debug_path

      String

      debug目錄。當初始化SDK時的save_log參數(shù)取值為true時,該目錄用于保存日志文件。

      save_wav

      String

      當初始化SDK時的save_log參數(shù)取值為true時,該參數(shù)生效。表示是否保存音頻debug,該數(shù)據(jù)保存在debug目錄中,需要確保debug_path有效可寫。

      注意,音頻文件無上限,請注意持續(xù)存儲導致磁盤存滿。

  • nui_set_params:以JSON格式設置SDK參數(shù)。

    /**
     * 以JSON格式設置參數(shù)。接口需要在nui_initialize之后nui_dialog_start之前調用。
     * @param params: 參數(shù)信息請參見如下說明。
     * @return 參見錯誤碼
     */
    -(NuiResultCode) nui_set_params:(const char *)params;
    • params詳細說明:

      參數(shù)

      類型

      是否必選

      說明

      service_type

      Int

      必須填“4”。此為需要請求的語音服務類型,聽悟實時推流為“4”。

      nls_config

      JsonObject

      訪問語音服務相關的參數(shù)配置,詳見如下。

      nls_config.sr_format

      String

      必須填“pcm”。對應的《CreateTask - 創(chuàng)建聽悟任務》中,創(chuàng)建聽悟任務時也請指定音頻流數(shù)據(jù)的編碼格式為pcm。

      nls_config.sample_rate

      Integer

      音頻采樣率,默認值:16000Hz。對應的《CreateTask - 創(chuàng)建聽悟任務》中,創(chuàng)建聽悟任務時也請指定音頻流數(shù)據(jù)的采樣率,當前支持 8000 和 16000。

  • nui_dialog_start:開始識別。

    /**
     * 開始識別
     * @param vad_mode: 多種模式,對于識別場景,請使用P2T。
     * @param dialog_params: 設置識別參數(shù),可不設置直接傳入空JSON字符串。
     * @return 參見錯誤碼
     */
    -(NuiResultCode) nui_dialog_start:(NuiVadMode)vad_mode
                          dialogParam:(const char *)dialog_params;
  • nui_dialog_cancel:結束識別。

    /**
     * 結束識別,調用該接口后,服務端將返回最終識別結果并結束任務
     * @param force: 是否強制結束而忽略最終結果,false表示停止但是等待完整結果返回
     * @return 參見錯誤碼
     */
    -(NuiResultCode) nui_dialog_cancel:(BOOL)force;
  • nui_release:釋放SDK。

    /**
     * 釋放SDK資源
     * @return 參見錯誤碼
     */
    -(NuiResultCode) nui_release;
  • nui_get_version:獲得當前SDK版本信息。

    /**
     * 獲得當前SDK版本信息
     * @return 字符串形式的SDK版本信息
     */
    -(const char*) nui_get_version;
  • nui_get_all_response:獲得當前事件回調的完整信息。

    /**
     * onNuiEventCallback回調中獲得當前事件回調的完整信息
     * @return json字符串形式的完整事件信息
     */
    -(const char*) nui_get_all_response;
  • NeoNuiSdkDelegate

    onNuiEventCallback:SDK事件回調。

    /**
     * SDK主要事件回調
     * @param event: 回調事件,參見如下事件列表
     * @param dialog: 會話編號,暫不使用
     * @param wuw: 語音喚醒功能使用(暫不支持)
     * @param asr_result: 語音識別結果和翻譯結果
     * @param finish: 本輪識別是否結束標志
     * @param resultCode: 參見錯誤碼,在出現(xiàn)EVENT_ASR_ERROR事件時有效
     */
    -(void) onNuiEventCallback:(NuiCallbackEvent)nuiEvent
                        dialog:(long)dialog
                     kwsResult:(const char *)wuw
                     asrResult:(const char *)asr_result
                      ifFinish:(BOOL)finish
                       retCode:(int)code;

    NuiCallbackEvent事件列表:

    名稱

    說明

    EVENT_VAD_START

    檢測到人聲起點.

    EVENT_VAD_END

    檢測到人聲尾點。

    EVENT_ASR_PARTIAL_RESULT

    語音識別中間結果。

    EVENT_ASR_RESULT

    語音識別最終結果。

    EVENT_ASR_ERROR

    根據(jù)錯誤碼信息判斷出錯原因。

    EVENT_MIC_EEROR

    錄音錯誤,表示SDK連續(xù)2秒未收到任何音頻,可檢查錄音系統(tǒng)是否正常。

    EVENT_SENTENCE_START

    實時語音識別事件,檢測到一句話開始。

    EVENT_SENTENCE_END

    實時語音識別事件,檢測一句話結束,返回一句的完整結果。

    EVENT_SENTENCE_SEMANTICS

    暫不使用。

    EVENT_RESULT_TRANSLATED

    翻譯結果。

    EVENT_TRANSCRIBER_COMPLETE

    停止語音識別后上報。

    onNuiNeedAudioData:獲取音頻。

    /**
     * 開始識別時,此回調被連續(xù)調用,App需要在回調中進行語音數(shù)據(jù)填充
     * @param audioData:  填充語音的存儲區(qū)
     * @param len: 需要填充語音的字節(jié)數(shù)
     * @return 實際填充的字節(jié)數(shù)
     */
    -(int) onNuiNeedAudioData:(char *)audioData length:(int)len;

    onNuiAudioStateChanged:根據(jù)音頻狀態(tài)進行錄音功能的開關。

    /**
     * 當start/stop/cancel等接口調用時,SDK通過此回調通知App進行錄音的開關操作
     * @param state:錄音需要的狀態(tài)(打開/關閉)
     */
    -(void) onNuiAudioStateChanged:(NuiAudioState)state;

    onNuiRmsChanged:音頻能量事件。

    /**
     * SDK運行過程中收到音頻的實時音頻能量值。
     * @param rms: 音頻能量值,范圍為-160至0
     */
    -(void) onNuiRmsChanged:(float) rms;

調用步驟

重要

請下載后在聽悟的樣例初始化代碼中將Appkey和Token置為default,url置為您創(chuàng)建聽悟實時記錄返回的會議MeetingJoinUrl。

  1. 初始化SDK、錄音實例。

  2. 根據(jù)業(yè)務需求配置參數(shù)。

  3. 調用nui_dialog_start開始識別。

  4. 根據(jù)音頻狀態(tài)回調onNuiAudioStateChanged,打開錄音機。

  5. 在onNuiNeedAudioData回調中提供錄音數(shù)據(jù)。

  6. 在EVENT_ASR_PARTIAL_RESULT和EVENT_SENTENCE_END事件回調中獲取識別結果,在EVENT_RESULT_TRANSLATED事件回調中獲得翻譯結果。

  7. 調用nui_dialog_cancel結束識別。

  8. 結束調用,使用nui_release接口釋放SDK資源。

代碼示例

說明

接口默認采用get_instance方式獲得單例,您如果有多例需求,也可以直接alloc對象進行使用。

NUI SDK初始化

BOOL save_log = NO;
NSString * initParam = [self genInitParams];
[_nui nui_initialize:[initParam UTF8String] logLevel:NUI_LOG_LEVEL_VERBOSE saveLog:save_log];

其中,genInitParams生成為String JSON字符串,包含資源目錄和用戶信息。其中用戶信息包含如下字段。

-(NSString*) genInitParams {
    NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
    NSString *bundlePath = [[NSBundle bundleWithPath:strResourcesBundle] resourcePath];
    NSString *debug_path = [_utils createDir];

    // 1. 接口與實現(xiàn):http://bestwisewords.com/zh/tingwu/interface-and-implementation?spm=a2c4g.11186623.0.0.2b045060jFsVFw
    //    按文檔步驟,首先創(chuàng)建AccessKey和創(chuàng)建項目
    //    然后需要用戶在自己的服務端調用CreateTask接口創(chuàng)建實時記錄,獲得MeetingJoinUrl
    //    此MeetingJoinUrl即為下方url
    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];

    //賬號和項目創(chuàng)建
    //  ak_id ak_secret 如何獲得,請查看http://bestwisewords.com/document_detail/72138.html
    [dictM setObject:@"default" forKey:@"app_key"]; // 必填,不改動
    [dictM setObject:@"default" forKey:@"token"]; // 必填,不改動

    // url中填入生成的MeetingJoinUrl。
    // 由于MeetingJoinUrl生成過程涉及ak/sk,移動端不可存儲賬號信息,故需要在服務端生成,并下發(fā)給移動端。
    // 詳細請看: http://bestwisewords.com/zh/tingwu/api-tingwu-2023-09-30-createtask
    [dictM setObject:@"wss://tingwu-realtime-cn-hangzhou-pre.aliyuncs.com/api/ws/v1?XXXX" forKey:@"url"]; // 必填
    //工作目錄路徑,SDK從該路徑讀取配置文件
    [dictM setObject:bundlePath forKey:@"workspace"]; // 必填

    //當初始化SDK時的save_log參數(shù)取值為true時,該參數(shù)生效。表示是否保存音頻debug,該數(shù)據(jù)保存在debug目錄中,需要確保debug_path有效可寫
    [dictM setObject:save_wav ? @"true" : @"false" forKey:@"save_wav"];
    //debug目錄。當初始化SDK時的save_log參數(shù)取值為true時,該目錄用于保存中間音頻文件
    [dictM setObject:debug_path forKey:@"debug_path"];
    
    //FullCloud = 1 // 在線實時語音識別可以選這個
    [dictM setObject:@"1" forKey:@"service_mode"]; // 必填,不改動

    NSString *id_string = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    TLog(@"id: %s", [id_string UTF8String]);
    [dictM setObject:id_string forKey:@"device_id"]; // 必填, 推薦填入具有唯一性的id, 方便定位問題

    NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

參數(shù)設置

以JSON字符串形式進行設置。

-(NSString*) genParams {
    NSMutableDictionary *nls_config = [NSMutableDictionary dictionary];
    [nls_config setValue:@16000 forKey:@"sample_rate"];
    [nls_config setValue:@"pcm" forKey:@"sr_format"];
    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
    [dictM setObject:nls_config forKey:@"nls_config"];
    [dictM setValue:@(SERVICE_TYPE_SPEECH_TRANSCRIBER) forKey:@"service_type"]; // 必填
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:dictM options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

NSString * parameters = [self genParams];
[_nui nui_set_params:[parameters UTF8String]];

開始識別

通過nui_dialog_start接口開啟監(jiān)聽。

-(NSString*) genDialogParams {
    NSMutableDictionary *dialog_params = [NSMutableDictionary dictionary];    
    NSData *data = [NSJSONSerialization dataWithJSONObject:dialog_params options:NSJSONWritingPrettyPrinted error:nil];
    NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    return jsonStr;
}

NSString * parameters = [self genDialogParams];
[_nui nui_dialog_start:MODE_P2T dialogParam:[parameters UTF8String]];

回調處理

  • onNuiAudioStateChanged:錄音狀態(tài)回調,SDK內部維護錄音狀態(tài),調用時根據(jù)該狀態(tài)的回調進行錄音機的開關操作。

    -(void)onNuiAudioStateChanged:(NuiAudioState)state{
        TLog(@"onNuiAudioStateChanged state=%u", state);
        if (state == STATE_CLOSE || state == STATE_PAUSE) {
            // 舊版本示例工程提供的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            // [_voiceRecorder stop:YES];
    
            // 新版本示例工程提供了新的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            [_audioController stopRecorder:NO];
        } else if (state == STATE_OPEN){
            self.recordedVoiceData = [NSMutableData data];
            // 舊版本示例工程提供的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            // [_voiceRecorder start];
    
            // 新版本示例工程提供了新的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            [_audioController startRecorder];
        }
    }
  • onNuiNeedAudioData:錄音數(shù)據(jù)回調,在該回調中填充錄音數(shù)據(jù)。

    -(int)onNuiNeedAudioData:(char *)audioData length:(int)len {
        static int emptyCount = 0;
        @autoreleasepool {
            @synchronized(_recordedVoiceData){
                if (_recordedVoiceData.length > 0) {
                    int recorder_len = 0;
                    if (_recordedVoiceData.length > len)
                        recorder_len = len;
                    else
                        recorder_len = _recordedVoiceData.length;
                    NSData *tempData = [_recordedVoiceData subdataWithRange:NSMakeRange(0, recorder_len)];
                    [tempData getBytes:audioData length:recorder_len];
                    tempData = nil;
                    NSInteger remainLength = _recordedVoiceData.length - recorder_len;
                    NSRange range = NSMakeRange(recorder_len, remainLength);
                    [_recordedVoiceData setData:[_recordedVoiceData subdataWithRange:range]];
                    emptyCount = 0;
                    return recorder_len;
                } else {
                    if (emptyCount++ >= 50) {
                        TLog(@"_recordedVoiceData length = %lu! empty 50times.", (unsigned long)_recordedVoiceData.length);
                        emptyCount = 0;
                    }
                    return 0;
                }
    
            }
        }
        return 0;
    }
  • onNuiEventCallback:NUI SDK事件回調,請勿在事件回調中調用SDK的接口,可能引起死鎖。

    -(void)onNuiEventCallback:(NuiCallbackEvent)nuiEvent
                       dialog:(long)dialog
                    kwsResult:(const char *)wuw
                    asrResult:(const char *)asr_result
                     ifFinish:(bool)finish
                      retCode:(int)code {
        TLog(@"onNuiEventCallback event %d finish %d", nuiEvent, finish);
        if (nuiEvent == EVENT_ASR_PARTIAL_RESULT || nuiEvent == EVENT_SENTENCE_END) {
            // asr_result在此包含task_id,task_id有助于排查問題,請用戶進行記錄保存。
            TLog(@"ASR RESULT %s finish %d", asr_result, finish);
            NSString *result = [NSString stringWithUTF8String:asr_result];
        } else if (nuiEvent == EVENT_RESULT_TRANSLATED) {
            // 獲得翻譯結果
            NSString *result = [NSString stringWithUTF8String:asr_result];
        } else if (nuiEvent == EVENT_ASR_ERROR) {
            // asr_result在EVENT_ASR_ERROR中為錯誤信息,搭配錯誤碼code和其中的task_id更易排查問題,請用戶進行記錄保存。
            TLog(@"EVENT_ASR_ERROR error[%d], error mesg[%s]", code, asr_result);
    
            // 可通過nui_get_all_response獲得完整的信息
            const char *response = [_nui nui_get_all_response];
            if (response != NULL) {
                TLog(@"GET ALL RESPONSE: %s", response);
            }
        } else if (nuiEvent == EVENT_MIC_ERROR) {
            TLog(@"MIC ERROR");
            // 舊版本示例工程提供的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            // [_voiceRecorder stop:YES];
            // [_voiceRecorder start];
    
            // 新版本示例工程提供了新的錄音模塊,僅做參考,可根據(jù)自身業(yè)務重寫錄音模塊。
            [_audioController stopRecorder:NO];
            [_audioController startRecorder];
        }
    
        //finish 為真(可能是發(fā)生錯誤,也可能是完成識別)表示一次任務生命周期結束,可以開始新的識別
        if (finish) {
        }
        
        return;
    }

結束識別

[_nui nui_dialog_cancel:NO];