web 前端

vue中使用vue-video-player,播放m3u8格式的

2019-08-05  本文已影响21人  一号聪明

video.js

后台加密采用的是切片加密,我项目中用户点播的时候拿到的是一个m3u8格式的视频连接,M3U8 是 Unicode 版本的M3U,用 UTF-8 编码。"M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP Live Streaming(HLS) 协议格式的基础,这种协议格式可以在 iPhone 和 Macbook 等设备播放。而 HLS是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议。

HLS 的工作原理是把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的 extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。
HLS 只请求基本的 HTTP 报文,与实时传输协议(RTP)不同,HLS 可以穿过任何允许 HTTP 数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。

简而言之,HLS 是新一代流媒体传输协议,其基本实现原理为将一个大的媒体文件进行分片,将该分片文件资源路径记录于 m3u8 文件(即 playlist)内,其中附带一些额外描述(比如该资源的多带宽信息···)用于提供给客户端。客户端依据该 m3u8 文件即可获取对应的媒体资源,进行播放。

我去,跑题了,,,说重点了。

  cnpm install video.js 
  cnpm install videojs-contrib-hls --save
main.js中引入css 
import hls from 'videojs-contrib-hls'
Vue.use(hls)
// 组件中引入video样式
<video-player
        @click.stop
        class="video-player"
        :playsinline="playsinline"    //播放器的配置,下面的方法,官方文档中给出了对应的解释
        :options="playerOptions"
        :headers="headers"
        @play="onPlayerPlay($event)"
        @pause="onPlayerPause($event)"
        @ended="onPlayerEnded($event)"
        @loadeddata="onPlayerLoadeddata($event)"
        @waiting="onPlayerWaiting($event)"
        @playing="onPlayerPlaying($event)"
        @timeupdate="onPlayerTimeupdate($event)"
        @canplay="onPlayerCanplay($event)"
        @canplaythrough="onPlayerCanplaythrough($event)"
        @ready="playerReadied"
        @statechanged="playerStateChanged($event)"
      >
</video-player>
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
// js部分
export default {
  name: 'index',
  props: ['videoPath'],
  data () {
    return {
      playsinline: true,
      playerOptions: {
        events: [],
        playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
        autoplay: true, // 如果true,浏览器准备好时开始回放。
        controls: true, //  控制条
        preload: 'auto', // 视频预加载
        muted: false, //  默认情况下将会消除任何音频。
        loop: false, // 导致视频一结束就重新开始。
        language: 'zh-CN',
        controlBar: {
          timeDivider: true,
          durationDisplay: true
        },
        aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
        sources: [{
          type: 'application/x-mpegURL',
          src: ''
        }],
        hls: true, // 启用hls?
        poster: '', // 你的封面地址
        width: document.documentElement.clientWidth,
        notSupportedMessage: '此视频暂无法播放,请稍后再试' //  允许覆盖Video.js无法播放媒体源时显示的默认信息。
      },
  
    }
  },
  created () {
    let userInfo = localStorage.getItem('userInfo')
    let token = JSON.parse(userInfo).accessToken
    this.playerOptions.sources[0].src = this.videoPath
  },
  methods: {
    // listen event
    onPlayerPlay (player) {
      console.log('player play!', player)
    },
    onPlayerPause (player) {
      console.log('player pause!', player)
    },
    onPlayerEnded (player) {
      console.log('player ended!', player)
    },
    onPlayerLoadeddata (player) {
      console.log('player Loadeddata!', player)
    },
    onPlayerWaiting (player) {
      console.log('player Waiting!', player)
    },
    onPlayerPlaying (player) {
      console.log('player Playing!', player)
    },
    onPlayerTimeupdate (player) {
      console.log('player Timeupdate!', player.currentTime())
    },
    onPlayerCanplay (player) {
      console.log('player Canplay!', player)
    },
    onPlayerCanplaythrough (player) {
      console.log('player Canplaythrough!', player)
    },
    playerStateChanged (playerCurrentState) {
      console.log(playerCurrentState)
    },
    playerReadied (player) {
      let _this = this
      var hls = player.tech({ IWillNotUseThisInPlugins: true }).hls
      player.tech_.hls.xhr.beforeRequest = function (options) {
        console.log(options)
        let userInfo = localStorage.getItem('userInfo')
        let token = JSON.parse(userInfo).accessToken
        options.headers = {
          'Accept': 'application/json, text/plain, */*',
          'Content-Type': 'application/json;charset=UTF-8',
          'Accept-Language': 'zh-CN,zh;q=0.9,hy;q=0.8,mn;q=0.7',
          'Authorization': 'Bearer ' + token
        }
        return options
      }
    },
    close () {
      this.$emit('close')
    }
  }
}

let userInfo = localStorage.getItem('userInfo')
let token = JSON.parse(userInfo).accessToken
options.headers = {
'Accept': 'application/json, text/plain, /',
'Content-Type': 'application/json;charset=UTF-8',
'Accept-Language': 'zh-CN,zh;q=0.9,hy;q=0.8,mn;q=0.7',
'Authorization': 'Bearer ' + token
}
return options

重点在以上部分,因为当用户点播的时候,后台需要对其进行鉴权。需要设置请求头将用户的token传给后台,查阅了好多博客,没有给出合理的配置,也有说修改源码解决的,我也尝试着改了源码,都模块化了,好多东西找不到修改的位置。改的也是一团糟,也尝试了别的播放器,发现都没有vue-video-player成熟。就在官网中又找了找。查阅好几遍,就发现只有这块能拦截到请求,但并没有告诉怎么改,扎心了。试了好几种。最后这种形式的成功的把请求头设置了。希望能帮到正在观看的你。

上一篇下一篇

猜你喜欢

热点阅读