h5音频和视频

标签

  • audio video
  • source

<video>

视频容器

  • 容器文件,类似于压缩了一组文件
    --音频轨道
    --视频轨道
    --元数据:封面,标题,字幕等
    --格式:.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的时候,忽略此属性

音频和视频

编解码器(浏览器中内嵌了一个叫做编解码器的东西)

  • 原始的视频容器非常大,添加需编码,播放需解码
  • 音频编解码器:AACMPEG-3OggVorbis
  • 视频编解码器:H.264VP8OggTheora
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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 首先,我们要理解两个概念:容器(container)和编解码器(codec)。1.视频容器音频文件或视频文件,都只...
    IT小C阅读 1,291评论 2 5
  • 前言 早年看电影是在在线的视频网站上看,但是往往有些电影是需要会员或者是购买才能看的,作为一个穷学生让我为了看一个...
    萌哒哒的小貔貅阅读 17,449评论 1 17
  • 前言 说到视频,大家自己脑子里基本都会想起电影、电视剧、在线视频等等,也会想起一些视频格式 AVI、MP4、RMV...
    ForestSen阅读 22,819评论 10 202
  • 视频编码与封装方式详解 1.编码方式和封装格式 2.视频编码标准两大系统 MPEG-1 MPEG-2 MPEG-3...
    latthias阅读 6,348评论 0 22
  • 宝宝在30-32周胎动明显增大,一会规律地打嗝,一会拳打脚踢,有时候妈妈都受不了,看来是个活泼爱动的宝宝。最近浑身...
    王小蜗阅读 190评论 0 0