语音录制和播放

权限配置

Android

需要配置 AndroidManifest.xml,添加权限如下:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

另外开发者在android系统下需要调用 System.loadLibrary("nim_audio")加载库文件。

iOS

iOS 10系统以上版本要求开发者添加权限申请的描述,否则程序在这些系统上会出现崩溃。开发者需要用到语音消息,那么就应该添加麦克风权限申请的描述。

key:Privacy - Microphone Usage Description
value: 是否允许此app使用麦克风?

若录音影响游戏音效之类的问题,需要每次调用sdk录音或者播放,结束以后,需要开发者调用OC接口将 audio session的category设置一下

[AVAudioSession sharedInstance] setCategory:xxxxxxxx]
/*Use this category for background sounds such as rain,car engine noise,etc.Mixes with other music.*/
AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient ;
/*Use this category for background sounds.other music will stop playing.*/
AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient;

初始化与清理

在使用语音功能前必须调用接口nim_audio::Audio::Init初始化语音模块;在退出程序前,调用接口nim_audio::Audio::ClearUp释放语音模块。

录制

在录制语音时需要确保录音设备运行正常。网易云通信 SDK 提供了一套录制高清语音的接口,用于采集,编码,存储高清语音数据,并提供过程回调,当前支持的录制语音文件格式包括amr和aac。

开始录制

/** @fn   bool StartCapture(int audio_format,int volume,int loudness,const std::string& capture_device)
* 开始录制语音
* @param[in] audio_format音频格式,AAC:0,AMR:1
* @param[in] volume 音量(0-255,默认180)pc有效
* @param[in] loudness 默认0,pc有效
* @param[in] capture_device 录音设备,pc有效,默认值传空字符串即可。
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool StartCapture(int audio_format,int volume,int loudness,const std::string& capture_device);

开始录制结果回调

/** @fn  bool RegStartCaptureCb(const OptResCallback& cb)
* 注册开始录制的回调函数
* @param[in] cb 回调函数
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool RegStartCaptureCb(const OptResCallback& cb);

结束录制

/** @fn  bool StopCapture()
* 停止录制语音
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool StopCapture();

结束录制回调

/** @fn   bool RegStopCaptureCb(const StopCaptureCallback& cb)
* 注册停止录制的回调函数
* @param[in] cb 回调函数
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool RegStopCaptureCb(const StopCaptureCallback& cb);
void OnStartCaptureCallback(int code)
{
    //开始录制回调,code != 200 表示录制出现错误
}

void OnStopCaptureCallback(int rescode, const char* sid, const char* cid, const char* file_path, const char* file_ext, long file_size, int audio_duration)
{
    //录制结束,函数参数包含录制文件的详细信息
}

void DoCapture(const std::string session_id, const std::string msg_id, nim_audio::nim_audio_type audio_format /*= nim_audio::AAC*/, int volume /*= 180*/, const wchar_t* capture_device /*= nullptr*/)
{
    nim_audio::Audio::RegStartCaptureCb(&OnStartCaptureCallback);
    nim_audio::Audio::RegStopCaptureCb(&OnStopCaptureCallback);
    nim_audio::Audio::StartCapture(session_id.c_str(), msg_id.c_str(), audio_format, volume, capture_device);
    nim_audio::Audio::StopCapture();
}

取消录制

进行语音录制时可以取消录制,SDK会停止当前录制并删除已保存的临时文件,通过回调获取操作结果。

/** @fn  bool CancelCapture()
* 取消录制语音
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool CancelCapture();
void OnCancelCaptureCallback(int code)
{
    //取消录制结果
}

bool CancelCapture()
{
    nim_audio::Audio::RegCancelAudioCb(&OnCancelCaptureCallback);
    return nim_audio::Audio::CancelCapture();
}

播放

语音消息录制和播放等接口封装在Audio类中,相关的C++接口代码在cpp/nim_audio/api子目录下,具体接口说明请参考api文档说明。网易云通信的语音消息格式有 aac 和 amr 两种格式可选,播放时需要传入文件路径和语音格式,通过注册回调函数获取播放状态。

/** @fn bool PlayAudio(const std::string& path,int audio_format)
* 语音播放,开始播放状态通过回调返回
* @param[in] path 播放文件绝对路径
* @param[in] audio_format 播放音频格式,AAC0AMR:1
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool PlayAudio(const std::string& path,int audio_format);

/** @fn  bool RegStartPlayCb(const PlayOptCallback& cb)
* 注册开始播放事件回调函数
* @param[in] cb 回调函数
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool RegStartPlayCb(const PlayOptCallback& cb);

停止播放

在语音播放过程中可以随时停止播放,通过回调函数获取操作结果。

/** @fn bool StopPlayAudio()
* 停止播放,停止播放结果通过回调返回
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool StopPlayAudio();

/** @fn  bool RegStopPlayCb(const PlayOptCallback& cb)
* 注册停止播放事件回调函数
* @param[in] cb 回调函数
* @return bool 返回值true:调用成功,false:调用失败
*/
static bool RegStopPlayCb(const PlayOptCallback& cb);

语音转文字

将接收到的语音消息转换为文本内容。

void foo(nim::IMMessage &msg_data)
{
    nim::IMAudio audio;
    nim::Talk::ParseAudioMessageAttach(msg_data, audio);
    nim::AudioInfo audio_info;
    audio_info.samplerate_ = "16000";
    audio_info.url_ = audio.url_;
    audio_info.duration_ = audio.duration_;
    audio_info.mime_type_ = audio.file_extension_;

    nim::Tool::GetAudioTextAsync(audio_info, ToWeakCallback([this](int rescode, const std::string& text) {
        if (rescode == nim::kNIMResSuccess) {
            ···
        }
        else {
            ···
        }
    }));
}