1?引言
在项目开发过程中经常需要接视频流。之前大都接的是HLS格式的流,这是Html5的video标签直接支持的。最近需要接rtsp流,web端目前不支持直接播放。本文提供一种方法直接播放rtsp流,不需要安装插件。
2? 基于flv.js的RTSP播放方案
HTML5 原生仅支持播放 mp4/webm 格式,是不支持 FLV格式的。 flash性能问题是长期以来被全世界人所诟病的,尤其是明年起chrome彻底抛弃flash,越来越多有直播需求的人产生焦虑。这就加速了html5播放器的发展,也使得人们对html5非插件式的播放器更加渴望。而flv.js就是这么一款可以利用html5的video标签将http-flv直播流实时播放的一个js版的播放器。
2.1 使用node构建服务器端
目录如下所示:
package.json
{
"name": "ffmpeg-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.17.1",
"express-ws": "^4.0.0",
"ffmpeg": "0.0.4",
"fluent-ffmpeg": "^2.1.2",
"http": "0.0.0",
"websocket-stream": "^5.5.0"
}
}
index2.js
var express = require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("G:/ffmpeg/ffmpeg/ffmpeg-4.3.1-win64-static/bin/ffmpeg");
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");
function localServer() {
let app = express();
app.use(express.static(__dirname));
expressWebSocket(app, null, {
perMessageDeflate: true
});
app.ws("/rtsp/:id/", rtspRequestHandle)
app.listen(8888);
console.log("express listened")
}
function rtspRequestHandle(ws, req) {
console.log("rtsp request handle");
const stream = webSocketStream(ws, {
binary: true,
browserBufferTimeout: 1000000
}, {
browserBufferTimeout: 1000000
});
let url = req.query.url;
// console.log("rtsp url:", url);
// console.log("rtsp params:", req.params);
try {
ffmpeg(url)
.addInputOption("-rtsp_transport", "tcp", "-buffer_size", "102400") // 这里可以添加一些 RTSP 优化的参数
.on("start", function () {
console.log(url, "Stream started.");
})
.on("codecData", function () {
console.log(url, "Stream codecData.")
// 摄像机在线处理
})
.on("error", function (err) {
console.log(url, "An error occured: ", err.message);
})
.on("end", function () {
console.log(url, "Stream end!");
// 摄像机断线的处理
})
.outputFormat("flv").videoCodec("libx264").noAudio().pipe(stream);
} catch (error) {
console.log(error);
}
}
localServer();
直接启动:
2.2 客户端
前端要安装flv.js,执行 npm install flv.js -S -D
<template>
<div class="video-box">
<video controls="controls" class="demo-video" ref="player" muted @dblclick="fullScreen"></video>
</div>
</template>
<script>
import flvjs from 'flv.js'
export default {
name: 'Home',
components: {},
data () {
return {
player: null,
loading: true
}
},
mounted () {
this.playVideo()
},
watch: {
rtsp: {
handler: function (val) {
if (val) {
if (this.player) {
this.player.unload()
this.player.destroy()
this.player = null
this.loading = true
}
this.$nextTick(() => {
this.playVideo()
})
}
},
immediate: true
}
},
methods: {
fullScreen () {
if (this.$refs.player.requestFullScreen) {
this.$refs.player.requestFullScreen()
} else if (this.$refs.player.mozRequestFullScreen) {
this.$refs.player.mozRequestFullScreen()
} else if (this.$refs.player.webkitRequestFullScreen) {
this.$refs.player.webkitRequestFullScreen()
}
},
playVideo () {
const time1 = new Date().getTime()
if (flvjs.isSupported()) {
let video = this.$refs.player
if (video) {
this.player = flvjs.createPlayer({
type: 'flv',
isLive: true,
url: `ws://192.168.80.49:8888/rtsp/id123?url=rtsp://192.168.80.49:8554/mystream`
})
this.player.attachMediaElement(video)
try {
this.player.load()
this.player.play().then(() => {
console.log(new Date().getTime() - time1)
this.loading = false
})
} catch (error) {
console.log(error)
}
}
}
}
},
beforeDestroy () {
if (this.player) {
this.player.unload()
this.player.destroy()
this.player = null
}
}
}
</script>
<style>
.video-box {
width: 100%;
height: 100%;
}
video {
width: 100%;
height: 100%;
object-fit: fill;
}
video::-webkit-media-controls-play-button {
display: none;
}
video::-webkit-media-controls-current-time-display {
display: none;
}
video::-webkit-media-controls-timeline {
display: none;
}
</style>
参考文章:
[1]?使用bilibili开源的flvjs实现摄像头rtsp视频直播_一只程序媛-CSDN博客_bilibili flv.js
[2]?使用flv.js + websokect播放rtsp格式视频流 - 骄阳似我_lq - 博客园
[3]?HTML5 播放 RTSP 视频 - 知乎
|