标签
-
audio
video
source
视频容器
- 容器文件,类似于压缩了一组文件
--音频轨道
--视频轨道
--元数据:封面,标题,字幕等
--格式:.avi、.flv、.mp4、.mkv、.ogv等
媒体元素
-
controls
显示或隐藏用户控制界面
默认情况下这些控件是不显示的,所以需要设置controls来显示控件:
<audio controls src="a.mp4"></audio>
-
autoplay
媒体是否自动播放 -
loop
媒体是否循环播放 -
currentTime
从开始到播放现在所用的时间 -
duration
媒体总时间(只读) -
volume
0.0~1.0的音量相对值 -
muted
是否静音 -
autobuffer
开始的时候是否缓冲加载,autoplay的时候,忽略此属性
音频和视频
编解码器(浏览器中内嵌了一个叫做编解码器的东西)
- 原始的视频容器非常大,添加需编码,播放需解码
- 音频编解码器:
AAC
、MPEG-3
、OggVorbis
- 视频编解码器:
H.264
、VP8
、OggTheora
source的作用与用法:
<video controls>
<source src="aaa.ogv"></source>
<source src="aaa.mp4"></source>
</video>
上述代码中,先加载aaa.ogv格式的文件,如果浏览器不支持ogv格式,就加载后面的aaa.mp4,以此类推,所以source的作用不言而喻了吧。
currentTime
播放过程中可以实时
获取当前播放了多长时间
<audio :src="w" id="a1" controls autoplay></audio>
var oA = document.getElementById("a1")
setInterval(function () {
console.log(oA.currentTime)
}, 1000)
可以看到,浏览器也并不是隔整一秒执行的......
currentTime不仅可以读取,还可以设置(可读写)
eg:设置媒体元素从60秒处开始播放:
oA.currentTime = 60
duration
var oA = document.getElementById("a1")
console.log(oA.duration)
直接这么获取到audio元素然后打印其duration,结果很可能是NaN,可以理解为没来得及获取媒体元素加载的时长,如果这里给设置一个延迟再打印,是可以获取到duration的。
当歌曲准备到可以被播放时,才进行获取duration和buffered等相关数据获取操作。
媒体元素_2
-
paused
媒体是否暂停(只读
) -
ended
媒体是否播放完毕(只读
) -
error
媒体发生错误的时候,返回的错误代码(只读
) -
currentSrc
以字符串的形式返回媒体地址(只读
) -
play()
媒体播放 -
pause()
媒体暂停 -
load()
重新加载媒体
load()
比如在js中改变了媒体元素的src,这时是需要重新加载媒体元素:
<video controls>
<source src="aaa.ogv"></source>
</video>
......
as[0].src = "aaa.mp4"
oV.load()
媒体元素_3
事件:loadstart
progress
suspend
emptied
stalled
play
pause
loadedmetadata
loadeddata
waiting
playing
canplay
canplaythrough
seeking
seeked
timeupdate
ended
ratechange
durationchange
volumechange
<video controls id="ov">
<source :src="w"></source>
</video>
var oV = document.getElementById("ov")
oV.addEventListener("ended", function () {
console.log("播放结束")
}, false)
文件播放结束时,控制台打印“播放结束”。
video额外特性
-
poster
:视频播放前的预览图片
//某vue文件------------------------------------------------------
<video controls id="ov">
<source :src="w"></source>
</video>
......
import pic from "@/assets/logo.png"
data(){
return {
pic
}
}
......
mounted(){
var oV = document.getElementById("ov")
oV.poster = pic
}
这里我是在vue+webpack项目中进行的实践,在webpack中一切都是模块,所以在要正确加载出图片文件,html中是将图片解码成了base64,因此这里使用模块的思想把图片引入然后赋值给video的poster。
在常规html中引入方式一般为:oV.poster="../assets/logo.png"
-
width
height
:设置视频的尺寸
<video controls id="ov" poster="../assets/logo.png">
<source :src="w"></source>
</video>
var oV = document.getElementById("ov")
oV.width = 800
oV.height = 700
-
videoWidth
videoHeight
:视频的实际尺寸(只读)
视频最原始的大小,不论被设置成多大尺寸,这个原始大小是不会变的
练习1:带声音的导航(部分代码)
<ul id="ul1">
<li au="a">1</li>
<li au="b">2</li>
<li au="c">3</li>
<li au="d">4</li>
<li au="e">5</li>
<li au="f">6</li>
<li au="g">7</li>
</ul>
<audio src="" id="a1"></audio>
var oUl = document.getElementById("ul1")
var aLi = oUl.getElementsByTagName("li")
var oA = document.getElementById("a1")
for(var i=0;i<aLi.length;i++){
aLi[i].onmouseover = function () {
console.log(this.getAttribute("au"))
oA.src = "http://yinjie/yuefu/"+this.getAttribute("au")+".mp3";
oA.play()
}
}
练习2:把视频以canvas方式输出(部分代码)
<video controls id="v1">
<source :src="aaa"></source>
</video>
<canvas id="c1"></canvas>
var oV = document.getElementById("v1")
var oC = document.getElementById("c1")
var oGc = oC.getContext("2d")
//canplay
//在媒体数据已经有足够的数据(至少播放数帧)可供播放时触发
//否则直接是获取不到videoWidth这种数据的
oV.addEventListener("canplay", function () {
oC.width = oV.videoWidth
oC.height = oV.videoHeight
console.log(oV.videoWidth, oV.videoHeight)
}, false)
setInterval(function () {
oGc.drawImage(oV, 0, 0)
//另外还可以进行其他像素级操作
}, 30)
练习3:自制播放器(部分代码)
功能:播放/暂停、播放时间实时显示、全屏、静音(每个功能基本上都是相对独立的,没有做互相影响的处理)
<video controls id="v1">
<source :src="aaa"></source>
</video>
<input type="button" value="播放"/>
<input type="text" value="00:00:00" readonly/> <!--实时播放时间显示-->
<input type="text" value="00:00:00" readonly/> <!--播放总时长-->
<input type="button" value="静音"/>
<input type="button" value="全屏"/>
var oV = document.getElementById("v1")
var oInput = document.getElementsByTagName("input")
var timer = null //计时器
var oDuration = null //媒体总时长
oV.addEventListener("canplay", function () {
oV.width = 250 //视频原始大小太大,设置宽高
oV.height = 500
oDuration = oV.duration
oInput[2].value = changeTime(oDuration) //设置总播放时长
//设置总播放时长要放在canplay里面,放在外面获取到的oDuration可能是空
}, false)
oInput[0].onclick = function () { //第一个按钮控制播放和暂停
if(oV.paused){
oV.play()
this.value = "暂停"
nowTime()
timer = setInterval(nowTime, 1000)
}
else {
oV.pause()
this.value = "播放"
clearInterval(timer)
}
}
function changeTime(iNum){ //总播放时长转换为时分秒
iNum = parseInt(iNum)
var iH = toZero(Math.floor(iNum/3600)); //时
var iM = toZero(Math.floor(iNum%3600/60));
var iS = toZero(Math.floor(iNum%60));
return iH+":"+iM+":"+iS;
}
function toZero(num) { // 9--09,12--12
if(num<=9){
return "0"+num
}
return ""+num;
}
function nowTime(){
oInput[1].value = changeTime(oV.currentTime)
}
oInput[3].onclick = function () {
if(oV.muted){
oV.volume = 1
this.value = "静音"
oV.muted = false //这句话一定要加
}
else {
oV.volume = 0
this.value = "取消静音"
oV.muted = true //这句话一定要加
//volume音量并不会影响muted值,所以需要手动设置
}
}
oInput[4].onclick = function () {
oV.webkitRequestFullScreen()
}
其中关于h5控制全屏播放,可参考如下博客:
张鑫旭:HTML5全屏API在FireFox/Chrome中的显示差异
武方博:html5实现全屏的api方法
练习4:自制播放器(部分代码)
功能:视频进度拖拽控制(只是做了通过拖拽控制视频进度,其他的相互影响的代码暂时未写)
<video controls id="v1">
<source :src="aaa"></source>
</video>
<div id="div1">
<div id="div2"></div>
</div>
var oV = document.getElementById("v1")
var oDiv1 = document.getElementById("div1")
var oDiv2 = document.getElementById("div2")
var oDuration = null //媒体总时长
var disX = 0 //视频进度
oV.addEventListener("canplay", function () {
oV.width = 250
oV.height = 500
oDuration = oV.duration
}, false)
oDiv1.onmousedown = function (ev) {
var ev = ev || window.event
disX = ev.clientX - oDiv1.offsetLeft
oDiv2.style.width = disX + "px"
document.onmousemove = function (ev) {
var ev = ev || window.event
var L = ev.clientX - oDiv1.offsetLeft
if(L<0){
L = 0
}
else if(L > oDiv1.offsetWidth){
L = oDiv1.offsetWidth
}
oDiv2.style.width = L + "px"
var scale = L / oDiv1.offsetWidth
oV.currentTime = oDuration * scale.toFixed(2)
}
document.onmouseup = function () {
document.onmousemove = null
}
return false
}