04月04, 2019

HTML5音频笔记

前阵子群里面的兄弟有推荐了一款应用:Quiver。试用了一下,感觉挺好,在此也推荐给大家。

这阵子似乎不是太想写博客,一方面是今年过来之后,也一直处于忙碌的状态,一方面搬了家(每天路上的时候就要2个小时了),还有也不像去年996那阵子好歹周六有个大半天的时间列提纲写文章。

之所以有这篇文章,我是感觉自己在移动端包括H5上面略显得薄弱。因为一直以来自己90%的时间都是在搞PC端的东西,移动端的问题要么别人自己解决了,要么我利用网上的资源帮别人解决了。今年这边公共团队也要做一些移动端的事,所以不得不去学习亦或是借鉴别人的东西,而不是说直接把别人的东西拿过来用(毕竟公司的前端方向在慢慢地往上发展)。

在慕课网上刚好有类似的主题:

alt

以下是我做的一些学习笔记吧。

video相关

写法

<video src="/media/examples/flower.mp4" controls>

支持类型

  • mp4
  • webm
  • ogv

兼容情况

IE8(包括)以下不支持video

IE9以上、safari浏览器不支持webmogv两种格式。

<video controls width="250">
    <source src="/media/examples/flower.webm" type="video/webm">
    <source src="/media/examples/flower.mp4" type="video/mp4">
    Sorry, your browser doesn't support embedded videos.
</video>

说明:video通过source来控制播放源,当浏览器不支持webm格式时,会往下一个去找。

video标签属性

  • src
  • width
  • height
  • controls
  • autoplay
  • loop (循环播放)
  • poster (视频封面,没有播放时显示的图片)
  • musted (当设置属性后,它规定视频的音频输出应该被静音)

widthheight一起使用时,播放器可能会被拉伸,但是播放内容不会拉伸,始终在最中心的位置。

只使用autoplay属性,在chrome下不会自动播放,但是结合musted,它就可以自动播放了。

video api事件

第一部分

  • play
  • pause
  • duration (返回当前视频的长度)
  • currentTime
  • src
  • volume (取值0-1)
  • controls (设置一下video上面的控件)
  • muted
  • networkState (返回视频的当前网络状态)
const videoNode = document.getElementById("myVideo");
// videoNode.play(); // 直接会在浏览器下报错,它不允许有声音的自动播放
// console.log(videoNode.duration); // 一开始得到的是NaN,得要通过定时器,过会儿拿
setTimeout(() => {
    const min = parseInt(videoNode.duration/60);
    const sec = parseInt(videoNode.duration%60);
    console.log(`${min}:${sec}`);
}, 100);

// 实现快进
const obtn = document.getElementById("快进按钮");
obtn.onclick = () => {
  videoNode.currentTime = videoNode.currentTime + 3
}

console.log(videoNode.networkState); // 3 (视频未找到)
setTimeout(() => {
   console.log(videoNode.networkState); // 1 视频已加载
}, 100);

networkState有三种状态:

  • 0 (未初始化)
  • 1 (视频已经选取好资源,但是未使用网络)
  • 2 (浏览器正在下载视频资源)
  • 3 (未找到视频资源,在一开始情况下,因为video不会立即找到资源,所以也会出现 3 这个状态码)

第二部分

  • currentSrc (返回当前视频的URL)
  • ended (返回视频的播放是否已结束)
  • loop (设置或返回视频是否应该在结束时重新播放)
  • playbackRate (设置或者返回视频播放的速度)
  • readyState (属性返回视频的当前就绪状态)
  • timeupdate (当目前的播放位置已更改时)
  • seeked (当用户已移动/跳跃到视频中的新位置时)
  • seeking (当用户开始移动/跳跃到视频中的新位置时)
  • volumechange (当音量更改时)
const videoNode = document.getElementById("myVideo");
console.log(videoNode.currentSrc); // 空字符串
setTimeout(() => {  
  console.log(videoNode.currentSrc); // 这里才能取到值,并且它不能赋值
}, 100);

videoNode.addEventListener('ended', () => {
  console.log('视频播放结束了');
}, false); 

// 查看或者设置视频的一个播放速度
console.log(videoNode.playbackRate);
videoNode.playbackRate = 0.5// 2 | 5,往快设置

// 监听视频的播放状态
videoNode.addEventListener('timeupdate', () => {
  // console.log('视频播放了');
  // 这里我们利用`currentTime`和`duration`可以实现播放了多长时间
}, false); 

