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,流媒体

流媒体不是一种新的媒体,而是一种信息传达技术,与传统传达技术主要区别就是播放终端。流媒体技术可以在不下载信息,比如声音,视频,以及多媒体信息,的情况下直接通过缓冲观看。也就是你不用下载音乐或视频,或者用一个磁带之类的载体。



作者:二斗豆子
链接:https://www.zhihu.com/question/20906684/answer/908577649
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考文章:

[1] 使用bilibili开源的flvjs实现摄像头rtsp视频直播_一只程序媛-CSDN博客_bilibili flv.js

[2] 使用flv.js + websokect播放rtsp格式视频流 - 骄阳似我_lq - 博客园

[3] HTML5 播放 RTSP 视频 - 知乎

GitHub 加速计划 / fl / flv.js
22.86 K
3.38 K
下载
HTML5 FLV Player
最近提交(Master分支:2 个月前 )
42343088 - 3 年前
3d9a5eaa This reverts commit 09982effa023e3bda8462b811caa5f47535e333f. 3 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