Vue 中使用 Video.js 播放 RTMP 视频
香港卫视有直播的 RTMP 流,本文简述了使用 Vue 技术播放 RTMP 流媒体的方法。
在网页上播放视频或者直播流,比较常用的视频流有很多。可以分为几类技术:
- HTTP 系列。直播采用的是 ogg 格式的流媒体;
- Apple 系列。直播采用的是 HLS 格式的流媒体;
- Flash 系列。直播采用的是 RTMP 格式的流媒体。
Video.js 库已经将常见的视频流进行了封装,并扩展了 HTML 的视频控件的能力。 因此我们主要使用 Video.js 作为基础进行开发。
Vue-Video-Player 的改造
在 Vue 中使用 Video.js 库的时候,常用的库就是 Vue-Video-Player 这个库。 这个库将 Video.js 封装为 Vue 组件,在 Vue 项目中直接引用即可。 但是这个库在播放 RTMP 格式视频流的时候,会出现问题!我们需要对其进行改造。
其实这个库最核心的源码就是一个名为 player.vue
的组件。其他文件不过是作为 Vue 插件的必要代码。 因此,我们可以直接将这个组件复制到我们的工程中,以普通组件的方式引入即可。 然后对其进行改造。改造方法如下
1 | import _videojs from 'video.js' |
这个库无法播放 RTMP 的根本原因尚不清楚,不过从这个改造方法来看,可能是由于作用域的问题, 导致在外部引入的 videojs-flash
模块无法在这个组件中加载,因此需要将这个模块在组件中引入。 然后运行即可。
1 | <template> |
在 Electron 中播放
在 Electron 中播放,需要加载 Flash。加载的方法也很简单,将下面代码加入创建窗口之前
1 | let flashPath = app.getPath('pepperFlashSystemPlugin'); |
然后打开 Electron 插件的功能
1 | mainWindow = new BrowserWindow({ |
然后把 videojs-flash
中提供的 video-js.swf
文件放到 statics
文件夹下即可。 这是我们在 Electron 中使用的效果。
打包模式下的问题
上述 Electron 应用在打包后,就无法播放 RTMP 视频了。为什么呢?
Electron 应用一旦打包,所有资源的加载都是以
file://
协议进行加载的,这时 Flash 被禁用了。
这是官方的解释。但是其实我试过,直接用 embed
标签从 static
文件夹中加载 swf 文件是可以的。 但是为什么 video-js.swf
就加载不出来,原因就不得而知了。 如果想要加载视频,可以采取将 Electron 编译好的 HTML 文件放到服务器上,如 nginx 。 通过服务器加载 Electron 应用内的页面。
官方给出的解决方案是,使用 nw-flash-trust
库,信任 Flash 。 但是我至今也没有试出来到底怎么使用这个库。
经过测试,我实验出了一种打包方法,可以摆脱单独的服务器。原理是采用内置服务器,最简单的方法是用 Express。 在应用程序的主进程中创建一个 Express 服务器,只需要设置静态文件中间件,即可通过服务器加载页面。 在主进程的 index.js
文件中添加如下函数
1 | function localServer() { |
然后做如下修改:
1 | import express from "express" |
1 | function createWindow () { |
然后就可以愉快地在本地播放 RTMP 视频啦。
这是本地播放视频的效果。 (没想到香港卫视晚上竟然在播《虹猫蓝兔七侠传》系列,童年心痛的回忆啊,央视播了一半被举报然后停播了)
在网页中播放
由于现在主流浏览器都抛弃了 Flash ,默认关闭 Flash 。而 Video.js 是不会去请求 Flash 权限的。 因此我们需要一个 embed
标签加载一个 swf 文件,通过点击这个标签获取 Flash 权限。 当然,在实际生产中,后续如何处理,就看大家怎么搞了。
这是我们在网页上获取 Flash 权限之前的效果:
点击 flash 文件,获取权限,效果如下: