Skip to content

Commit

Permalink
Update video.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lily0325 committed Jan 14, 2025
1 parent 1babb2e commit 17b1322
Showing 1 changed file with 122 additions and 1 deletion.
123 changes: 122 additions & 1 deletion docs/function/video.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

但是很多时候HLS直播链接不是这些第三方播放器都可以播放,需要自己一个一个使用这些第三方播放器demo测试是否可以播放。

### h265web.js
### 使用h265web.js库播放HLS视频流

比如最近项目有个视联设备摄像头的HLS直播链接使用上面这些第三方播放器都无法播放,最后使用了`h265web.js`这个第三方播放器才可以播放。

Expand Down Expand Up @@ -171,6 +171,127 @@ github地址:https://github.com/numberwolf/h265web.js

## RTSP前端浏览器播放

前端浏览器正常来说是无法直接播放RTSP视频流的,需要使用FFmpeg等工具将RTSP视频流转换成其他能够在前端播放的视频流格式,所以是没有纯前端的处理方法,除非是使用第三方的浏览器播放插件来使用。

可以将RTSP视频流通过FFmpeg转成rtmp,但是rtmp视频流基于flash才能播放,所以你的电脑必须安装flash,但是当前各大浏览器都准备不再支持flash,而且rtmp视频流播放还是具有2-3秒的延迟实现,所以不推荐使用。

主流的浏览器播放RTSP视频流的方式:

1. `使用FFmpeg和WebSocket`:

FFmpeg是一个强大的多媒体处理工具,可以将RTSP流转换为其他格式。

可以使用FFmpeg将RTSP流转换为MEPG-TS或DASH格式,然后通过WebSocket将转换后的流发送到浏览器。

浏览器端需要使用相应的播放器库来播放,例如JSMPEG。

2. `使用FFmpeg和WebRTC`:

WebRTC是一种实时通信技术,它允许浏览器之间进行实时音频、视频和数据传输。

可以使用WebRTC将RTSP流转换为浏览器可播放的格式,如VP8或VP9。

需要在服务器端进行转码和代理,将RTSP流转换为WebRTC流。


### 使用FFmpeg和WebSocket

#### 首先先下载FFMPEG

官方地址:https://ffmpeg.org/

不是安装包类型的,根据系统下载源码后,将其放到环境变量中,使其能够全局调用。

#### RTSP视频流转换成WebSocket

使用的是github开源的项目

https://github.com/xiaosen125/video

掘金地址:

https://juejin.cn/post/6844903949309313037?searchId=20240816191001FD5B207680FC9CA96B7D#heading-7

使用FFMPEG本地主码流转码的方式转换成mpeg-ts格式,前端通过websocket方式接收二进制流并在canvas中展示画面

复刻项目:https://gitee.com/lily0325/rtsp2web



#### 核心调用:

在项目的routes文件夹中的video.js文件中,`/play`地址的post请求接收前端传回来的用户ID与设备Code,通过这两个参数,获取到该设备真正的RTSP视频流地址。

开启一个子进程,将RTSP视频流通过FFMPEG转成mpeg-ts格式,然后通过websocket发送出去。

```JS
router.post('/play', async (req, res, next) => {
const { clientID, cameraID } = req.body;
try {
await updateRecord(clientID);
// 通过clientID和cameraID获取到设备的RTSP视频流地址
// ···
playStatic = await videoStream(rtspUrl, clientID, cameraID);
playStatic.startTransCodo();

res.status(200).send({ cameraID });
} catch (error) {
res.status(500).send({ error: '内部服务器错误' + error });
}
});

```

上述代码中的VideoStream类是一个封装好的类,其中的startTransCodo方法就是新建一个Mpeg1Muxer类的实例

这个Mpeg1Muxer类能够开启一个子进程,调用FFMPEG将RTSP视频流转换成mpeg-ts格式流,然后通过websocket发送出去,前端通过websocket接收到视频每一帧的二进制流,然后使用JSMPEG库在canvas中展示画面。

```JS
// 生成唯一ID
const clientID = uuid.v4();


// 播放实时视频
const transCodeApi = (data) => {
fetch("/rtspUrl/live/VnetPlay", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
})
.then((res) => res.json())
.then((res) => {
// 获取 id 为 video 的元素
const videoElement = document.getElementById("video");
// 创建一个新的 canvas 元素
const canvas = document.createElement("canvas");
canvas.id = "video-canvas";
canvas.width = videoElement.clientWidth;
// 清空 videoElement 原有的子元素,并添加新的 canvas 元素
videoElement.innerHTML = "";
videoElement.appendChild(canvas);

const url = `ws://localhost:8080/videoService/clientID=${clientID}&cameraID=${data.cameraCode}`;
// const canvas_doc = document.getElementById("video-canvas");
player = new JSMpeg.Player(url, {
canvas: canvas,
videoBufferSize: 1024 * 1024 * 100,
pauseWhenHidden: false, // 标签页处于非活动状态时是否暂停播放
onPlay: function () {
console.log("onPlay");
},
onEnded: function () {
console.log("onEnded");
},
});
})
.catch((err) => {
autolog.log("设备直播流请求失败!", "error", 2500);
});
};


// 调用
await transCodeApi({ clientID, cameraCode: val });
```

0 comments on commit 17b1322

Please sign in to comment.