2023年12月29日 22:42
原创作品,转载时请务必以超链接形式标明文章原始出处,否则将追究法律责任。

好久没进山了,上次进山还是去的白石峪,逛完山下吃了个建基泡馍。话说建基泡馍味道也没有想象中的那么好,左边是沣河马王街道桥头的永信一泡馍,右边是长安县的建基泡馍。说实话味道都差不多,肉量也差不多,但是建基给我的印象不好,端上来感觉卖相不行,凌乱的感觉,永信一则是整整齐齐。价格永信一便宜2元,好不好大家自己看,有些游客来西安花了三十五吃了一碗泡馍也就是薄薄两片肉,而下面这两个泡馍不高于26。

image.png

看完泡馍,我们进入正题,在这里我就不得不说一下现在的国内技术网站和搜索引擎。尼玛百度搜索出来都是一堆没用的东西,同一个问题重复率高达70%,是00后都不爱写技术文章了吗。CSDN尼玛看一篇文章你还要收钱,想钱想疯了吧,总的觉得国内技术站成了毛线了,博客园尼玛都不行了。

进入正题,今天主要实现从服务端拉取监控视频流,再将视频在html页面播放,视频格式是rtsp格式。由于这种格式不能被浏览器直接识别,因此无法直接播放。所以我们需要对rtsp格式的视频进行转码,比如转成flv,mp4,mov格式。具体的实现细节我们看一下。

  1. 首先因为我们在本地模拟一个rtsp推流过程,这部分我们要借助于VLC Media Player播放器

    • 下载VLC Merdia Player播放器并安装
      image.png

    • 打开媒体菜单,点击流
      image.png

    • 点击添加按钮,添加一个mp4视频文件,点击串流按钮
      image.png

    • 接着进入到如下界面
      image.png

    • 点击下一个,在弹出界面选择RTSP
      image.png

    • 点击添加按钮,弹出如下界面,端口8554,路径我们命名为testpol
      image.png

    • 然后点击下一个,弹出如下界面,勾选激活转码,配置文件选择TS
      image.png

    • 点击下一个,弹出如下界面,此时我们需要把本机IP补进去,默认这里是没有ip的。
      image.png

    • 然后点击流,就完成了模拟推流,我们设置循环以后可以看到一直在循环推流
      image.png

    • OK,推的流到底能不能播放,我们再打开一个VLC播放器,点击菜单打开网络串流
      image.png

    • 在弹出的界面输入串流地址rtsp://192.168.0.106:8554/testpol
      image.png

    • 点击播放,效果如下,此时证明我们推的流没有问题。
      image.png

  2. 接下来我们要在google浏览器播放这个视频,因为浏览器不能像VLC播放器一样去转码,所以我们只能通过ffmpeg工具去转码,转成flv或者mp4等浏览器能够播放的格式。所以我们需要一台服务器,安装ffmpeg,安装node.js,在这里我们就把自己机器当成服务器,客户端服务端就只有自己的这台机器。

    • 第一步,ffmepg安装,可以去官网下载,https://ffmpeg.org//download.html#build-windows
      image.png
      下载ffmpeg-release-full.7z压缩包
      image.png
      下载完成后解压,bin目录包含三个exe文件
      image.png
      这三个工具网上都有介绍,我就不再赘述,我们主要关注ffmpeg这个视频转码处理工具。ok,解压完成我们需要将bin目录配置到环境变量
      image.png至此ffmpeg就安装好了。

    • 第二步,开发node.js后端服务,这个服务主要是调用ffmpeg对流进行转码,转成flv格式

      • 第一步,选择开发工具,作为一名.net程序员,必须选择visual studio,确保vs安装了node.js开发包
        image.png

      • 安装好以后我们创建一个express项目
        image.png

      • 创建出来的项目是这样的
        image.png
        安装的npm包,vs很简单,直接在npm上右键搜索安装即可
        image.png

      • 我们打开app.js文件,在端口监听完以后加入如下代码,启动Websocket,监听8888端口,并创建ffmpeg引用。当客户端和websocket建立连接以后,会触发connection事件,下面的代码就是拿到rtsp流地址,然后转成flv格式返回给客户端。这里的req.url.slice(1)就是我们模拟的串流地址rtsp://192.168.0.106:8554/testpol。

      • var server = app.listen(app.get('port'), function () {
            debug('Express server listening on port ' + server.address().port);
            console.log('Express server listening on port');
        });
        const WebSocket = require('ws');
        const wss = new WebSocket.Server({ port: 8888, perMessageDeflate: false })
        var webSocketStream = require('websocket-stream/stream');
        const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
        const ffmpeg = require('fluent-ffmpeg');
        ffmpeg.setFfmpegPath(ffmpegPath);
        
        wss.on('connection', handleConnection)
        
        function handleConnection(ws, req) {
            console.log(req);
            const url = req.url.slice(1);
            const stream = webSocketStream(ws, { binary: true });
            const ffmpegCommand = ffmpeg(url)
                .addInputOption('-analyzeduration', '100000', '-max_delay', '1000000')
                .on('start', function () { console.log('Stream started.') })
                .on('codecData', function () { console.log('Stream codecData.') })
                .on('error', function (err) {
                    console.log('An error occured: ', err.message)
                    stream.end()
                })
                .on('end', function () {
                    console.log('Stream end!')
                    stream.end()
                })
                .outputFormat('flv').videoCodec('copy').noAudio()
        
            stream.on('close', function () {
                ffmpegCommand.kill('SIGKILL')
            })
        
            try {
                ffmpegCommand.pipe(stream)
            } catch (error) {
                console.log(error)
            }
        }
      • OK,至此服务端就编辑好了,我们把他启动起来
        image.png
        如果黑窗口没有报错,并且Express浏览器运行出默认页面,证明node.js服务运行正常
        image.png

    • 第三步,开发客户端,客户端使用VUE2,开发工具hbuilder。这里使用html5原生的video去播放,因为服务端我们把rtsp流转成了flv,所以我们需要安装flvjs插件来播放。具体代码如下|

      • 首先html中添加一个video

      • <video ref="videoPlay" muted style="width: 1000px;height: 400px;background-color: red;" autoplay controls>
        </video>
      • 接着我们npm install flv.js,js代码如下

        import flvjs from 'flv.js';
        mounted() {
            if (flvjs.isSupported()) {
              const url = 'rtsp://192.168.0.106:8554/testpol'
              this.player = flvjs.createPlayer({
                type: 'flv',
                isLive: true,
                url: 'ws://192.168.0.106:8888/' + url
              })
              
              this.player.on('error', (e) => {
                console.log(e)
              })
              
              this.player.attachMediaElement(this.$refs.videoPlay)
              
              try {
                this.player.load()
                this.player.play()
              } catch (error) {
                console.log(error)
              }  
            }
        },


    • OK,将客户端跑起来,此时我们发现服务端已经开始转码
      image.png

    • 服务端转码成功,客户端播放一定成功
      image.png

  3. OK至此整个流程全部结束,希望对大家有参考意义,而不是百度上那些250写的误人子弟的文章。

发表评论
匿名  
用户评论

匿名游客

2024年01月01日 23:37
你这篇文章无敌了,赞一个