技术栈
● JSMpeg
● node服务端
● node包:node-rtsp-stream
● mac环境安装ffmpeg(brew install ffmpeg)
一、JSMpeg
JSMpeg: JavaScript中的MPEG1视频和MP2音频解码器
是一个用JavaScript编写额视频播放器。它由一个MPEG- TS解复用器、MPEG1视频和MP2音频解码器、WebGL和Canvas2D渲染器以及Web Audio声音输出组成。JSMpeg可以用过Ajax加载静态视频,并允许通过websockets进行低延迟流式传输(约50毫秒)
JSMpeg 可以在IPhone5S上一30fps的速度节吗720视频,适用于任何现代浏览器(Chrome、Firefox、Safari、Edge),压缩后的大小仅为20kb
<script src="jsmpeg.min.js"></script>
<div class="jsmpeg" data-url="video.ts"></div>
<div class="jsmpeg" data-url="<url>"></div>
或者直接调用JavaScript中的JSMpeg.Player()构造函数
var player = new JSMpeg.Player(url, [, options]);
请注意,使用HTML元素(内部为JSMpeg.VideoElement)在JSMpeg.Player智商提供了一些功能。即SVG暂停/播放按钮和在IOS动画热播日的还是那个解锁音频的能力。
url参数接受MPEG.ts文件或Websocket服务器的(ws://…)的URL
options参数支持一下属性:
● canvas-用于视频渲染的HTML canvas元素。如果没有给出,渲染器将创建自己的Canvas元素。
● loop-是否循环播放视频(仅限静态文件)默认为true
● autoplay- 是否立即开始播放(仅限静态文件)。默认false
● audio- 是否解码音频。默认为true
● video - 是否解码视频。默认为true
● 海报 - 图像的URL, 用作视频播放前显示的海报。
● pauseWhenHidden - 选项卡处于非活动状态时是否暂停播放,默认为true。请注意,浏览器通常会在非活动选项卡中限制JS
● disableGl - 是否禁用 WebGL 并始终使用 Canvas2D 渲染器。默认false。
● disableWebAssembly - 是否禁用 WebAssembly 并始终使用 JavaScript 解码器。默认假
● preserveDrawingBuffer - 是否使用 preserveDrawingBuffer 创建 WebGL 上下文 - 对于通过canvas.toDataURL() 的“屏幕截图”来说是必需的。默认假。
● progressive - 是否以块的形式加载数据(仅限静态文件)。启用后,可以在整个源完全加载之前开始播放。默认为真。
● throttled - 使用渐进式时,是否在不需要播放时延迟加载块。默认为真。
● chunkSize - 使用渐进式时,一次加载的块大小(以字节为单位)。默认 10241024 (1mb)。
● decodeFirstFrame - 是否解码并显示视频的第一帧。用于设置画布大小并将框架用作“海报”图像。这在使用自动播放或流媒体源时无效。默认为真。
● maxAudioLag – 流式传输时,排队的最大音频长度(以秒为单位)。
● videoBufferSize – 流式传输时,大小 视频解码缓冲区的字节数。 默认 5121024 (512kb)。 对于非常高的比特率,您可能必须增加此值。
● audioBufferSize – 流式传输时,音频解码缓冲区的大小(以字节为单位)。 默认 128*1024 (128kb)。 对于非常高的比特率,您可能必须增加此值。
● onVideoDecode(decoder, time) – 在每个解码和渲染的视频帧之后调用的回调
● onAudioDecode(decoder, time) – 在每个解码的音频帧之后调用的回调
● onPlay(player) – 播放开始时调用的回调
● onPause(player) – 播放暂停时调用的回调(例如,当调用 .pause() 或源结束时)
● onEnded(player) – 播放到达源末尾时调用的回调(仅在循环为 false 时调用)。
● onStalled(player) – 当没有足够的数据播放时调用的回调
● onSourceEstablished(source) – 当源第一次收到数据时调用的回调
● onSourceCompleted(source) - 一个 当源接收到所有数据时调用的回调
// index.html文件中
<script type="text/javascript" src="https://jsmpeg.com/jsmpeg.min.js"></script>
// index.jsx文件中
import React, { useEffect } from "react";
import styles from "./index.module.less";
const JSMpegCom = () => {
useEffect(() => {
const video = document.getElementById("video");
const url = "ws://" + document.location.hostname + ":9998/";
const player = new window.JSMpeg.Player(url, {
canvas: video,
disableWebAssembly: true,
disableGl: true,
autoplay: true,
loop: true
});
player.play();
}, []);
return (
<div className={styles["containers"]}>
<h1>视频直播</h1>
<canvas id="video" className={styles["video"]}>
事实上
</canvas>
</div>
);
};
export default JSMpegCom;
二、node服务端
流式传输任何RTSP流并输出到websocket以供jempeg使用。HTML5流媒体视频(需要ffmpeg)
// server.js
const Stream = require("node-rtsp-stream");
// 设置rtsp视频流地址
const rtsp_urls =
"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
const streams = new Stream({
name: "sockets",
streamUrl: rtsp_urls,
wsPort: 9998,
ffmpegOptions: {
// 选项ffmpeg标志
"-stats": "", // 没有必要值的选项使用空字符串
"-r": 30 // 具有必需值的选项指定键后面的值<br> '-s':'1920*1080'
}
});
执行服务:
node server.js
三、demo效果
GitHub上传了demo仓库地址:https://github.com/coco723/blog/issues/12