平板生成的音频为amr格式,audio标签无法播放,最近项目上就遇到了这种情况,环境为React.js语言的UMI框架,分页列表可播放多个amr文件,网上找了一个叫benz-amr-recorder的插件,api写的详细,但是没有这种情况的实例,自己摸索着,最后搞定,自己写的样式。才疏学浅,各路高人多指教。
1.benz-amr-recorder安装到项目里
npm install benz-amr-recorder
2.引入benz-amr-recorder插件,初始化数据
import React,{useState,useEffect} from 'react';
import BenzAmrRecorder from 'benz-amr-recorder';
interface mediaprops{
children?:any,
list:never[],
dataindex:number,
customstyle?:boolean
}
const Index = (props:mediaprops)=>{
const {list,dataindex,customstyle=false} = props;//从父组件获取列表及当前项的位置和自定义样式
const [detail,setDetail] = useState({...list[dataindex],amr:new BenzAmrRecorder(),intervalTime:undefined})//初始化当前项的信息,包括独有的amr音频管理对象和控制播放时间的变量
const [amrAdoDuration,setAmrAdoDuration] = useState(0);//记录音频的长度
const [amrAdoCurPos,setAmrAdoCurPos] = useState(0);//记录音频播放的位置
const [playStat,setPlayStat] = useState(false);//记录音频是否播放
3.初始化benz-amr-recorder插件
useEffect(()=>{
//读出并展示音频的播放时长
detail['amr'].initWithUrl(detail.url).then(()=>{
setAmrAdoDuration(Math.round(detail['amr'].getDuration()));
})
})
4.监听当前子项是否在播放音频
useEffect(()=>{
if(detail['amr'].isPlaying()){//是的话,给当前子项设置一个定时器,每一秒更新一下播放到哪儿了
detail['intervalTime'] = setInterval(()=>{
setAmrAdoCurPos(Math.round(detail['amr'].getCurrentPosition()));
},1000);
} else{//否,清除当前子项的定时器
if(detail['intervalTime']) clearInterval(detail['intervalTime'])
}
},[detail['amr'].isPlaying()]);
5.处理点击播放和暂停
return (
<li className={customstyle}>
{props.children}
{
detail['mediatype']==='audio'?//是否为音频
<div className={styles.audioicon}>
{
detail.mediaSuffix.indexOf('amr')>-1?//是否媒体标题后缀为amr
<>
//下面就是amr播放器,用了一下antd的Process组件
<Process
percent={amrAdoCurPos===0?0:Math.round((amrAdoCurPos/amrAdoDuration)*100)}
format={percent=>percent?formatTime(Math.round(percent/100*amrAdoDuration))+'/'+formatTime(amrAdoDuration):'00:00/00:00'}
style={{fontSize:16}}
/>
<div style={{alignSelf:'flex-start'}} onClick={()=>{
setPlayStat(!playStat);//设置播放暂停的状态
detail.amr.playOrPauseOrResume();//播放或者暂停时,再被点了一次,暂停或者播放或者从头开始播放
detail.amr.onEnded(()=>{
//结束的时候,播放完了要把状态都重新初始化
setAmrAdoCurPos(Math.round(detail['amr'].getDuration()));
setPlayStat(false);
//清理定时器
if(detail['intervalTime']) clearInterval(detail['intervalTime'])
})
}}>
//自己封装的组件,其实就是antd中CaretRightOutlined,PauseOutlined俩图标根据状态playStat展示
<IconPreview
imgurl={!playStat?'CaretRightOutlined':'PauseOutlined'}
imgstyle={{width:'auto',height:'auto',border:'1px solid #d9d9d9',padding:'4px 3px 2px 5px',borderRadius:4,cursot:'pointer',marginTop:8}}
/>
</div>
</>:<Audio src={detail.url} controls={true} controlsList="nodownload" autoPlay="true"/>
}
</div>:null
}
</li>
)
6.最后贴一下时间格式处理函数和样式
const formatTime=(param:any)=>{
if(param<60){//一分以内
if(param<10){
return '00:0'+param;
}else{
return '00:'+param;
}
}else if (param>=60&¶m<3600){//一分到十分之间
let cop_sStr = param%60;
let sStr = cop_sStr+'';
if(cop_sStr<10){
sStr = '0'+cop_sStr;
}
if(param<600){//十分以内
return '0'+parseInt((param/60)+'')+':'+sStr;
}else{
return parseInt((param/60)+'')+':'+sStr;
}
}else{
let cop_sStr = param%60;
let sStr = cop_sStr+'';
if(cop_sStr<10){
sStr = '0'+cop_sStr;
}
let cop_mStr = param/60%60;
let mStr = cop_mStr+'';
if(cop_mStr<10){//1分到10分
mStr = '0'+cop_mStr;
}
if(param<36000&¶m>=3600){
return '0'+parseInt((param/3600)+'')+':'+mStr+':'+sStr;
}else{
return parseInt((param/3600)+'')+':'+mStr+':'+sStr;
}
}
}
.audioicon{
border:1px solid red;
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
padding:0 65px 0 16px;
}