项目总结(关于audio音频标签的使用和在angular4.0中使用过程中的一些坑)

马上又到月底了,又一波新的需求又要来临了。所以趁此空隙把之前这一个月的心得和遇到的问题写一下
因为项目中有一个资讯转语音的功能,也就是把一篇文章转化为语音播放。至于怎么转化,这个是由后台这边转化好之后,发送了一个url音频地址给前端,由前端直接加载到audio标签的src属性上。
audio标签的使用这个可以直接参考w3c的文档
例如:

<audio src="/i/horse.ogg" controls="controls">
Your browser does not support the audio element.
</audio>

其中有很多属性,这个也是参考w3c的文档。
首先我先说一下我遇到的一些问题,我在angular中用document.getElementById("audio") 获取不到这个对象,然后我就发现原来是获取的时候audio这个元素还没有加载进来,因为这个项目是由angular4.0+ionic3.0开发的,所以我就使用了ionic3.0的生命周期钩子ionViewDidEnter(每次进入页面的时候调用,这个时候页面已经加载好了,已经进入页面了),在这个时候我获取到了audio元素,但是我获取到后打印出来是这样一段代码

<audio id="audio">
   <source src="asset/a.mp3" type="audio/mp3">
<audio>   

获取的不是一个对象,而是一段代码,当我用typeof 验证数据类型的时候输出的是object。经过查找搜索才发现自己把一些基础都遗忘了,doucument.getElementById获取的是一个dom对象,但是它是一段dom元素,这段dom元素具有一些对象的属性,这个我以后还需要再去看一下基础知识。
获取到audio对象之后呢发现,这个时候它没有duration(播放总长)和currentTime(当前播放的时间)这个两个属性。audio对象有很多属性,这个具体参考下面:
*****Audio 对象属性
属性 描述
audioTracks 返回表示可用音频轨道的 AudioTrackList 对象。
autoplay 设置或返回是否在就绪(加载完成)后随即播放音频。
buffered 返回表示音频已缓冲部分的 TimeRanges 对象。
controller 返回表示音频当前媒体控制器的 MediaController 对象。
controls 设置或返回音频是否应该显示控件(比如播放/暂停等)。
crossOrigin 设置或返回音频的 CORS 设置。
currentSrc 返回当前音频的 URL。
currentTime 设置或返回音频中的当前播放位置(以秒计)。
defaultMuted 设置或返回音频默认是否静音。
defaultPlaybackRate 设置或返回音频的默认播放速度。
duration 返回音频的长度(以秒计)。
ended 返回音频的播放是否已结束。
error 返回表示音频错误状态的 MediaError 对象。
loop 设置或返回音频是否应在结束时再次播放。
mediaGroup 设置或返回音频所属媒介组合的名称。
muted 设置或返回是否关闭声音。
networkState 返回音频的当前网络状态。
paused 设置或返回音频是否暂停。
playbackRate 设置或返回音频播放的速度。
played 返回表示音频已播放部分的 TimeRanges 对象。
preload 设置或返回音频的 preload 属性的值。
readyState 返回音频当前的就绪状态。
seekable 返回表示音频可寻址部分的 TimeRanges 对象。
seeking 返回用户当前是否正在音频中进行查找。
src 设置或返回音频的 src 属性的值。
textTracks 返回表示可用文本轨道的 TextTrackList 对象。
volume 设置或返回音频的音量。
Audio 对象方法
方法 描述
addTextTrack() 向音频添加新的文本轨道。
canPlayType() 检查浏览器是否能够播放指定的音频类型。
fastSeek() 在音频播放器中指定播放时间。
getStartDate() 返回新的 Date 对象,表示当前时间线偏移量。
load() 重新加载音频元素。
play() 开始播放音频。
pause() 暂停当前播放的音频。*

这个时候我查找之后我才发现audio元素虽然加载好了,但是audio的资源还没有加载好,也就是这个src属性值还没有加载好,所以这时候这段音频的总时长和当前播放时间肯定是不知道的,这个时候呢,我给它增加了一个监听事件:

let that = this;
this.audio.addEventListenter("canplay",function(e){
  that.currentTime = that.toTime(this.currentTime);
  that.duration = that.toTime(this.duration);
});

这段代码也是放在ionViewDidEnter生命周期钩子中的,所以这个时候定义个
let that = this;这里写代码片

ionViewDidEnter(){
  let that = this;
  this.audio.addEventListenter("canplay",function(e){
  that.currentTime = that.toTime(this.currentTime);
  that.duration = that.toTime(this.duration);
});
  this.currentTime = this.toTime(this.audio.currentTime);
  this.duration = this.toTime(this.audio.duration);
}

这里的that和this来回切换主要是this代表的值不一样,也就是运行的环境不一样。
之所以监听事件之后又加了两行代码是因为,在第一次进入这个页面时会执行监听,之后因为有缓存,就不会走监听事件了,这时候播放时长和当前播放时间就获取不到了,所以要加一下这两行代码。
然后就要给播放按钮加上点击事件按钮,也就是播放与暂停来回切换

audioPlay(){
  this.isPlay = !this.isPlay; // 控制是播放还是暂停
  let that = thisif(this.isPlay){
    this.audio.play();//播放
    let progressBar = this.progressBar;
    this.interval = setInterval(function(){//设置一个定时器主要是为了播放条滑动
        that.currentTime = that.toTime(that.audio.currentTime);
        //下面是播放条主要的
        let widthLine = Math.round(that.audio.currentTime) / Math.round(that.audio.duration) * 100 + 4;
        progressBar.style.width = widthLine + "%";
        //如果当前播放的时间和总共的播放时长相等的话就停止播放,显示暂停按钮
        if(that.toTime(that.audio.currentTime) == that.toTime(that.audio.duration)){
        that.isPlay = false;
        //  清除定时器
        clearInterval(that.interval);
        }
    },1000);
  }else{
     this.audio.pause();//暂停
     clearInterval(this.interval);//清除定时器
  }
}

// 时间转化为分秒
toTime(s) {
        let t;
        if(s > -1){
           //  var hour = Math.floor(s/3600);
            var min = Math.floor(s/60) % 60;
            var sec = s % 60;
           // if(hour < 10) {
               // t = '0'+ hour + ":";
           // } else {
               // t = hour + ":";
           //  }

            if(min < 10)
            {t = "0";}
            else{
            t="";
            }
            t += min + ":";
            if(sec < 10){t += "0";}
            t += sec.toFixed(2);
        }
        return t;
    }
    // 秒转化为00:00这样的格式的

以上为js,下面为html代码布局
语音展示

<p>
  <audio>
   <source [src]="voiceUrl" type="audio/mp3"/>
  </audio>
  <span class="audio_play_area" tapple (click)="audioPlay()">
       <i>
         <img *ngIf="!isPlay" src="assets/images/video/shengyin.png"/>
         <img *ngIf="isPlay" src="assets/images/video/shengyin.gif"/>
    </i>
  </span>
  <span class="audio_length">{{duration}}</span>
  <span class="current_time">{{currentTime}}</span>
  <span class="audio_info_area">资讯</span>
  <span class="progress_bar_box">
        <span class="progress_bar"><img class="progress_slider" src="assets/images/video/slider.png"/></span>
  </span>
</p>
// 主要是看这个布局

css样式如下

//语音样式
.bullet_audio{
width:100%;
height:80px;
margin-top:12px;
border: 1px solid #ddd;
background-color: #f4f5f7;
position: relative;
.audio_play_area{
position:absolute;
left:20px;
top: 40px;
transform: translateY(-50%);
i{
display:block;
img{
width: 34px;
height:34px;
}
}
}
.audio_length{
font-size:13px;
position:absolute;
bottom:15px;
right: 20px;
color:#999;
}
.current_time{
font-size:13px;
position:absolute;
bottom:15px;
left: 22%;
color:#999;
}
.audio_info_area{
font-size:13px;
color:#333;
overflow:hidden;
display:block;
width:60%;
text-overflow:ellipsis;
white-space: nowrap;
word-wrap:normal;
position:absolute;
top:15px;
left:22%;
}
.progress_bar_box{
width:72%;
display:block;
position:absolute;
bottom:36px;
right:20px;
background-color:#c3c3c3;
height:3px;
cursor: pointer;
.progress_bar{
background-color:#ff6000;
height:3px;
display:block;
position:relative;
width:4%;
}
.progress_slider{
width:10px;
height;10px;
position:absolute;
right:0;
top:50%;
transform: translateY(-50%);
}
}
}

最后的效果图如下:
![这里写图片描述]

猜你喜欢

转载自blog.csdn.net/xiaolinlife/article/details/80818461