13 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务

前言

接上一篇文章 rtsp视频服务 转换为 rtmp服务 转换为前端可用的服务

继续讨论 前端播放 rtsp 视频服务  

rtsp视频服务 转换为 rtmp服务 转换为前端可用的服务 会使用到 ffmpeg 来实现 rtsp 服务转换为 rtmp 服务, nginx-http-flv 来实现 rtmp 服务转换为 http-flv 服务, 因此 前端可以直接播放视频 

这里使用 node 作为后台服务, 使用 ffmpeg 基于 websocket 协议将 rtsp 直接转换为 前端可用的 flv 视频数据 

我们这里 参考的代码来自于 GitHub - LorinHan/flvjs_test: 采用flvjs实现摄像头直播

主要包含一个 node 作为代理服务器, 加上一个测试的前端项目 

node 代理服务器 

index.js 如下, 代码来自于 GitHub - LorinHan/flvjs_test: 采用flvjs实现摄像头直播 中的 index.js,并做了一定的调整 

服务启动步骤如下 

npm install 
node index.js 

其中的主要处理为, 启动一个 websocket 服务器, 代理 以 "/rtsp" 打头的 websocket 请求, 然后获取查询字符串中的 url, 基于 ffmpeg 将 rtsp 视频数据转换为 flv 视频数据, 然后 响应回去 

ffmpeg -re -i $rtspUrl -rtsp_transport tcp -buffer_size 102400 -vcodec copy -an -f flv 
// 然后将转换之后的结果响应给 客户端
var express =  require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("ffmpeg");
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");

// config
let rtspServerPort = 9999

function localServer() {
    let app = express();
    app.use(express.static(__dirname));
    expressWebSocket(app, null, {
        perMessageDeflate: true
    });
    app.ws("/rtsp/:id/", rtspRequestHandle)
    app.listen(rtspServerPort);
    console.log("express listened on port : " + rtspServerPort)
}

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

测试的 HelloWorld.vue 

如下 rtsp 服务为 rtsp://localhost:8554/rtsp/test_rtsp 

创建一个 flvPlayer, 视频输入为 ws://localhost:9999/rtsp/xxx/?url=rtsp://localhost:8554/rtsp/test_rtsp 

然后 启动项目, 能够正常看到视频 即成功 

<template>
    <div class="video-wrapper">
        <video class="demo-video" ref="player" muted autoplay></video>
    </div>
</template>
<script>
import flvjs from "flv.js";
export default {
    data () {
        return {
          id: "xxx",
          rtsp: "rtsp://localhost:8554/rtsp/test_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:9999/rtsp/${this.id}/?url=${this.rtsp}`
                });
                this.player.attachMediaElement(video);
                try {
                    this.player.load();
                    this.player.play();
                } catch (error) {
                    console.log(error);
                }
            }
        }
    },
    beforeDestroy () {
        this.player.destory();
    }
}
</script>
<style>

	    .video-wrapper {
	        max-width: 880px;
	        max-height: 660px;
			border:1px solid red;
	    }
    .demo-video {
        max-width: 880px;
        max-height: 660px;
    }
</style>

测试页面展示效果如下 

FlvUsage.html 

也可以使用一个普通的 html 来进行测试 

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
  <!--  <script src="./js/flv.min.js"></script>-->
  <style>
    body, center {
      padding: 0;
      margin: 0;
    }

    .v-container {
      width: 640px;
      height: 360px;
      border: solid 1px red;
    }

    video {
      width: 100%;
      height: 100%;
    }
  </style>

</head>
<body>
<div class="v-container">

  <video id="player1" muted autoplay="autoplay" preload="auto" controls="controls">
  </video>

</div>

<script>
  if (flvjs.isSupported()) {
    var videoElement = document.getElementById('player1');
    var flvPlayer = flvjs.createPlayer({
      type: 'flv',
      url: 'ws://localhost:9999/rtsp/xxx/?url=rtsp://localhost:8554/rtsp/test_rtsp'
    });
    flvPlayer.attachMediaElement(videoElement);
    flvPlayer.load();
  }</script>

</body>
</html>

测试页面展示效果如下 

完 

猜你喜欢

转载自blog.csdn.net/u011039332/article/details/126732885