【原创】 2019.09.05
JSMpeg项目地址:https://github.com/phoboslab/jsmpeg
JSMpeg 是一种采用Javascript解码音视频的技术,可用于视频直播或点播。
首先,我们为什么要用JSMpeg技术?
- HTTP-FLV技术在IOS Safari不被支持。
- WebRTC技术兼容性差。
- HTTP Live Streaming (HLS) 有巨大的,无法优化的直播延时。
- 并不是所有浏览器可以解码H.264, 并不是所有浏览器可以解码VP8。
因此,JSMpeg直播方案几乎是唯一的高兼容性、低延时H5直播方案。
播放器核心代码很简单:
<script src="jsmpeg.min.js"></script>
<div class="jsmpeg" data-url="video.ts"></div>
创建一个完整的播放Demo步骤如下:
下载 jsmpeg.min.js
https://jsmpeg.com/jsmpeg.min.js
下载 一个ts文件,并改名video.ts
https://jsmpeg.com/blade-runner-2049-360p.ts
创建一个index.html文件,内容如下:
<!DOCTYPE html>
<html>
<head>
<title>JSMpeg Demo</title>
<meta name="viewport" content="width=device-width"/>
</head>
<body>
<div class="content">
<div class="section">
<h1>JSMpeg Vod Demo - 2019.09.02 Evan </h1>
</div>
<div class="jsmpeg full-width" data-url="video.ts"
data-loop="true" data-autoplay="true""></div>
</div>
<script type="text/javascript" src="jsmpeg.min.js"></script>
</body>
</html>
写好的html文件在这里:http://47.244.50.172:8080/play/jsmpeg/360p/index.html
再配置一个nginx服务器(用其他web服务器也可以)。在nginx的html目录创建创建一个播放目录 例如:nginx/html/play/jsmpeg/360p/
将 jsmpeg.min.js、 video.ts、 index.html 三个文件放到创建的目录,播放环境就搭建完毕了:
用谷歌浏览器访问下面地址,即可播放。
http://47.244.50.172:8080/play/jsmpeg/360p/
其中47.244.50.172:8080要根据你的nginx提供的服务改成你自己的IP和端口
这个播放过程很流畅,画面清晰,对CPU的消耗比VLC高100%左右。这个播放需要等文件下载完毕后才开始播放,文件加载时间比较长。
直播
这里有个文章https://imququ.com/post/html5-live-player-2.html
作者5年没更新了,现在的版本已经采用TS流并且支持音频了。
不过他的文章给我很多帮助,引用这里的一句话:
看到这里,大家肯定会说,这不是要一次性下完全部内容么,怎能称之为直播。是的,要实现直播,还要用 Web Sockets 实现一个实时传输流的服务。FFmpeg 支持很多直播流格式,但不支持 Web Sockets。解决方案是用 FFmpeg 开一个 HTTP 直播流,再开个 Node 服务转一下。
详细一点的过程是这样的,用 NodeJS 监听 FFmpeg 的 HTTP 直播地址,把收到的数据 通过 Web Sockets 广播给所有客户端。
Websocket代码在这里:https://github.com/phoboslab/jsmpeg/blob/master/websocket-relay.js
Websoket服务部署:
我这里使用的系统是 CentOS 7 64bit
创建目录:
mkdir /opt/nodejs/
下载nodejs
cd /opt/nodejs
wget https://nodejs.org/dist/v12.9.1/node-v12.9.1-linux-x64.tar.gz
tar zxvf node-v12.9.1-linux-x64.tar.gz
安装ws模块。注意,这里有个坑,如果按照官网提供的方式安装,即直接敲命令 npm install ws 会将ws模块安装到其他目录,导致启动服务报错:“cannot find module 'ws'”,所以我这里改成这样的安装方式:
cd node-v12.9.1-linux-x64/bin
./node ./npm install ws
./node ./npm install http-server
拷贝JSMpeg项目里面的websocket-relay.js 文件到这个目录:
/opt/nodejs/node-v12.9.1-linux-x64/bin
运行 ./node websocket-relay.js live
这里的‘live’字符串实际上是密码,注意和下面推流的密码需要保持一致,否则推流会失败。
到这里websocket服务搭建完毕。
采集摄像头视频推流:
下载ffmpeg windows版本 https://ffmpeg.zeranoe.com/builds/
我这里使用的版本是 ffmpeg-4.2-win64-static.zip
这里我遇到个坑,运行官网提供的推流命令会失败。可能因为官网文档2年多没更新了,旧版本文档中的ffmpeg命令已经不支持了。
经过测试,ffffmpeg 4.2 windows版本可以成功推送摄像头视频的命令如下:
ffmpeg -y -f vfwcap -r 25 -i 0 -f mpegts -codec:v mpeg1video -s 1280x720 -b:v 1000k -bf 0 http://47.244.50.172:8081/live/
这条ffmpeg命令的各个参数解释如下:
-y: 覆盖目标
-f vfwcap: 设置视频源类型为vfwcap (VfW 视频采集)
-r 25: 设置帧率25fps
-i 0: 从0号摄像头采集
-f mpegts: 设置输出视频格式 mpegts
-codec:v mpeg1video 设置视频编码
-s 1280x720: 设置输出尺寸
-b:v 1000k: 设置输出码率
-bf 0: 未知 (官网例子都带了这个参数,但Evan不知道这个参数的具体含义)
播放:
再写个直播播放器 的index.html,代码如下:
<html>
<head>
<title>WS video player</title>
<style type="text/css">
body {
text-align: center;
width: 100%;
height: 100%;
}
#videoCanvas {
/* Always stretch the canvas to 640x480, regardless of its internal size. */
width : 100%!important;
max-width: 800px;
}
</style>
<style type="text/css">
html, body {
background-color: #333;
text-align: center;
}
</style>
</head>
<body>
<h1>JSMpeg player - Evan v2019.09.03</h1>
<p>
<input type="text" id="inputUrl" onkeydown="if(event.keyCode==13)play();" value="ws://47.244.50.172:8082/"
size="80" />
<button id="btnplay" onClick="play();" type="button">Play</button>
</p>
<p>
<canvas id="videoCanvas" align = "center">
</p>
<script type="text/javascript" src="jsmpeg.min.js"></script>
<script type="text/javascript">
var canvas = document.getElementById('videoCanvas');
var bPlay = false;
var player = null;
var btn = document.getElementById('btnplay');
function play(){
if(bPlay)
{
player.stop();
//player.destroy()
delete player;
player = null;
bPlay = false;
btn.innerHTML = "Play";
}
else
{
var playUrl = document.getElementById("inputUrl").value ;
player = new JSMpeg.Player(playUrl, {canvas: canvas});
btn.innerHTML = "Stop";
bPlay = true;
}
}
</script>
</body>
</html>
(写好的html文件在这里: http://47.244.50.172:8080/play/jsmpeg/live/index.html)
将 jsmpeg.min.js、 index.html 放到nginx 的html目录,然后在谷歌浏览器里面打开这个地址,就可以观看直播视频了。播放地址:
http://47.244.50.172:8080/play/jsmpeg/live/
到这里,简单的JSMpeg直播环境搭建完毕。这个服务器仅仅支持推一路流,同时推多路流还需要改写ws服务器脚本。写一个支持多路流的ws脚本不难,写好后替换官网的websocket-relay.js文件就可以了。
本文链接:http://www.cnweblog.com/fly2700/archive/2019/09/07/325500.html