// seeked 当用户对视频的进度条并且已经完成操作时会触发的事件,使用的时候必须用on
videoNode.onseeked = () => {
  console.log('seeked');
}

// seeking 当用户开始拖动进度条时 就会触发的事件,使用的时候必须用on
videoNode.onseeking = () => {
   console.log('seeking...');
}

// 当音量改变时
videoNode.onvolumechange = () => {
   console.log('change...');
}

readyState有三种状态:

  • 0 (没有关于视频就绪的信息)
  • 1 (有数据 但快不足以支撑了)
  • 2 (当前的数据是可以用 但是没有数据来播放下一帧/毫秒了)
  • 3 (数据正在缓冲 当前及至少下一帧是可用了)
  • 4 (可用数据足已开始播放)

第三部分

  • requestFullscreen (全屏)
  • load (从新视频加载资源)
  • canplay (视频已经准备好开始播放)
const videoNode = document.getElementById("myVideo");
// videoNode.requestFullscreen(); // 报错
videoNode.webkitRequestFullscreen(); // 不起作用,提示得用户操作

obtn.onclick = () => {
  videoNode.webkitRequestFullScreen();
}

// 但是要注意的是火狐不认webkit,它得写成`mozRequestFullScreen`,s变成大写

// load 刷新播放器的事件
obtn.onclick = () => {
  videoNode.src = "xx";
  videoNode.load(); // 当视频来源更新时,需要重新刷新
}

videoNode.addEventListener('canplay', () => {
  console.log('视频已经加载好 可以开始播放了');
}, false)

自定义视频播放器

需要实现的点有:

  • 布局
  • 暂停/播放
  • 全屏(可以给图标做一个动画效果)
  • 时间的计算(当前播放时长、总时长)
  • 播放进度条(能随着播放变化、能拖拽)
  • 声音进度条

视频总时间的计算

一开始计算的值是NaN,所以这种方式是有问题的

// 监听能够播放的事件
videoNode.addEventListener('canplay', () => {
  // videoNode.duration
}, false);

当视频播放的时候,需要当前的时间动起来

videoNode.addEventListener('timeupdate', () => {

}, false);

拖拽简单代码

node.onmousedown = (e) => {
  const ev = e || event;
  const l = ev.clientX - this.offsetLeft; // 算出鼠标指针在node元素的x偏移量
  document.onmousemove = (e) => {
    const ev = e || event;
    const needX = ev.clientX - l; // 计算要移动的距离

    // 这里可以处理一下边界范围

    node.style.left = `${needX}px`;

  }
  document.onmouseup = () => {

    document.onmousemove = document.onmouseup = null;
  }
  return false; // 去掉默认事件
}

拖拽注意点

  • 拖的时候,要pause,暂停视频
  • 抬起的时候,要继续play (如果当前的状态是处于play状态)
  • 抬起的时候,能在当前位置播放
// 设置抬起的时候在当前位置播放
videoNode.currentTime = videoNode.duration * (移动的长度/总长度);

audio相关

使用基本同video标签

写法

<audio src="/media/examples/flower.mp4"></audio>

支持类型

  • mp3
  • wav
  • ogg

兼容问题

safari浏览器不认ogg格式

js生成audio对象

const myAudio = new Audia();
myAudio.src = '音频地址';
myAudio.play(); // chrome会报错,得有用户交互

audio 标签属性

  • src
  • controls
  • autoplay
  • loop
  • muted

需要注意的是,和video不同,在chrome下audio加了autoplaymuted并不会自动播放。

另外,在audio中没有widthheight属性,必须使用style标签进行控制。

audio API事件

第一部分

  • play
  • pause
  • duration
  • currentTime
  • src
  • volume
  • controls
  • muted
  • networkState

第二部分

  • currentSrc
  • ended
  • loop
  • playbackRate
  • readyState
  • timeupate
  • seeked
  • seeking
  • volumechange

第三部分

  • requestFullscreen
  • load
  • canplay

注意:requestFullscreen必须使用audio标签,js对象不能使用。

自定义MP3音频播放器

需要实现的点有:

  • 布局
  • js动态创建audio对象
  • 暂停/播放
  • 静音/正常
  • 播放进度条
  • 点击进度条 (需要计算鼠标的位置所占的百分比,currentTime的值就是duration*百分比)
  • 上一首/下一首 (及背景图切换)

拓展

之前有记录过直播相关的笔记,大家有兴趣也可以看看:H5直播开发相关笔记

本文链接:www.my-fe.pub/post/html5-video-audio-note.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。