关于视频的一些总结

一. 视频事件

事件名 描述
abort 播放终止时触发。 如视频正在播放,这时拖到开始位置重新播放,就会触发 abort 事件
canplay 当 ready state 变为 HAVE_ENOUGH_DATA 时触发, 这表示有足够的数据可播放
canplaythrough 当 ready state 变为 CAN_PLAY_THROUGH 时触发,这表示下载速度在保持当前状态不变的情况下,整个媒体文件可以没有中断的进行播放。注意:在 Firefox 中,手动设置 currentTime 还会触发 canplaythrough 事件
durationchange 当 metadata 加载结束或修改结束时触发,这表示媒体文件的 duration 发生了变化
emptied 媒体文件变成空时触发。如媒体文件已经全部或部分加载完,这时调用 load() 去重新加载会触发 emptied 事件
ended 播放结束时触发
error 发生错误时触发。元素的 error 属性包含了详细信息。
interruptbegin 在 Firefox OS 设备,播放的 audio 被中断,或者在 app 中,正在播放 audio 的 app 转为后台运行,或是有更高优先级的 audio 开始播放,都会触发 interruptbegin 事件
interruptend 在 Firefox OS 设备中,之前中断的 audio 又开始重新播放,或者在 app 中,后台运行的 app 转为前台运行,或当更高优先级的 audio 播放结束,都会触发 interruptend 事件
loadeddata 媒体文件的第一帧加载完成时触发
loadedmetadata 媒体文件的 metadata 加载完成时触发
loadstart 媒体文件开始加载时触发
pause 播放暂停时触发
play 暂停之后重新播放时触发。也就是说,先得触发一个 pause 事件,然后重新播放才会触发 play 事件,需要注意的是,这只是一个动作,并不表示立即就会开始播放
playing 当媒体文件暂停或停止缓冲后,开始播放时触发
progress 媒体文件正在下载时触发。通过元素的 buffered 属性可以获取已下载的可用的数据
ratechange 播放速度改变时触发, 即playbackRate属性改变时触发
seeked seek 操作完成时触发
seeking seek 操作开始时触发, 拖动进度条的时候会触发seeking事件
stalled 当 user agent 尝试去拉取数据,但是数据没有传过来时触发
suspend 媒体文件加载暂停时触发。可能的原因是下载已完成,或是其他原因导致的暂停
timeupdate 元素的 currentTime 属性发生改变时触发
volumechange 音量发生改变时触发,可能是设置音量,也可能是修改了 muted 属性
waiting 当请求的操作(比如播放)因为另一个操作而阻塞时触发(比如 seek)

loadeddata VS canplay VS canplaythrough

  • loadeddata:加载了一些数据
  • canplay:加载了足够的数据,这些数据足够开始播放
  • canplaythrough:加载了足够的数据,这些数据不仅足够开始播放,也足够结束播放

play VS playing progress

假设我们要播放一个视频,当点击 play 按钮(或调用 play 方法),video.paused 会置为 false,并触发 play 事件,但这并不保证 video 会立即开始播放,它只是尝试去播放。

如果在任意时间点,video 没有足够的数据可用了,它就会暂停(同样的,video.paused 置为 false),并触发 waiting 事件。一旦有了足够的数据(readyState >= HAVE_FUTURE_DATA),就会触发 playing 事件,这时视频会重新开始播放。

因此,play 适合获取动作状态,playing 适合获取播放状态。比如,当触发 waiting 事件时,显示 loading,当触发 playing 事件时,移除 loading。

当用户拖拉进度条的时候,会触发事件 seeking——— play——— wating——— seeked——— playing

所以play事件触发时候可能视频还不能播放,只代表用户的操作;但是playing事件触发的时候,代表视频处于可播放状态

progress

通过元素的 buffered 属性可以获取缓冲数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
progressEvent ($event) {

let video = $event.currentTarget;

// 如果还没有buffer不要取,不然会抛异常

// Failed to execute 'end' on 'TimeRanges': The index provided (4294967295) is greater than the maximum bound (0).

if (video.buffered.length) {

let bufferedEnd = video.buffered.end(video.buffered.length - 1);

let duration = video.duration;

this.videoBufferRate = bufferedEnd / duration;
}
},

二. 视频属性

可以查看MDN上的HTMLMediaElement元素的属性

error, currentSrc, preload, seeking, paused, played, autoplay, volume, audioTracks, width,height, videoHeight(视频原本的高度),videoWidth(视频原本的高宽度), buffered, currentTime, loop, muted, poster, srcObject(这是一个mediaStream对象), readyState, networkState, duration, playbackRate, ended,controls 等等

三. 视频全屏

  1. 视频全屏

    判断是否是在全屏状态:

    1
    2
    3
    isInFullscreen () {
    return (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement)
    }

    进入全屏:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    requestFullScreen (element) {
    if (element.requestFullscreen) {
    element.requestFullscreen();
    } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
    } else if (element.msRequestFullscreen) {
    element.msRequestFullscreen();
    } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullScreen();
    }
    this.fullScreen = 1;
    }

    退出全屏:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    exitFullscreen (element) {
    // 普通div 需要使用document才能exitFullscreen
    // video 可以使用元素本身的exitFullscreen
    if (element.exitFullscreen) {
    element.exitFullscreen();
    } else if (element.msExitFullscreen) {
    element.msExitFullscreen();
    } else if (element.mozCancelFullScreen) {
    element.mozCancelFullScreen();
    } else if (element.webkitCancelFullScreen) {
    element.webkitCancelFullScreen();
    }
    }
  2. 普通div全屏

    普通div(假设为container)全屏时注意两个点:

    (1)如果container包含video标签和其他div标签,那么在全屏之后video的z-index会特别高,以至于全屏之后只会显示video,其他元素会被隐藏。

    解决方法,将需要与video一同全屏显示的标签加上z-indx:2147483647

    (2)在调用上面requestFullScreen的时候传入需要全屏的div,但是调用exitFullscreen的时候需要传入document对象才可以退出全屏