Home

Awesome

Logo wsPlayer

​ wsPlayer是一款专注于WebSocket-fmp4协议的web视频播放器,HTTP/WebSocket-fmp4协议与RTMP、HLS、HTTP-FLV相比,具有播放延时短,HTML5兼容性好等优点;

见各流媒体协议对比:

协议名称网络传输协议延时编码类型HTML5支持情况
RTSPTCP/UDP/组播0~3sH264/H265不支持,(RTSP over HTTP除外)
RTMPTCP0~3sH264/H265(CodecID =12)不支持
HLSHTTP短连接1~10sH264/H265video标签支持
HTTP-FLVHTTP长连接0~3sH264/H265(CodecID =12)flv → fmp4 → video标签
HTTP-fmp4HTTP长连接0~3sH264/H265video标签原生支持
WebSocket-FLVWebSocket0~3sH264/H265(CodecID =12)flv → fmp4 → video标签
WebSocket-fmp4WebSocket0~3sH264/H265使用MSE,vidoe标签播放

备注:浏览器对单个页面的HTTP长连接的并发数限制为6个,这意味着HTTP-FLV、HTTP-fmp4只能同时播放6个视频画面;但浏览器对WebSocket的连接数没有限制;

项目依赖

需要使用mp4box.js来解析fmp4 moov中的codecs;

快速开始

推荐使用ZLMediaKit作为WebSocket-fmp4协议的后端流媒体服务器

  1. 部署后端流媒体服务器
docker pull panjjo/zlmediakit
docker run -id -p 8080:80 -p 554:554 panjjo/zlmediakit
  1. 使用ffmpeg命令,向ZLMediaKit添加一路RTSP推流
ffmpeg -re -stream_loop -1 -i test.mp4 -an -vcodec copy -f rtsp -rtsp_transport tcp rtsp://100.100.154.29/live/test
  1. 根据ZLMediaKit的播放url规则得知,WebSocket-fmp4协议的URL格式为:
ws://100.100.154.29:8080/live/test.live.mp4
  1. 然后调用播放器代码:
<html>
<head>
</head>
<body>
    <script type="text/javascript" src="mp4box.all.min.js"></script>
    <script type="text/javascript" src="wsPlayer.js"></script>
    <video muted autoplay id="video"></video>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            var player = new wsPlayer("video", "ws://100.100.154.29:8083/live/test.live.mp4");
            player.open();
        });
    </script>
</body>
</html>

5. magic-videoplayer

原本打算起名wsplayer,但是wsplayer的项目名称在npm公共仓库中已经被使用,顾起名magic-videoplayer magic-videoplayer 基于 react 开发,支持主流的播放器功能 以及主流的视频格式和功能 以及判别视频文件属于哪类视频格式,支持多个播放器同步播放时间校正 #使用

#项目里使用

npm i magic-videoplayer --save
或
yarn add magic-videoplayer

Player 播放器

视频播放器

代码演示

import React, { useEffect, useState } from 'react';
import { Player } from 'magic-videoplayer';

const Play = () => {
  const [url, setUrl] = useState('');
  const [ref, setRef] = useState('');
  const [wsUrl, setWsUrl] = useState('');
  const [width, setWidth] = useState(700);

  return (
    <div>
      <div style={{ width }}>
        <Player
          url={url}
          onRef={(s) => {
            setRef(s);
          }}
          extra={<div style={{ color: '#fff', lineHeight: '30px' }}>额外按钮</div>}
          onPtzChange={(ptz) => {
            console.log(ptz, 'ptzchange');
          }}
          onError={() => {
            console.log('错误onerr');
          }}
          reconnection
          onPlay={(w, h, type) => {
            console.log({ w, h, type });
          }}
          emptyurlPrompt="请选择摄像头"
          onFullChange={(full) => {
            console.log(full);
          }}
        ></Player>
      </div>
    </div>
  );
};

export default () => <Play />;

API

参数说明类型默认值
url视频地址 直播为 ws 开头 片段为 http 开头<font color='#c41d7f'>string</font>-
onError播放错误时的回调<font color='#c41d7f'> ()=>void </font>-
onPlay直播流开始播放的回调<font color='#c41d7f'> (videoWidth: number, videoHeight: number,videoType:string) => void </font>-
autoPlay直播流是否自动播放<font color='#c41d7f'> boolean</font>true
reconnection是否开启断线重连<font color='#c41d7f'> boolean </font>false
onRef组件的 ref 引用<font color='#c41d7f'> (ref:any)=>void</font>-
extra控制台额外的标签<font color='#c41d7f'> ReactNode | (() => ReactNode) </font>-
videoClassvideo 暴露 class<font color='#c41d7f'> string </font>-
canvasClasscanvas 暴露 class<font color='#c41d7f'> string </font>-
screenshot是否显示截图按钮<font color='#c41d7f'>boolean</font>false
closeControlBar关闭底部控制栏(仅在直播流有效)<font color='#c41d7f'>boolean</font>false
banfullscreen禁止播放器全屏(仅在直播流有效)<font color='#c41d7f'>boolean</font>false
emptyurlPrompt播放地址为空时的提示内容<font color='#c41d7f'> string</font>-

播放器原理

​ 将WebSocket收到的fmp4 Segment片段appendBufferMediaSource中,此时video.buffered会记录当前已经appendBuffer的视频时间段,然后将video.buffered的起始时间设置给video.currentTime,然后浏览器就会从video.buffered缓存的视频开始播放

项目计划

联系方式