Win7 IE11中使用Videojs播放HLS视频

1,195 阅读2分钟

起因

需求大概就是页面支持播放HLS视频,并且最低适配到ie11。

播放器选用了Video.js7,Video.js7内置了videojs-http-streaming (VHS)插件,原生支持播放HLS视频。与Vue结合体验很好:

播放器源码大概是这样,还引入了videojs-playlist用于实现播放列表:

<template>
  <div class="video">
    <video ref="videoPlayer" class="video-js"></video>
  </div>
</template>

<script>
import videojs from 'video.js';
import 'videojs-playlist';

export default {
  name: 'VideoPlayer',
  props: {
    playlist: {
      type: Array,
      required: true,
    },
    selectedVideoIndex: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      player: null,
    };
  },
  watch: {
    playlist(newValue) {
      if (!this.player) return;

      this.player.playlist(newValue);
      this.player.playlist.autoadvance(0);
    },
    ...
  },
  mounted() {
    const that = this;

    this.player = videojs(
      this.$refs.videoPlayer,
      {
        controls: true,
        fill: true,
        autoplay: true,
        preload: true,
      },
      function onPlayerReady() {
        this.on('canplay', that.handleVideoCanPlay);
        this.on('waiting', that.handleVideoWaiting);
        this.on('play', that.handleVideoStart);
        this.on('pause', that.handleVideoPause);
        this.on('playlistitem', that.handleVideoChange);
        this.on('error', (err) => that.handleError(err));
      }
    );
  },
  methods: {
    ...
  },
};
</script>
<style scoped>
...
</style>

功能测试和兼容性测试阶段都没有发现什么问题,直到一位同事用他的win7笔记本打开了播放页面。。。

结果就是在win7的ie11上完全播不了视频,立即谷歌原因,找到:

解决方式

根据上面的链接,videojs的开发者建议在win7 ie11上利用flash播放器播放HLS视频,于是我们需要引入两个库:

修改代码

  1. 首先在播放器组件引入两个库:
import videojs from 'video.js';
import 'videojs-playlist';
import 'videojs-flash';
import '@brightcove/videojs-flashls-source-handler';
  1. 然后在新建播放器实例时,声明techOrder属性,优先使用html5播放器,当无法播放时使用flash播放器:
  mounted() {
    const that = this;

    this.player = videojs(
      this.$refs.videoPlayer,
      {
        controls: true,
        fill: true,
        autoplay: true,
        preload: true,
        techOrder: ['html5', 'flash'],
      },
      function onPlayerReady() {
        this.on('canplay', that.handleVideoCanPlay);
        this.on('waiting', that.handleVideoWaiting);
        this.on('play', that.handleVideoStart);
        this.on('pause', that.handleVideoPause);
        this.on('playlistitem', that.handleVideoChange);
        this.on('error', (err) => that.handleError(err));
      }
    );
}
  1. 最重要的是提供那个特殊的swf文件(用于播放HLS视频)的位置,供videojs-flash取用 这里使用的是官方提供的CDN链接,但更推荐将此文件部署在自己的服务器上取用
  mounted() {
    const that = this;

    this.player = videojs(
      this.$refs.videoPlayer,
      {
        controls: true,
        fill: true,
        autoplay: true,
        preload: true,
        techOrder: ['html5', 'flash'],
        flash: {
          swf: 'https://unpkg.com/@brightcove/videojs-flashls-source-handler/dist/video-js.swf',
        },
      },
      function onPlayerReady() {
        this.on('canplay', that.handleVideoCanPlay);
        this.on('waiting', that.handleVideoWaiting);
        this.on('play', that.handleVideoStart);
        this.on('pause', that.handleVideoPause);
        this.on('playlistitem', that.handleVideoChange);
        this.on('error', (err) => that.handleError(err));
      }
    );
}

代码修改到此结束,想看效果?别忘了下载Flash Player,不然还是播放不了的。

Flash Player下载

下载完成后刷新页面!我靠,怎么还是播不了。。。只不过这回换了个报错:

VIDEOJS: ERROR: (CODE:0 MEDIA_ERR_CUSTOM)  MediaError {type: "FLASHLS_ERR_CROSS_DOMAIN", origin: "flash", message: ""}

解决跨域

查询了一下问题原因

github.com/videojs/vid… www.cnblogs.com/tv151579/p/…

总结一下,也就是说我们页面域(a.com)下的swf文件会自动去请求媒体文件域(b.com)根目录下的一个crossdomain.xml文件,来确认该媒体文件能否被页面域访问。如果没有该文件或域名不匹配,则会报跨域错误。

crossdomain.xml配置规则

配置好了crossdomain.xml,将它部署到媒体文件域(b.com)根目录即可。

当你刷新播放页面能够看到这个请求被成功处理,说明该文件已成功部署

截止目前,win7 IE11上已能成功播放HLS视频!!! 接下来的工作就是需要给用户一个升级或者下载Flash Player的提示~