在做vue2.0钉钉微应用项目,有需要播放音频的是需求,用阿里云sdk播放器不购买相关服务,音频有些播放不了。于是我就直接用HTML5原生的Audio标签自己写音频播放器。(业务需求:记录上次播放位置并从上次播放位置播放,观看进度不满100%不允许快进,满100%方可快进。)以下是整个业务代码:

CSS部分:

.audio-box{
   height:100%;
   width:100%;
   background:rgba(16,32,56,.9);
   position:relative;
   z-index:3000;
   .audio-name{
        width:100%;
        font-size:.14rem;
        color:#eee;
        position:absolute;
        left:0;           
        top: .30rem;
        text-align:center;
        @include ellipsis();
   }
   .perisphere{
       width:3rem;
       height:3rem;
       background:rgba(255,255,255,.3);
       border-radius:100%;
       -moz-border-radius: 100%;
       -webkit-border-radius: 100%;
       position:absolute;
       left:0;
       bottom:0;
       top:0;
       right:0;
       margin:auto;
       z-index:3005;
        @include flexbox();
        @include flex-direction(row);
        @include justify-content(center);
        @include align-items(center);
     .audio-show-img-box{
       width:2.5rem;
       height:2.5rem;
       border-radius:100%;
       -moz-border-radius: 100%;
       -webkit-border-radius: 100%;
        @include flexbox();
        @include flex-direction(row);
        @include justify-content(center);
        @include align-items(center);        
       #audio-show-img{
           width:100%;
           height:100%;
           border-radius:100%;
           -moz-border-radius: 100%;
           -webkit-border-radius: 100%;
        }
       
        
    .audio-play-show {
        -webkit-animation: say 12s linear infinite;
        -moz-animation: say 12s linear infinite;
        -ms-animation: say 12s linear infinite;
        -o-animation: say 12s linear infinite;
        animation: say 12s linear infinite;
    }
    
    .audio-pause-show {
        -webkit-animation: stopSay 2s linear infinite;
        -moz-animation: stopSay 2s linear infinite;
        -ms-animation: stopSay 2s linear infinite;
        -o-animation: stopSay 2s linear infinite;
        animation: stopSay 2s linear infinite;
    }
    
    @-webkit-keyframes say {
        0% {}
        100% {
            -webkit-transform: rotateZ(360deg);
        }
    }
    
    @-moz-keyframes say {
        0% {}
        100% {
            -moz-transform: rotateZ(360deg);
        }
    }
    
    @-ms-keyframes say {
        0% {}
        100% {
            -ms-transform: rotateZ(360deg);
        }
    }
    
    @-o-transforms say {
        0% {}
        100% {
            -o-transform: rotateZ(360deg);
        }
    }
    
    @keyframes say {
        0% {}
        100% {
            transform: rotateZ(360deg);
        }
    }
    
    @-webkit-keyframes stopSay {
        0% {}
        100% {
            -webkit-transform: rotateZ(0);
        }
    }
    
    @-moz-keyframes stopSay {
        0% {}
        100% {
            -moz-transform: rotateZ(0);
        }
    }
    
    @-ms-keyframes stopSay {
        0% {}
        100% {
            -ms-transform: rotateZ(0);
        }
    }
    
    @-o-transforms stopSay {
        0% {}
        100% {
            -o-transform: rotateZ(0);
        }
    }
    
    @keyframes stopSay {
        0% {}
        100% {
            transform: rotateZ(0);
        }
    }

       
     }
 
   .audio-play-img-box{
       width:2.5rem;
       height:2.5rem;
       border-radius:100%;
       -moz-border-radius: 100%;
       -webkit-border-radius: 100%;      
       position:absolute;
       left:0;
       bottom:0;
       top:0;
       right:0;
       margin:auto;
       z-index:4100;
        @include flexbox();
        @include flex-direction(row);
        @include justify-content(center);
        @include align-items(center);
        display:none;
        .show-play-img{
               height:1rem;
               width:1rem;
               margin:.75rem 0 0 .75rem;
               cursor:pointer;
               
              
       }    
   }
}
   .load-title{
            width:100%;
            font-size:.12rem;
            color:#eee;
            position:absolute;
            left:0;           
            bottom: .54rem;
            text-align:center;
            @include ellipsis();
       }
   .audio-control{
       width:100%;
       height:.44rem;
       background:rgba(0,0,0,.6);
       position:absolute;
       left:0;
       bottom:0;
       z-index:3100;
        @include flexbox();
        @include flex-direction(row);
         @include justify-content(space-around);
        @include align-items(center);
        
       .audio-play-control{
           height:.26rem;
           width:.22rem;
           background:url('../../static/icon-audio-pause.png') no-repeat center center;
           background-size:100% 100%;
           margin-left:.12rem;
           cursor:pointer;
       }
       .size{
             font-size:.12rem;
             color:#fff;
             float: left;
             display: block;
         }
         .timeshow{
             font-size:.12rem;
             color:#fff;
             float: right;
            display: block;
         }
       .right-timeUpdata{
            height:100%;       
            width:2rem;
            @include flexbox();
            @include flex-direction(row);
            @include align-items(center);
           .timeline{               
                height: .04rem;
                width:100%;
                background-color: rgba(256, 256, 256, 0.6);
                border-radius: 5px;
                position: relative;
                z-index: 3100;                
                span{
                    position: relative;
                    width: 0px;
                    height: .04rem;            
                    background: #0188fd;
                    box-shadow: inset 1px 1px 1px 0 rgba(0,0,0,.06);
                    border-radius: .10rem;
                    -moz-border-radius: .10rem;
                    -webkit-border-radius: .10rem;
                    display: block;
                    -webkit-transition: width ease-out 0.3s;
                    -o-transition: width ease-out 0.3s;
                    transition: width ease-out 0.3s;
                }
                span:after{
                    content: "";
                    position: absolute;
                    top: -.05rem;
                    right: 0;
                     width: .12rem;
                     height: .12rem;
                    border-radius: 100%;
                    -moz-border-radius: 100%;
                    -webkit-border-radius: 100%;
                     background: #0188fd;
                }
           }

       }
   }
}

 

