51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

uniapp利用百度语音接口实现听书功能,简单流程

最近折腾了一下之前那个小说app的听书功能,最开始想法很丰富,比如要搞成音乐播放一样,还带类似歌词滚动啥的东西,然后还去uniapp的插件商城转了一圈,随后就发现那里的插件一个比一个坑爹,要么自带bug要么不兼容,所以扯了好几天进展都反反复复,最后就干脆自己写了,采用uniapp自带的createInnerAudioContext方法。当然,这个方法也是坑一大堆,网上的教程带偏性很严重,要么就是细节都不齐全,不过也还是解决了问题,完成了简略版的听书功能。
所以,就整理个教程水一水吧。

这个教程也不局限于小说内容的听书,任何文字内容都可以处理下,实现语言播放功能。

那么,开始教程吧

前置说明:

百度的语音接口存在字数的限制,同时一次性太多字数也会需要更多的加载时间,所以合理的办法是通过将小说的内容根据段落拆分成数组,变为一个播放列表来进行依次播放,这样就可以明显减小加载延迟同时也减小播放失败的可能性。而且主要是,我发现很多支持听书的app,或者那些网站,都是采用这种模式,毕竟百度的接口是免费的。

百度语音接口参数说明:

这是一条标准的请求地址,可直接用于播放(目前是免费的)

https://ai.baidu.com/aidemo?type=tns&spd=5&pit=5&vol=15&dt=1&per=0&tex=牛逼啊

几个主要的参数如下:

type=tns:数据类型
spd=5:语速,可以是1-9的数字,数字越大,语速越快。
vol=15:音量
per=0:发声,0女生,1男生,3逍遥,4软萌(可能还有其它的,自行测试吧)
tex=**:需要播放的文字

具体步骤

1.在uniapp页面的script标签内全局加上如下代码,定义音频播放的全局对象。

const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = false;

注意这里不能放在onload中,因为这个对象只允许创建一次,而不是每次页面加载都创建,那样会造成多次执行的问题。

2.定义相关字段,包括当前的段落id,播放状态,和内容list

playid:0,
playstatus:false,
contentList:[],

这里的内容contentList字段,我是通过将实际文字内容转换得到的,具体的内容大概如下,这是我的app接口传的数据,具体使用的时候,根据实际为准

这是小说的内容<br/><br/>&#12288;&#12288;
这是第二行的数据<br/><br/>&#12288;&#12288;
这是一条没啥用的数据<br/><br/>&#12288;&#12288;
这是新的一条<br/><br/>&#12288;&#12288;
结尾了<br/><br/>&#12288;&#12288;

然后我通过以下方法,给contentList字段赋值,后面的方法里有,以下只是原理

var content = that.content;
content = content.replace("<h2>","").replace("</h2>","").replace(/[\r\n]/g,"").replace(/\ +/g,""); ;
content = content.split("<br/><br/>&#12288;&#12288;");
var list = [];
for(var i in content){
    var arr = {
        url:"https://ai.baidu.com/aidemo?type=tns&spd=5&pit=5&vol=15&dt=1&per=0&tex="+content[i].replace("<br/>&#12288;&#12288;",""),
        text:content[i].replace("<br/>&#12288;&#12288;",""),
    }
    list.push(arr);
}
that.contentList = list;

3.定义播放相关方法。

//听书功能开始
play(){
    var that = this;
    uni.showToast({
      title: '语音播放开始',
    });
    //获取当前文章内容(可以根据实际情况修改)
    var data = that.currentChapter;
    var content = data.content;
    //获取文章内容结束
    content = content.replace("<h2>","").replace("</h2>","").replace(/[\r\n]/g,"").replace(/\ +/g,""); ;
    content = content.split("<br/><br/>&#12288;&#12288;");
    var list = [];
    for(var i in content){
        var arr = {
            url:"https://ai.baidu.com/aidemo?type=tns&spd=5&pit=5&vol=15&dt=1&per=0&tex="+content[i].replace("<br/>&#12288;&#12288;",""),
            text:content[i].replace("<br/>&#12288;&#12288;",""),
        }
        list.push(arr);
    }
    that.contentList = list;
    //上面一段的具体内容是,获取当前的文章内容,处理成json数组,来为播放做准备,同样的以实际情况为准
    that.playStart(list);
},
//开始播放,根据playid选择播放的段落,默认第一条
playStart(list){
    var that = this;
    var playid = that.playid;
    
    
    innerAudioContext.src = list[playid].url;
    if(!that.playstatus){
        innerAudioContext.play();
    }
    
    
    
},
//依次播放的方法,播放一段自动到下一段,如果大于当前段落总数,则执行本文章内容全部播放完成后方法
playAdd(list){
    var that = this;
    that.playid++;
    var total = list.length;
    if(that.playid > total - 1){
        that.playid = 0;
        //执行本文章内容播放完成后的方法
    }else{
        that.playstatus = false;
        innerAudioContext.stop();
        that.playStart(list);
    }
    //return false
},
//暂停方法
playPause(){
    var that = this;
    that.playstatus = false;
    innerAudioContext.pause();
},

4.在onload中监听

var that = this;
//监听当前段落是否播放完成,完成就播放下一段
innerAudioContext.onEnded(() => {
    var list = that.contentList;
    innerAudioContext.stop();
    that.playAdd(list);
    
});
innerAudioContext.onPlay(() => {
    console.log("播放开始了");
    that.playstatus = true;
});
innerAudioContext.onError((res) => {
  uni.showToast({
    title: '语音播放失败,请检查当前网络',
    icon:'none',
  });
  that.playstatus = false;
});

监听不能放在单独的方法内,因为监听会多次执行导致段落id被多次+1造成顺序问题。

5.onUnload中停止播放

innerAudioContext.stop();

离开页面后,执行停止方法。

4.定义一个点击事件,控制听书的开启和暂停,我这里用了colorUI的图标库

<text class="cuIcon-video" v-show="!playstatus" @tap="play()"></text>
<text class="cuIcon-videofill" v-show="playstatus" @tap="playPause()"></text>

5.效果如下:

Lark20210109-105654.jpeg

教程就到这里,感兴趣的可以加群讨论,目前听书已经整合到app的源码,需要的可以去本站的交易专区购买。

本文来自投稿,不代表本站立场,如若转载,请注明出处:https://www.ruletree.club/archives/2220/

赞(7)
未经允许不得转载:工具盒子 » uniapp利用百度语音接口实现听书功能,简单流程