讯飞 语音sdk 分段播放文本

本文介绍如何使用讯飞语音合成SDK实现文本的分段播放功能。主要步骤包括:将待播放文本存储于数组中,依次播放数组中的每个文本片段,并通过回调函数控制播放流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

讯飞语音合成sdk中 分段播放文本功能的实现。


1.建立一个数组,把要分段播放的文本放入数组

2.首先播放数组的第一个记录。    [_iFlySpeechSynthesizer startSpeaking:@"测试语音"];

3. 在onComplete 方法中去播放下一个记录

_iFlySpeechSynthesizer4.注意,由于 _iFlySpeechSynthesizer 是派送单独线程进行 语音播放,在onComplete中无法获得 _iFlySpeechSynthesizer的上下文,所以要用这样的代码:

//把数组中的内容分段阅读,中间加入提示音
-(void) speechWithArray{
    if(self.speech_content_array == nil || [self.speech_content_array count] <= 0 ){
        return ;
    }
    [self speechWithString:self.speech_content_array[0] ];
}

-(void) speechWithString:(NSString  *) content{
    DLog(@"合成语音的内容是%@",content);
    [_iFlySpeechSynthesizer startSpeaking:content];
}


/** 播放后结束回调

 当整个合成结束之后会回调此函数

 @param error 错误码
 */
- (void) onCompleted:(IFlySpeechError*) error{
    self.current_speech_number ++;
    if (self.current_speech_number < [self.speech_content_array count]){
        [self.audioPlayer play];
        [self performSelectorOnMainThread:@selector(speechWithString:) withObject:(NSString *)self.speech_content_array[self.current_speech_number] waitUntilDone:NO];
    }else{
        [self.voiceHud dismissView];
        current_msc_status = MSC_Ready;
    }

}