HTMl部分:

 

<template>
	<div class="audio-box">
		<audio id="audio" preload="auto"></audio>
		<p class="audio-name"></p>
		<div class="perisphere">
			<div class="audio-show-img-box">
				<img class="images" id="audio-show-img" src="../../../static/icon-audio-show.png" />
			</div>
			<div class="audio-play-img-box" id="audio-play-img-box">
				<img id="show-play-img" class="show-play-img images" src="../../../static/icon-audio-bag-play.png" />
			</div>
		</div>
		<p class="load-title" id="load-title">正在缓冲…</p>
		<div class="audio-control">
			<div class="audio-play-control" id="audio-play-control"></div>
			<span class="size" id="size">00:00</span>
			<div class="right-timeUpdata">
				<p class="timeline" id="timeline"><span id="progress"></span></p>
			</div>
			<span class="timeshow" id="timeshow">00:00</span>
		</div>
	</div>
</template>

js部分:

<script type="text/javascript">
	import axios from 'axios';
	import router from '../../router';
	import { Toast } from 'mint-ui';
	import { global_set } from '../../script/global.js';
	export default {
		data() {
			return {
				planId: this.$route.query.planId, //学习计划id
				courseId: this.$route.query.courseId, //课程id
				token: this.$route.query.access_token,
				resourceId: this.$route.query.resourceId,
				playContent: '',

			}
		},
		created() {

		},
		mounted() {
			axios.get(global_set.host + "/plan/myTask/getSingleResourceProgress", {
					params: {
						access_token: this.token,
						courseId: this.courseId,
						planId: this.planId,
						resourceId: this.resourceId, //加资源id
						timeStamp: Date.parse(new Date()),
					}
				})
				.then((data) => {
					this.playContent = data.data.data;
					var that = this;
					//音频标题设置
					$('.audio-name').html(that.playContent.name)
					/*********************mp3************************/
					that.$nextTick(function() {
					     var onoff = false,
							 audio = document.getElementById('audio'),
							 isPalyControl = document.getElementById('audio-play-control'),
							 showPalyImgBox = document.getElementById('audio-play-img-box'),
							 showPalyImg = document.getElementById('show-play-img'),
							 audioShowImg = document.getElementById('audio-show-img'),
							 timeline = document.getElementById('timeline'),

							 progress=document.getElementById('progress'), //进度条
							 timeshow=document.getElementById('timeshow'), //总时间
							 size=document.getElementById('size'), //时时显示时间
							 loadTitle=document.getElementById('load-title');  //缓冲显示

						//是否允许快进
						var progressBtn = that.playContent.studyProgress;
						//上次播放位置记录
						var recentStart = that.playContent.recentStart;
						audio.src = that.playContent.url;
						audioPlay();
						var button=true;
						audio.addEventListener("canplay",function() {							
							//设置初始播放位置						
							var	 seekable = this.seekable && this.seekable.length > 0;											  	
								if(seekable && button){
									var that=this;		
									  setTimeout(function(){
											 that.currentTime = recentStart;
											 button=false;
										},500)
									 
									 
								}							
							
						});
						//绑定timeupdate事件
						audio.addEventListener('timeupdate', function() {
							//获取当前的播放时刻(单位秒)
							var currentTimes = audio.currentTime; 
							if(!isNaN(audio.duration)) {
								 //播放时间显示
								setTimeShow();
								//用时间比来获取进度条的值
								var progressValue = audio.currentTime / audio.duration;
								if(progressValue == 1) {
									//当前播放完成停止播放
									audioPause();
									onoff = true;
									//播放完进度保存
									var durations = audio.duration; //获取获取视频总时长(单位秒)
									var percents = Math.round(currentTimes * 100 / durations); //四舍五入进度
									var tempTimeEnd = parseInt(currentTimes, 10); //当前播放时刻转换
									//intervalFun(percents, tempTimeEnd);
									

								}

							};
						}, false);
						audio.addEventListener("pause",
							function() { //音频监听暂停时保存当前进度
								var currentTime = audio.currentTime; //获取当前的播放时刻(单位秒)
								var duration = audio.duration; //获取获取视频总时长(单位秒)
								var percent = Math.round(currentTime * 100 / duration); //四舍五入进度
								var tempTimes = parseInt(currentTime, 10); //当前播放时刻转换
								intervalFun(percent, tempTimes); //调取延时请求函数saveTask
							}, false);
						// 进度条控制
						timeline.addEventListener('touchend', function(e) {							
							var x = e.changedTouches[0].clientX - this.offsetLeft;          
							var X = x < 0 ? 0 : x;          
							var W =this.offsetWidth;          
							var place = X > W ? W : X; 
							//是否允许用户快进
							if(progressBtn >= 100) {
								audio.currentTime = (place / W).toFixed(2) * audio.duration    
								progress.style.width=(place / W).toFixed(2) * 100 + "%";    
								
							}           

						});
						// 设置播放时间
						function setTimeShow() {                    
							var playTime = secondToMin(audio.currentTime); 
							var duration = audio.duration === Infinity ? null : audio.duration;
							var durations=secondToMin(duration);
							loadTitle.style.display='none';
							size.innerHTML=playTime; 
							timeshow.innerHTML=durations;
							progress.style.width=( audio.currentTime / duration).toFixed(4) * 100 + "%"             
							       
						}       
						// 计算时间        
						function secondToMin(s) {          
							var MM = Math.floor(s / 60);          
							var SS = s % 60;          
							if(MM < 10) {
								MM = "0" + MM;  
							}                    
							if(SS < 10) {
								SS = "0" + SS; 
							}                    
							var min = MM + ":" + SS;        
							return min.split('.')[0];          
						}

						isPalyControl.onclick = function() {
							palyControl();
							onoff = !onoff;

						}
						showPalyImg.onclick = function() {
							palyControl();
							onoff = !onoff;

						}
						//播放暂停切换
						function palyControl() {
							if(onoff) {
								audioPlay();
							} else {
								audioPause();
							}
						}
						//播放
						function audioPlay() {
							audio.play();
							//console.log(audio.networkState) //0.此元素未初始化 1.正常但没有使用网络 2.正在下载数据 3.没有找到资源
							if(audio.error != null) {
								console.log(audio.error.code) //1.用户终止 2.网络错误 3.解码错误 4.URL无效
							}
							isPalyControl.style.height = 0.26 + 'rem';
							isPalyControl.style.background = 'url("../../../static/icon-audio-pause.png") no-repeat center center';
							isPalyControl.style.backgroundSize = '100% 100%';
							showPalyImgBox.style.display = 'none';
							//播放动效
							audioShowImg.style.animation = 'say 12s linear infinite';
							audioShowImg.style.WebkitAnimation = 'say 12s linear infinite';
							audioShowImg.style.MozAnimation = 'say 12s linear infinite';
							audioShowImg.style.MsAnimation = 'say 12s linear infinite';
							audioShowImg.style.OAnimation = 'say 12s linear infinite';

							// $('#audio-show-img').css({"-webkit-animation":"say 12s linear infinite","-moz-animation":"say 12s linear infinite","-ms-animation":"say 12s linear infinite","animation":"say 12s linear infinite"});

						};
						//暂停
						function audioPause() {
							audio.pause();
							isPalyControl.style.height = 0.22 + 'rem';
							isPalyControl.style.background = 'url("../../../static/icon-audio-play.png") no-repeat center center';
							isPalyControl.style.backgroundSize = '100% 100%';
							showPalyImgBox.style.display = 'block';
							//关闭播放动效
							audioShowImg.style.animation = 'stopSay 2s linear infinite';
							audioShowImg.style.WebkitAnimation = 'stopSay 2s linear infinite';
							audioShowImg.style.MozAnimation = 'stopSay 2s linear infinite';
							audioShowImg.style.MsAnimation = 'stopSay 2s linear infinite';
							audioShowImg.style.OAnimation = 'stopSay 2s linear infinite';

							// $('#audio-show-img').css({"-webkit-animation":"stopSay 2s linear infinite","-moz-animation":"stopSay 2s linear infinite","-ms-animation":"stopSay 2s linear infinite","animation":"stopSay 2s linear"});
						};
						//保存audio进度
						function intervalFun(progre, times) {
							axios.post(global_set.host + "/plan/myTask/saveTask", $.param({
									access_token: that.token,
									planId: that.planId,
									courseId: that.courseId,
									resourceId: that.resourceId,
									courseType: 2,
									progress: progre,
									tempTime: times,
									timeStamp: Date.parse(new Date()),
								}))
								.then((data) => {

								})
								.catch(function(err) {

								})
						};
					})
				})
				.catch(function(err) {
					//console.log(err);
				})

		},

	}
</script>

 

效果如下:

Logo

前往低代码交流专区

更多推荐