先上两张效果图:
image.png
image.png
上面两张图分别代表录音列表和播放的两种状态
如果我们有多条录音数据,每个数据都可以播放,一般是我们点击播放的时候再去请求接口,获取相关的数据,获取数据后,用URL.createObjectURL转换为url,然后 用new Audio新建一个播放器,然后播放,然后暂停或者切换其他的数据播放,图形的变化以及最后录音播放完的提示和图形的变化,这是一个大概的思路过程。其中最难得我觉得是多条数据播放和暂停质检图形的变化。
下面我上代码,大家可以简单看下:
image.png
引入共用表格组件,起始最开始的时候我们也觉得使用表格组件在不同的页面使用各自的组件挺好,但到了项目后期和维护的时候,常常需要修改表格的一些样式或者其它,又因为使用了大量的表格,要在不同的文件去改,这就很繁琐。后来,我们把一些共用的组件写成了共用组件,调用很方便。
image.png这就是表格共用组件里专门为播放组件进行专门适配的。传入tb.operationName2,如果有这部分组件才会生效,然后用class和element的icon标识去切换图标,
image.png这就是传入表格共用组件的参数,operationName2是专门为表格后面的按钮设置的参数。
// 播放
playRecord(scope,btn,index) {
let row = this.tb.data[scope.$index]
let url = scope.row.url;
//检查是否有audio
if(!url){
this.$message.error('没有录音文件');
return false;
}
if(this.audio) {
this.audio.pause();
}
this.tb.data.map( (item,index) => {
if(item.url != url && item.icon != "el-icon-service") {
item.icon = 'el-icon-service';
this.$set(this.tb.data,index,item);
}
})
if (scope.row.icon == 'el-icon-service') {
row.icon = 'el-icon-loading';
this.$set(this.tb.data,scope.$index,row);
this.$axios({ // 用axios发送post请求
method: 'post',
url: '/api/robot/caseManager/downLoadVoice', // 请求地址
data: {
url: url
}, // 参数
responseType: 'blob' // 表明服务器返回的数据类型
})
.then((res) => { // 处理返回的文件流
if (res.data.type != 'application/json') {
const formatArr = (res.headers['content-disposition']).split(".");
const format = formatArr[formatArr.length - 1];
const content = res.data;
const blob = new Blob([content]);
if ('download' in document.createElement('a')) { // 非IE下载
this.audio = new Audio();
this.audio.src = URL.createObjectURL(res.data);
row.icon = "el-icon-more";
this.$set(this.tb.data,scope.$index,row)
this.audio.play();
var self = this;
this.audio.onended = function () {
self.$message.success('播放完毕');
row.icon = "el-icon-service";
self.$set(self.tb.data,scope.$index,row)
}
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName)
}
} else {
this.$message({
type: 'error',
message: '播放失败'
})
row.icon ='el-icon-service';
this.$set(this.tb.data,scope.$index,row)
}
})
.catch(err => {
console.log(err)
})
} else if (scope.row.icon == 'el-icon-more') {
row.icon = 'el-icon-caret-right';
this.$set(this.tb.data,scope.$index,row)
this.audio.pause();
} else if (scope.row.icon == 'el-icon-caret-right') {
row.icon = 'el-icon-more';
this.$set(this.tb.data,scope.$index,row)
this.audio.play();
}
},
},
最后这段代码就是播放的关键了。首先我会判断有没有audio,如果有暂停,然后把除了点击的数据,其他的标识变为待播放的标识。然后判断这条数据的标识,如果是带播放的就会下载数据,然后播放,绑定播放完毕的回调函数,改变为播放标识,然后调用$set方法去修改数据,因为数据是个数组,每条数据又是一个对象,我们直接修改一个对象的属性,vue并不会热更新。如果是正在播放,我们就暂停并修改图标。如果是暂停标识,我们就播放,修改图标。
上面这些都不是很难,就是在不同状态不同数据要对应上向匹配的图标会困难一些
网友评论