1 标签定义声音,比如音乐或其他音频流。
2 设置为自动播放的 audio 元素:autoplay=“autoplay”
但是只有pc端可以实现 移动端不行(pc端的浏览器要比移动端的完善很多,对有些属性支持也会好很多)
3 audio不单单是个标签 他也是window下的一个对象,对象就有属性和方法,作为对象他有哪些常用的方法呢
对象属性:
currentTime 获取当前播放时间
duration 获取歌曲的总时间
play 是否在播放 返回true/false
pause 是否暂停 返回true/false
对象方法:
play() 播放歌曲
pause() 暂停歌曲
load()重新加载歌曲
4 onloadedmetadata
事件在指定视频/音频(audio/video)的元数据加载后触发。
视频/音频(audio/video)的元数据包含: 时长,尺寸大小(视频),文本轨道。
视频/音频(audio/video)在加载过程中,触发的顺序如下:
onloadstart
ondurationchange
onloadedmetadata
onloadeddata
onprogress
oncanplay
oncanplaythrough
https://www.cnblogs.com/leinov/p/3896772.html
例子:用Vue写出如下样式
解析:
1 先写出HTML样式
<!-- 时间轴 -->
<div id="musicSlider">
<div style="width: 15%; float: left;">
<label v-text="$options.filters.formatSecond(audio.currentTime)"></label>
</div>
<div style="width: 70%; float: left;">
<input type="range" style="padding: 0; margin: 0;width: 100%;"
v-model="sliderTime" min="0" max="100" @change="changeCurrentTime">
</div>
<div style="width: 15%; float: left;">
<label v-text="$options.filters.formatSecond(audio.maxTime)"></label>
</div>
</div>
<!-- 歌曲信息 -->
<div id="audioInfo">
<audio id="audio-1" :src="song.musicUrlAudio" ref="audio" autoplay="autoplay" onended="nextMusic()"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata" >
</audio>
</div>
左右两边的时间怎么获得呢?
v-text不解释标签,也就是直接输出获取的数据,v-text使用过滤器,通过$options.filters进行使用
v-text如何使用filters:https://jingyan.baidu.com/article/e52e36151dae2040c60c51f0.html
filters: {
formatSecond(second = 0) {
return realFormatSecond(second);
}
}
// 将整数转换成 时:分:秒的格式
function realFormatSecond(second) {
var secondType = typeof second
if (secondType === 'number' || secondType === 'string') {
second = parseInt(second)
var mimute = Math.floor(second / 60)
second = second - mimute * 60
return ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
} else {
return '00:00'
}
}
Vue的method方法里面
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
onTimeupdate(res) {
this.audio.currentTime = res.target.currentTime;
this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100);
},
onLoadedmetadata(res) {
console.log(this)
console.log(res)
this.audio.maxTime = parseInt(res.target.duration);
},
changeCurrentTime() {
this.$refs.audio.currentTime = parseInt(this.sliderTime / 100 * this.audio.maxTime)
},
打印出的this
audio.currentTime=> 打印 res.target.duration通过parseInt转化为整数就是整首歌的时长
那,最左边的那个时间怎么变化,那个滑竿怎么跟着变呢?
过滤器里面返回了这个函数:realFormatSecond
解决进度条:
http://www.cnblogs.com/lalalagq/p/9961959.html
https://blog.csdn.net/fgdfgasd/article/details/82152482?utm_source=blogxgwz5
源码:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="shortcut icon" href="images/fa.ico">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<style type="text/css">
.mui-bar {
background-color: white;
}
body {
background-color: white;
color: black;
}
#musicPlayBtns {
position: fixed;
bottom: 5%;
width: 100%;
}
#musicSlider {
position: fixed;
bottom: 15%;
width: 100%;
}
@media screen and (orientation: portrait) {
#baseIndo {
position: fixed;
width: 100%;
top: 5%;
}
#musicImage {
position: fixed;
width: 100%;
top: 20%;
/* bottom: 45%; */
}
}
@media screen and (orientation: landscape) {
#baseIndo {
width: 50%;
float: right;
top: 1%;
}
#musicImage {
width: 50%;
float: left;
/* top: 1%; */
}
}
.mui-bar {
height: 58px;
}
.mui-title {
font-weight: 700;
}
.sub-title {
font-size: 12px;
font-weight: 400;
line-height: 82px;
position: absolute;
display: block;
width: 100%;
margin: 0 -10px;
padding: 0;
text-align: center;
white-space: nowrap;
color: #000;
}
/* 控制进度条 */
.slider {
/* margin-top:100px; */
width: 100%;
position: relative;
height: 24px;
margin-bottom: 16px;
display: flex;
align-items: center;
cursor: default;
user-select: none;
outline: none;
}
.slider-track {
position: absolute;
height: 2px;
left: 0;
right: 0;
top: 50%;
margin-top: -1px;
background-color: #bec2c1;
}
.slider-fill {
position: absolute;
height: 2px;
width: 100%;
background-color: #888;
left: 0;
top: 50%;
margin-top: -1px;
}
.slider-thumb {
position: absolute;
top: 50%;
width: 12px;
height: 12px;
background-color: #888;
color: #888;
border-radius: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
}
</style>
</head>
<body>
<!-- https://github.com/wangduanduan/element-audio -->
<div id="app">
<div style="margin-top:60px;">
<div style="text-align: center;">
<!-- 显示 -->
<div id="musicImage">
<img width="65%" height="auto" style="border-radius:50%;" src="music.jpg" alt="" />
</div>
<!-- 时间轴 -->
<div id="musicSlider">
<div style="width: 15%; float: left;">
<label v-text="$options.filters.formatSecond(audio.currentTime)"></label>
</div>
<div style="width: 70%; float: left;">
<input type="range" style="padding: 0; margin: 0;width: 100%;"
v-model="sliderTime" min="0" max="100" @change="changeCurrentTime">
</div>
<div style="width: 15%; float: left;">
<label v-text="$options.filters.formatSecond(audio.maxTime)"></label>
</div>
</div>
<!-- 按钮 -->
<div id="musicPlayBtns">
<div style="width: 45%; float: left;">
<img width="30px;" height="auto" id="preBtn" src="images/pre1.png" alt="" @click="preMusic" />
</div>
<div style="width: 10%; float: left;">
<img width="30px;" height="auto" id="playBtn" :src="audio.playing ? 'images/play1.png' : 'images/pause1.png'" alt="" @click="startPlayOrPause" />
</div>
<div style="width: 45%; float: left;">
<img width="30px;" height="auto" id="nextBtn" src="images/next1.png" alt="" @click="nextMusic" />
</div>
</div>
<!-- 歌曲信息 -->
<div id="audioInfo">
<!-- 此处的ref属性,可以很方便的在vue组件中通过 this.$refs.audio获取该dom元素 -->
<audio id="audio-1" ref="audio" autoplay="autoplay" controls src="http://192.168.188.1:8000/nwmsucms/music/musicfile_7295697c-04a0-47a3-8b74-b299192a86b6.mp3"
@pause="onPause"
@play="onPlay"
@timeupdate="onTimeupdate"
@loadedmetadata="onLoadedmetadata"
@ended="nextMusic">
</audio>
</div>
</div>
</div>
</div>
<script src="vue.min.js"></script>
<script src="jquery.min.js"></script>
<script type="text/javascript">
// 将整数转换成 时:分:秒的格式
function realFormatSecond(second) {
var secondType = typeof second
if (secondType === 'number' || secondType === 'string') {
second = parseInt(second)
var mimute = Math.floor(second / 60)
second = second - mimute * 60
return ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2)
} else {
return '00:00'
}
}
var app = new Vue({
el: '#app',
data: {
song: {},
audio: {
// 该字段是音频是否处于播放状态的属性
playing: false,
currentTime: 0,
maxTime: 0,
minTime:0,
step:0.1
},
sliderTime: 0,
},
created: function () {
//var songJson = sessionStorage.getItem('songJson');
// var chineseSongsJson = sessionStorage.getItem('chineseSongsJson');
// var englishSongsJson = sessionStorage.getItem('englishSongsJson');
// this.song = JSON.parse(songJson);
// console.log(this.song)
// this.chineseSongs = JSON.parse(chineseSongsJson);
// this.englishSongs = JSON.parse(englishSongsJson);
},
mounted: function () {
},
methods:{
// 控制音频的播放与暂停
startPlayOrPause() {
return this.audio.playing ? this.pause() : this.play();
},
play() {
this.$refs.audio.play();
},
pause() {
this.$refs.audio.pause();
},
// 当音频播放
onPlay() {
this.audio.playing = true;
},
// 当音频暂停
onPause() {
this.audio.playing = false;
},
/* 音频的时间显示主要有两部分,音频的总时长和当前播放时间。可以从两个事件中获取
loadedmetadata:代表音频的元数据已经被加载完成,可以从中获取音频总时长
timeupdate: 当前播放位置作为正常播放的一部分而改变,或者以特别有趣的方式,例如不连续地改变,可以从该事件中获取音频的当前播放时间,该事件在播放过程中会不断被触发 */
// 当timeupdate事件大概每秒一次,用来更新音频流的当前播放时间
onTimeupdate(res) {
this.audio.currentTime = res.target.currentTime;
this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100);
},
// 当加载语音流元数据完成后,会触发该事件的回调函数
// 语音元数据主要是语音的长度之类的数据
onLoadedmetadata(res) {
this.audio.maxTime = parseInt(res.target.duration);
},
// 拖动进度条,改变当前时间,index是进度条改变时的回调函数的参数0-100之间,需要换算成实际时间
changeCurrentTime() {
this.$refs.audio.currentTime = parseInt(this.sliderTime / 100 * this.audio.maxTime)
},
// 进度条格式化toolTip
/* formatProcessToolTip(index = 0) {
index = parseInt(this.audio.maxTime / 100 * index)
return '进度条: ' + realFormatSecond(index)
}, */
handleTouchStart(e) {
this.setValue(e.touches[0]);
document.addEventListener('touchmove', this.handleTouchMove);
document.addEventListener('touchup', this.handleTouchEnd);
document.addEventListener('touchend', this.handleTouchEnd);
document.addEventListener('touchcancel', this.handleTouchEnd);
// e.preventDefault();
// this.onDragStart(e);
},
handleTouchMove(e) {
// console.log(e.changedTouches[0])
this.setValue(e.changedTouches[0]);
},
handleTouchEnd(e) {
this.setValue(e.changedTouches[0]);
document.removeEventListener('touchmove', this.handleTouchMove);
document.removeEventListener('touchup', this.handleTouchEnd);
document.removeEventListener('touchend', this.handleTouchEnd);
document.removeEventListener('touchcancel', this.handleTouchEnd);
// this.onDragStop(e);
},
// 从点击位置更新 value
setValue(e) {
const $el = this.$el;
const {
maxTime,
minTime,
step
} = this.audio;
let value = (e.clientX - $el.getBoundingClientRect().left) / $el.offsetWidth * (maxTime - minTime);
value = Math.round(value / step) * step + minTime;
value = parseFloat(value.toFixed(5));
if (value > maxTime) {
value = maxTime;
} else if (value < minTime) {
value = minTime;
}
this.$refs.audio.currentTime = value;
},
preMusic() {
this.audio.playing = false;
var songIndex = this.chineseSongs.findIndex(x => x.id == this.song.id);
var preIndex = 0;
if(songIndex !== -1) {
preIndex = (songIndex - 1) < 0 ? (this.chineseSongs.length - 1) : (songIndex - 1);
this.song = this.chineseSongs[preIndex];
} else {
songIndex = this.englishSongs.findIndex(x => x.id == this.song.id)
preIndex = (songIndex - 1) < 0 ? (this.englishSongs.length - 1) : (songIndex - 1);
this.song = this.englishSongs[preIndex];
}
// this.readLyric();
},
nextMusic() {
this.audio.playing = false;
var songIndex = this.chineseSongs.findIndex(x => x.id == this.song.id);
var nextIndex = 0;
if(songIndex !== -1) {
nextIndex = (songIndex + 1) >= this.chineseSongs.length ? 0 : (songIndex + 1);
this.song = this.chineseSongs[nextIndex];
} else {
songIndex = this.englishSongs.findIndex(x => x.id == this.song.id)
nextIndex = (songIndex + 1) >= this.englishSongs.length ? 0 : (songIndex + 1);
this.song = this.englishSongs[nextIndex];
}
// this.readLyric();
},
},
filters: {
formatSecond(second = 0) {
return realFormatSecond(second);
}
}
})
</script>
</body>
</html>