JSMpeg视频直播demo实践

4,512 阅读4分钟

技术栈

  • JSMpeg
  • node服务端
  • node包:node-rtsp-stream
  • mac环境安装ffmpeg(brew install ffmpeg)

一、JSMpeg

1. 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>

2. 用法

可以使用容器的CSS类jsmpeg在HTML中创建JSMpeg视频播放器

<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 - 使用渐进式时,一次加载的块大小(以字节为单位)。默认 1024*1024 (1mb)。
  • decodeFirstFrame - 是否解码并显示视频的第一帧。用于设置画布大小并将框架用作“海报”图像。这在使用自动播放或流媒体源时无效。默认为真。
  • maxAudioLag – 流式传输时,排队的最大音频长度(以秒为单位)。
  • videoBufferSize – 流式传输时,大小 视频解码缓冲区的字节数。 默认 512*1024 (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) - 一个 当源接收到所有数据时调用的回调

3. demo实践

  1. HTML文件中
// index.html文件中
<script type="text/javascript" src="https://jsmpeg.com/jsmpeg.min.js"></script>
  1. 实现
// 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仓库地址:github.com/coco723/blo…