npm install express express-ws fluent-ffmpeg websocket-stream -S -D
其中setFfmpegPath这里是指明了ffmpeg的安装路径,如果没有安装,请看第4点
var express = require("express"); var expressWebSocket = require("express-ws"); var ffmpeg = require("fluent-ffmpeg"); ffmpeg.setFfmpegPath("D:/ffmpeg-20191031-7c872df-win64-static/ffmpeg-20191031-7c872df-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("copy").noAudio().pipe(stream); } catch (error) { console.log(error); } } localServer();video标签中的muted属性,是因为在视频流加载好之后,autoplay属性无法自动播放,加上这个属性后就可以实现了
<template> <div> <video class="demo-video" ref="player" muted autoplay></video> </div> </template> <script> import flvjs from "flv.js"; export default { data () { return { id: "1", rtsp: "rtsp://admin:12345@192.168.0.101:554/h264/ch1/main/av_stream", player: null } }, mounted () { if (flvjs.isSupported()) { let video = this.$refs.player; if (video) { this.player = flvjs.createPlayer({ type: "flv", isLive: true, url: `ws://localhost:8888/rtsp/${this.id}/?url=${this.rtsp}` }); this.player.attachMediaElement(video); try { this.player.load(); this.player.play(); } catch (error) { console.log(error); }; } // if (video) { // this.player = flvjs.createPlayer({ // type: "flv", // url: `/static/test.flv` // }); // this.player.attachMediaElement(video); // try { // this.player.load(); // this.player.play(); // } catch (error) { // console.log(error); // }; // } } }, beforeDestroy () { this.player.destory(); } } </script> <style> .demo-video { max-width: 880px; max-height: 660px; } </style>