实现摄像头的直播功能其实有许多方案,像是安装vlc插件、rtsp转rtmp然后使用videojs通过flash播放rtmp**(由于chrome已经不使用flash所以放弃使用videojs,并且videojs针对部分摄像机(比如:海康)不是很友好,作者大大也很久没有维护的原因,部分rtsp、rtmp流的视频直播是无法找到媒体的兼容源)** 以及hls .m3u8等方式
然而现今的浏览器对于vlc插件几乎都不再支持了,flash在2020年也将被chrome停止支持,而.m3u8的方案用来做直播的话似乎延迟很高
经过一番查找,最终决定使用B站(bilibili)开源的flvjs作为解决方案,其原理是后端用ffmpeg(服务器先安装ffmpeg)将rtsp视频流转换为flv,然后通过websocket传输flv视频流,然后前端通过websocket获取到视频流后,使用flvjs对视频流再一次处理并进行播放,这是一套无插件无flash免费的视频直播解决方案。

  1. vlc下载地址(https://www.stellarplayer.com/?chan=sem_02&bd_vid=11500080128163536149

安装完后点击-媒体->打开网络串流->
在这里插入图片描述
如果不能进行观看直播,下面可以放弃了

  1. 安装ffmpeg(windows为实例)
    ffmpeg官网http://www.ffmpeg.org/download.html
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210318111603374.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhaWR1XzQxODAzODg4,size_16,color_FFFFFF,t_7
    在这里插入图片描述
    下载完后配置坏境变量
    在这里插入图片描述
    FFMPEG_HOME
    D:\ffmpeg\ffmpeg-4.3.2-2021-02-27-essentials_build\bin

再去path指定变量%FFMPEG_HOME%

最后通过cmd窗口ffmpeg -version命令来查看是否安装成功

  1. 安装node(https://www.html.cn/qa/node-js/10701.html

  2. 通过npm安装第三方依赖

 npm install express express-ws fluent-ffmpeg websocket-stream -S -D 

服务器执行

  1. 编写index.js(这个js需要通过node启动,启动命令(直接在js的目录下):node index.js,并且此js作为websocket传输流)

其中setFfmpegPath为ffmpeg的安装路径,并且值为ffmpeg安装路径的bin/ffmpeg

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();

前端vue

<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: "",
            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>
Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