<span style="color:#ff0000;">[self performSelectorOnMainThread:@selector(speechWithString:) withObject:(NSString *)self.speech_content_array[self.current_speech_number] waitUntilDone:NO];</span>
这个是关键。
2 预备工作 2.1 创建iOS工程 在XCode中建立你的工程,或者打开已经建立的工程。 2.2 添加静态库 将开发工具包中lib目录下的iflyMSC.framework添加到新建工程中(如下图所示)。 提交 图一 图二 提交 图三 2.3 添加framework 按下图添加SDK所需要的iOS库,请注意libz.dylib,CoreTelephoney.framework不要遗漏。 提交 图四 注:如果使用的是离线识别,还需要增加libc++.dylib。 2.4 确认SDK的路径 提交 图五 请确认上图红色部分的路径能够找到iflyMSC.framework。为了支持多人开发,建议双击红色部分,把路径改为相对路径,例如像下图所示。 提交 图六 注意:请把不必要的路径删除。例如更新了SDK后,新的SDK与旧的SDK不在同一路径,请把旧的路径删除,避免引用到旧的库。对应集成SDK后发现编译失败,提示找不到头文件,请先检查这个路径是否正确。 2.5 导入头文件 在你需要使用MSC服务的文件中导入相应的头文件 例如: C/C++ Code //带界面的语音识别控件 #import “iflyMSC/IFlyRecognizerViewDelegate.h” #import “iflyMSC/IFlyRecognizerView.h” C/C++ Code //不带界面的语音识别控件 #import “iflyMSC/IFlySpeechRecognizerDelegate.h” #import “iflyMSC/IFlySpeechRecognizer.h” C/C++ Code //不带界面的语音合成控件 #import “iflyMSC/IFlySpeechSynthesizerDelegate.h” #import “iflyMSC/IFlySpeechSynthesizer.h” 2.6 集成帮助文档到Xcode 打开终端(termainl或iterm),cd 到压缩包的doc 目录,执行以下命令: 注:不同的xcode版本,对应的docset路径可能有变化,需要根据实际路径来操作。 C/C++ Code cp -R -f -a com.iflytek.documentation.IFlyMSC.docset ~/Library/Developer/Shared/Documentation/DocSets/ 然后执行命令 C/C++ Code open ~/Library/Developer/Shared/Documentation/DocSets/ 请核对文档的版本为最新下载的版本 提交 图七 打开Xcode的帮助文档就可以看到已经集成的文档 提交 图八 2.7 初始化 必须在初始化后才可以使用语音服务,初始化是异步过程,推荐在程序入口处调用。 Appid是应用的身份信息,具有唯一性,初始化时必须要传入Appid。可以从demo的Definition.h APPID_VALUE中查看此信息。Demo和SDK申请地址:http://xfyun.cn C/C++ Code //将“12345678”替换成您申请的APPID。 NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@",@” 12345678”]; [IFlySpeechUtility createUtility:initString]; 3 语音听写 使用示例如下: C/C++ Code //头文件定义 //需要实现IFlyRecognizerViewDelegate,为识别会话的服务代理 @interface RecognizerViewController : UIViewController<IFlyRecognizerViewDelegate> { IFlyRecognizerView *_iflyRecognizerView; } //初始化语音识别控件 _iflyRecognizerView = [[IFlyRecognizerView alloc] initWithCenter:self.view.center]; _iflyRecognizerView.delegate = self; [_iflyRecognizerView setParameter: @"iat" forKey: [IFlySpeechConstant IFLY_DOMAIN]]; //asr_audio_path保存录音文件名,如不再需要,设置value为nil表示取消,默认目录是documents [_iflyRecognizerView setParameter:@"asrview.pcm " forKey:[IFlySpeechConstant ASR_AUDIO_PATH]]; //启动识别服务 [_iflyRecognizerView start]; /*识别结果返回代理 @param resultArray 识别结果 @ param isLast 表示是否最后一次结果 */ - (void)onResult: (NSArray *)resultArray isLast:(BOOL) isLast { } /*识别会话错误返回代理 @ param error 错误码 */ - (void)onError: (IFlySpeechError *) error { } 4 语音识别 4.1 在线语音识别 上传联系人,使用示例如下: C/C++ Code //创建上传对象 _uploader = [[IFlyDataUploader alloc] init]; //获取联系人集合 IFlyContact *iFlyContact = [[IFlyContact alloc] init]; NSString *contactList = [iFlyContact contact]; //设置参数 [_uploader setParameter:@"uup" forKey:@"subject"]; [_uploader setParameter:@"contact" forKey:@"dtt"]; //启动上传 [_uploader uploadDataWithCompletionHandler:^(NSString * grammerID, IFlySpeechError *error) { //接受返回的grammerID和error [self onUploadFinished:grammerID error:error]; }name:@"contact" data: contactList]; 上传用户词表,使用示例如下: C/C++ Code //创建上传对象 _uploader = [[IFlyDataUploader alloc] init]; //生成用户词表对象 //用户词表 #define USERWORDS @"{\"userword\":[{\"name\":\"iflytek\",\"words\":[\"德国盐猪手\",\"1912酒吧街\",\"清蒸鲈鱼\",\"挪威三文鱼\",\"黄埔军校\",\"横沙牌坊\",\"科大讯飞\"]}]}" IFlyUserWords *iFlyUserWords = [[IFlyUserWords alloc] initWithJson:USERWORDS ]; #define NAME @"userwords" //设置参数 [_uploader setParameter:@"iat" forKey:@"sub"]; [_uploader setParameter:@"userword" forKey:@"dtt"]; //上传词表 [_uploader uploadDataWithCompletionHandler:^(NSString * grammerID, IFlySpeechError *error) { //接受返回的grammerID和error [self onUploadFinished:grammerID error:error]; } name:NAME data:[iFlyUserWords toString]]; abnf语法上传,示例如下: C/C++ Code // ABNF语法示例,可以说”北京到上海” #define ABNFPARAM @”sub=asr,dtt=abnf” #define ABNFDATA = “#ABNF 1.0 gb2312; language zh-CN; mode voice; root $main; $main = $place1 到$place2 ; $place1 = 北京 | 武汉 | 南京 | 天津 | 天京 | 东京; $place2 = 上海 | 合肥;” //创建上传对象 _uploader = [[IFlyDataUploader alloc] init]; //设置参数 [_uploader setParameter:@"asr" forKey:@"sub"]; [_uploader setParameter:@"abnf" forKey:@"dtt"]; //上传abnf语法 [_uploader uploadDataWithCompletionHandler:^(NSString * grammerID, IFlySpeechError *error) { //接受返回的grammerID和error [self setGrammerId:grammerID]; }name:ABNFNAME data:ABNFDATA]; 4.2 本线语音识别 1) 创建识别对象(注:如果使用的是离线识别,还需要增加libc++.dylib) C/C++ Code //此方法为demo中封装,具体实现请参照demo。 self.iFlySpeechRecognizer = [RecognizerFactory CreateRecognizer:self Domain:@"asr"]; 2)设置参数 C/C++ Code //开启候选结果 [_iflySpeechRecognizer setParameter:@"1" forKey:@"asr_wbest"]; //设置引擎类型,clound或者local [_iflySpeechRecognizer setParameter:@”local” forKey:[IFlySpeechConstant ENGINE_TYPE]]; //设置字符编码为utf-8 [_iflySpeechRecognizer setParameter:@"utf-8" forKey:[IFlySpeechConstant TEXT_ENCODING]]; //语法类型,本地是bnf,在线识别是abnf [_iflySpeechRecognizer setParameter:@”bnf” forKey:[IFlyResourceUtil GRAMMARTYPE]]; //启动asr识别引擎 [[IFlySpeechUtility getUtility] setParameter:@"asr" forKey:[IFlyResourceUtil ENGINE_START]]; //设置服务类型为asr识别 [_iflySpeechRecognizer setParameter:@"asr" forKey:[IFlySpeechConstant IFLY_DOMAIN]]; //设置语法构建路径,该路径为sandbox下的目录,请确保目录存在 [_iflySpeechRecognizer setParameter:_grammBuildPath forKey:[IFlyResourceUtil GRM_BUILD_PATH]]; //设置引擎资源文件路径,如demo中的aitalkResource中的common.mp3 [_iflySpeechRecognizer setParameter:_aitalkResourcePath forKey:[IFlyResourceUtil ASR_RES_PATH]]; 3)编译语法文本
在Ubuntu系统中使用TTS(Text-to-Speech)语音合成时,可能会遇到合成失败的问题。这通常与API调用、网络连接、文件权限、依赖库缺失或代码逻辑有关。以下是常见的排查与解决方法: ### 检查API调用与认证 确保使用的是正确的API密钥和私钥,并且已经正确配置了访问权限。如果使用的是百度TTS API,需检查`client_id`和`client_key`是否正确[^1]。此外,确认API调用次数是否已超出免费额度或是否被限制。 ### 检查网络连接 TTS服务通常依赖于远程服务器,因此需要确保系统能够正常访问互联网,并且能够连接到TTS服务提供商的服务器。可以通过`ping`或`curl`命令测试网络连通性。例如: ```bash ping ai.baidu.com ``` 或 ```bash curl -I https://tsn.baidu.com ``` ### 检查返回结果与日志 查看API返回的错误码和错误信息,以便更准确地定位问题。例如,百度TTS API会返回`err_no`、`err_msg`等字段,帮助判断是参数错误、认证失败还是服务不可用等问题[^1]。 ### 检查文件路径与权限 如果语音合成后的文件无法保存,可能是由于文件路径不存在或权限不足。确保目标目录存在且具有写权限。例如: ```bash mkdir -p /path/to/output chmod 777 /path/to/output ``` ### 安装必要的依赖库 如果使用的是C/C++开发的SDK(如语音合成SDK),需要确保系统中已安装所有必要的依赖库,如`libcurl`、`libssl`等。可以使用以下命令安装常见依赖: ```bash sudo apt-get update sudo apt-get install libcurl4-openssl-dev libssl-dev ``` ### 检查文本长度限制 某些TTS服务对输入文本长度有限制。例如,语音合成SDK建议单次合成文本不超过2048个字符,超过时需要分段处理并增加容错机制[^3]。可以在代码中添加文本长度检查逻辑,避免因超限导致合成失败。 ### 示例:文本长度检查 ```c #define MAX_TEXT_LEN 2048 int check_text_length(const char *text) { if (strlen(text) > MAX_TEXT_LEN) { fprintf(stderr, "Error: Text length exceeds maximum allowed length of %d characters.\n", MAX_TEXT_LEN); return -1; } return 0; } ``` ### 检查Makefile与编译环境 如果使用的是嵌入设备或本地编译环境,确保Makefile配置正确,所有依赖库路径已正确设置。例如,在使用`gcc`编译语音控制程序时,确保包含了正确的头文件路径和链接库[^4]: ```makefile CC = gcc CFLAGS = -I./inc -L/usr/lib/x86_64-linux-gnu -lxml2 OBJS = voicectl.o common.o voicectl: $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) ``` ### 调试与日志记录 在程序中添加详细的日志输出,记录API请求参数、返回结果以及关键步骤的状态,以便分析问题。例如: ```c #include <stdio.h> #include <stdlib.h> void log_message(const char *msg) { FILE *log_file = fopen("/var/log/tts_debug.log", "a"); if (log_file) { fprintf(log_file, "%s\n", msg); fclose(log_file); } } ``` ### 使用示例程序测试 参考语音合成示例程序,进入指定目录并运行示例代码,验证是否能够正常生成语音文件。例如: ```bash cd /oem/BDSpeechSDK/sample/tts ./tts_sample "456hello你好今天天气不错" output.pcm ``` 如果示例程序可以正常运行,说明问题可能出在自定义代码逻辑中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值