• vue+flvjs实现自定义控制条的流媒体播放器


    vue+flvjs实现自定义控制条的流媒体播放器

    flvjs与FLV有什么区别和联系?

    flv.js

    是 HTML5 Flash 视频(FLV)播放器,纯原生 JavaScript 开发,没有用到 Flash。由 bilibili 网站开源(Github)。

    概览:

    一个实现了在 HTML5 视频中播放 FLV 格式视频的 JavaScript 库。它的工作原理是将 FLV 文件流转码复用成 ISO BMFF(MP4 碎片)片段,然后通过 Media Source Extensions 将 MP4 片段喂进浏览器。

    flv.js 是使用 ECMAScript 6 编写的,然后通过 Babel Compiler 编译成 ECMAScript 5,使用 Browserify 打包。

    功能:

    • FLV 容器,具有 H.264 + AAC 编解码器播放功能
    • 多部分分段视频播放
    • HTTP FLV 低延迟实时流播放
    • FLV 通过 WebSocket 实时流播放
    • 兼容 Chrome, FireFox, Safari 10, IE11 和 Edge
    • 十分低开销,并且通过你的浏览器进行硬件加速

    FLV

    HTTP FLV则是将RTMP封装在HTTP协议之上的,可以更好的穿透防火墙等。rtmp和http-flv的视频格式都是flv格式的,只是传输协议而不同。rtmp是tcp的传输协议,而http-flv是http长链接的传输协议。

    总结

    flvjs是一个H5播放器。FLV是一种协议。flvjs可以用于播放FLV格式的视频。

    几种视频流比较。

    协议 http-flv rtmp hls
    传输方式 http流 tcp流 http流
    视频封装格式 flv flv Ts文件
    延迟
    数据分段 连续流 连续流 切片文件
    h5播放 flv.js video.js hls.js

    vue中使用flvjs。

    1.使用npm安装flv.js

    npm install --save flv.js
    

    2.新建FlvLive.vue文件,在文件中引入

    import flvjs from 'flv.js'
    

    3.在template标签中添加代码

      <figure
        ref="videoContainer"
        data-fullscreen="false"
      >
        <video
          ref="video"
          autoplay
        >
          Your browser is too old which doesn't support HTML5 video.
        </video>
       </figure>
    

    4.在created中加入以下代码

    this.$nextTick(() => {
        if (flvjs.isSupported()) {
            const flvPlayer = flvjs.createPlayer({
                type: 'flv',
                isLive: true,
                url: this.src,
            });
            flvPlayer.attachMediaElement(this.$refs.video);
            flvPlayer.load();
            flvPlayer.play();
            this.flvPlayer = flvPlayer;
        }
    });
    

    flvjs.isSupported()判断当前浏览器是否支持flv。

    flvPlayer.attachMediaElement(this.$refs.video) 挂载video标签。

    也可以使用如下方式:

    <video
        id="videoEdlement"
        autoplay
    >
        Your browser is too old which doesn't support HTML5 video.
    </video>
    

    js

    const id = document.getElementById('videoEdlement')
    flvPlayer.attachMediaElement(id)
    

    使用这种方式会导致组件无法复用。除非给video传入不同的id的值。

    5.传入src,一个简单的播放器就完成了。也可以在video标签中加入controls属性以利用H5播放器自带的控制条。

    自定义控制条。

    效果图,画面是ffmpeg推的一个mp4的流。红框部分为控制条。

    使用全屏API

    这里使用webkitRequestFullScreen()API实现全屏功能。

    webkitRequestFullScreen() 方法用于发出异步请求使元素进入全屏模式。来自MDN教程的解释。

    使用全屏API时需要注意,如果全屏的元素是video,自定义的控制条会被全屏后的video元素覆盖住,更改z-index也不能解决。所以要放大video的父级元素。

    this.$refs.videoContainer.webkitRequestFullScreen();

    CSS部分

    设置全屏时的背景,隐藏全屏时video标签中的控制条。

    /* fullscreen */
    html:-ms-fullscreen {
         100%;
    }
    :-webkit-full-screen {
        background: #666;
    }
    figure[data-fullscreen='true'] {
        max- 100%;
         100%;
        margin: 0;
        padding: 0;
        /* hide controls on fullscreen with WebKit */
        video::-webkit-media-controls {
            display: none !important;
        }
    }
    

    figure[data-fullscreen='true'] {...}

    在点击全屏按钮时会改变这个属性。体现在如下代码中。

    setFullscreenData(state) {
        this.$refs.videoContainer.setAttribute(
            'data-fullscreen',
            Boolean(state),
        );
    },
    

    判断当前页面是否处于全屏状态

    对应不同的浏览器内核做兼容处理。

    isFullScreen() {
        return Boolean(
            document.fullScreen ||
            document.webkitIsFullScreen ||
            document.mozFullScreen ||
            document.msFullscreenElement ||
            document.fullscreenElement,
        );
    },
    

    开发中遇到的报错

    Uncaught (in promise) DOMException:The play() request was interrupted by a new load request
    

    报错信息表示:视频还没有准备好,就已经开始播放了。这种情况会出现在,视频地址错误的情况下。常常是地址为空,或者格式错误。

    Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
    

    调用play()的时候,音频文件还没有加载完成导致的问题。建议给video标签加上autoplay。不然老是出现这个问题。到底是什么原因导致的还不知道。

    同一页面中引入4个画面时,其他三个画面会报错。video标签的id一致导致的。

    总结

    本文通过实现一个自定义控制条的H5播放器,来学习相关的内容,包括:flvjs在vue中的使用。js的全屏API。以及一个document的一些内置对象的使用。

    完整代码:gitee

    passion
  • 相关阅读:
    [译] 我最终是怎么玩转了 Vue 的作用域插槽
    通俗易懂的Git使用入门教程
    JS取出两个数组的不同或相同元素
    jQuery中四种事件监听的区别
    vuex里mapState,mapGetters使用详解
    php 获取时间今天明天昨天时间戳
    Linux crontab定时执行任务
    php返回json数据函数实例_php技巧_脚本之家
    mysql查看表结构命令
    Mysql命令大全
  • 原文地址:https://www.cnblogs.com/youngniu/p/14373059.html
Copyright © 2020-2023  润新知