前端在瀏覽器顯示攝像頭傳回的RTSP影片流,前端採用的技術有VUE+video.js+flv.js

鼓舞飞扬發表於2024-04-23

在前端使用Vue.js框架,結合video.js和flv.js播放RTSP影片流,需要經過一系列步驟,因為瀏覽器並不能直接播放RTSP流,所以通常需要一個伺服器來將RTSP流轉為HLS或FLV格式,然後前端再透過flv.js播放。以下是一個基於此思路的基本實現指南:

確保你已經安裝了Vue.js、video.js、flv.js相關的依賴。

npm install video.js flv.js --save

Vue元件實現

下面是一個簡單的Vue元件示例,演示如何整合video.js和flv.js來播放轉換後的FLV影片流。

<template>
  <div>
    <video ref="videoPlayer" class="video-js vjs-big-play-centered" controls></video>
  </div>
</template>

<script>
import videojs from "video.js";
import "video.js/dist/video-js.css";
import flvjs from "flv.js";

export default {
  name: "FlvPlayer",
  data() {
    return {
      player: null,
    };
  },
  mounted() {
    this.initPlayer();
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose();
    }
  },
  methods: {
    initPlayer() {
      // 假設你已經有了一個HTTP-FLV的地址,該地址是由後端服務提供的,將RTSP流轉換為FLV格式
      const streamUrl = "http://your-server-address/stream.flv";
      
      // 初始化video.js播放器
      this.player = videojs(this.$refs.videoPlayer, {}, function() {
        // 當player ready後,初始化flv.js外掛
        this.on("ready", () => {
          // 檢查flv.js是否支援當前環境
          if (flvjs.isSupported()) {
            const tech = flvjs.getTech('Flvjs');
            this.src({
              type: 'application/x-flv',
              src: streamUrl,
            });
            this.tech_.el_.addEventListener('loadstart', function() {
              flvjs.createPlayer({
                type: 'flv',
                url: streamUrl,
              }).attachMediaElement(this.media()).load();
            });
          } else {
            console.error("flv.js is not supported in this browser.");
          }
        });
      });
    },
  },
};
</script>

<style>
/* 可以在這裡新增自定義樣式 */
</style>

注意事項

  • 你需要有一個後端服務將RTSP流轉換為FLV或HLS流。常用的工具有Node.js的flv.js伺服器、ffmpeg等。
  • 程式碼中的streamUrl應替換為你的實際流媒體地址。
  • flv.js不支援Safari瀏覽器,對於需要廣泛相容的專案,可能需要考慮其他方案或回退機制。
  • 確保你的伺服器配置支援跨域訪問,因為前端播放器可能跨域請求影片流。

以上程式碼提供了一個基礎框架,實際應用中可能需要根據具體需求和環境進行調整。

如果streamUrl從後端獲取,並隔一段時間推送一次呢?

如果streamUrl需要從後端動態獲取,並且這個URL可能會隨著時間推移而變化(例如,每隔一段時間後端推送新的流地址),你可以採用Vue的響應式特性以及WebSocket或輪詢的方式來動態更新影片流地址。下面是一個簡化版的實現思路:

使用WebSocket接收實時更新

  1. 安裝WebSocket客戶端庫: 首先,確保你的專案中安裝了WebSocket客戶端庫,如socket.io-clientnpm install socket.io-client

  2. 建立WebSocket連線: 在Vue元件中建立與後端的WebSocket連線,並設定訊息監聽器來接收新的streamUrl

import io from "socket.io-client";

data() {
  return {
    player: null,
    streamUrl: '', // 初始化為空或預設值
    socket: null, // 用於存放WebSocket例項
  };
},
mounted() {
  this.initWebSocket();
  this.initPlayer();
},
methods: {
  initWebSocket() {
    this.socket = io("http://your-backend-url"); // 替換為你的後端WebSocket伺服器地址
    this.socket.on("newStreamUrl", (newUrl) => {
      console.log("New stream URL received:", newUrl);
      this.streamUrl = newUrl;
      // 當收到新的URL時,重新設定播放器的源
      if (this.player && this.player.src) {
        this.player.src({
          type: 'application/x-flv',
          src: this.streamUrl,
        });
        // 重新載入播放器
        this.player.load();
        // 如果需要,還可以在這裡呼叫play()方法開始播放
      }
    });
  },
  
  // ...其他程式碼保持不變
},
beforeDestroy() {
  // 清理WebSocket連線
  if (this.socket) {
    this.socket.disconnect();
  }
  // ...其他清理工作
}

使用定時輪詢

如果WebSocket不可行,你也可以使用定時輪詢的方式從後端獲取新的streamUrl。這種方式較為簡單,但不夠實時,且可能會增加伺服器負擔。

data() {
  return {
    // ...其他資料屬性
    pollInterval: null, // 用於儲存輪詢定時器
  };
},
mounted() {
  this.pollStreamUrl(); // 啟動輪詢
},
methods: {
  async pollStreamUrl() {
    try {
      const response = await axios.get("/api/getStreamUrl"); // 假設這是獲取新streamUrl的API
      if (response.data && response.data.streamUrl !== this.streamUrl) {
        this.streamUrl = response.data.streamUrl;
        // 更新播放器的源,同WebSocket部分的處理
        if (this.player) {
          this.player.src({
            type: 'application/x-flv',
            src: this.streamUrl,
          });
          this.player.load();
        }
      }
    } catch (error) {
      console.error("Error fetching stream URL:", error);
    }
    // 設定下一次輪詢
    this.pollInterval = setTimeout(() => this.pollStreamUrl(), 5000); // 每5秒檢查一次
  },
  
  // ...其他程式碼保持不變
},
beforeDestroy() {
  // 清除輪詢定時器
  if (this.pollInterval) {
    clearTimeout(this.pollInterval);
  }
  // ...其他清理工作
}

以上兩種方法分別展示了使用WebSocket實時接收新流地址和定時輪詢獲取流地址的實現思路。根據你的具體需求和後端支援情況選擇合適的方案。

 

相關文章