前端如何實現整套視頻直播技術流程

目錄大綱:

  1. 直播技術的簡單介紹
  2. 前端搭建使用的技術
  3. 實踐效果
  4. 後續需要深入的地方

簡介:

首先說明,本篇文章是概念+實踐,對於希望瞭解和實踐一個簡單的攝像頭直播網頁功能的人會有幫助,由於篇幅和實踐深入度有限,目前demo效果只支持直播播放電腦端以及常用攝像頭的實時視頻流,其他複雜的功能(例如視頻信息實時處理,高併發,網絡分發等)尚未實現,還需要進一步探索。

下面按照目錄大綱來一個一個講解:

1. 直播技術的介紹

直播技術涵蓋很廣,現如今大家廣泛瞭解的就有視頻網站的個人直播、手機直播、安防方面的攝像頭監控等會使用到直播的技術;

下面先出一張概念圖,介紹直播流程中的各個技術環節。可以理解分為採集端、流媒體服務器以及播放端;還需要了解什麼是推流,什麼是拉流。

前端如何實現整套視頻直播技術流程

  • 採集端:顧名思義是視頻的源頭,視頻的採集一般都是從真實的攝像頭中得到的。例如移動端設別、PC端設備的攝像頭以及一些攝像頭設備
  • 流媒體服務器:流媒體服務器是整個直播技術框架的非常重要的一環,它需要接收從採集端推上來的視頻流,然後將該視頻流再推送到播放端
  • 播放端:播放端就是各種app,網頁中的播放器,拉取流媒體服務器上的視頻流,然後進行轉碼,最終播放出來
  • 推流:把採集階段收集的數據封裝好傳輸到服務器的過程
  • 拉流:服務器已有直播內容,用指定地址進行拉去的過程

既然需要推流和拉流, 就必然涉及到視頻流的傳輸,所以接下來介紹常用的流媒體傳輸協議 常用的流媒體傳輸協議有RTMP,RTSP,HLS,HTTP-FLV

  • RTMP:(可用於推流端和拉流端) Real Time Messaging Protocol 實時消息傳輸協議,RTMP協議中,視頻必須是H264編碼,音頻必須是AAC或MP3編碼,且多以flv格式封包。因為RTMP協議傳輸的基本是FLV格式的流文件,必須使用flash播放器才能播放.
  • RTSP:(用於推流端) Real-Time Stream Protocol,RTSP 實時效果非常好,適合視頻聊天、視頻監控等方向
  • HLS(用於拉流端) Http Live Streaming,由Apple公司定義的基於HTTP的流媒體實時傳輸協議。傳輸內容包括兩部分:1.M3U8描述文件,2.TS媒體文件。TS媒體文件中的視頻必須是H264編碼,音頻必須是AAC或MP3編碼。數據通過HTTP協議傳輸。目前video.js庫支持該格式文件的播放
  • HTTP-FLV(用於拉流端) 本協議就是http+flv,將音視頻數據封裝成FLV格式,然後通過http協議傳輸到客戶端,這個協議大大方便了瀏覽器客戶端播放直播視頻流.目前flv.js庫支持該格式的文件播放

有了以上基本概念之後,我們就大致知道要搭建一個擁有直播功能的頁面需要哪些東西了,下面就基於這個架構進行各個部分的實現

2. 前端搭建使用的技術

  • 搭建流媒體服務

提到流媒體服務器,其實作為開發前端的人來說,本人一開始也是無所適從的,不知道這個東西該怎麼實現或者要用什麼語言去寫.首先想到的肯定是搜索現有的實現技術,看看是否能夠通過純前端去實現,純JS技術的話,肯定首先想到了node.js,於是就使用node.js+視頻流媒體技術實現方案的關鍵詞去搜索,獲得了一個看著比較靠譜的結果:NodeMediaServer,然後去看介紹發現是基於node去實現的一個開源的流媒體服務器,雖然最新版本已經使用go去重構了,但是畢竟歷史上它是由node來開發的,所以決定看文檔試一試搭建一個這樣的服務器.NodeMediaServer官網:

http://www.nodemedia.cn/

NodeMediaServer支持:以rtmp,rtsp,hls協議拉進行推流,支持http-flv,ws-flv來進行拉流,也就是支持瀏覽器端使用http或websocket傳輸flv格式的視頻流進行播放

開始搭建流媒體服務器:

  • 下載對應的安裝包,使用的Linux環境

下載:

<code>wget https://cdn.nodemedia.cn/nms/3.2.12/nms-linux-amd64-20200222.tar.gz /<code>

解壓:

<code>tar -zxvf nms-linux-amd64-20200222.tar.gz/<code>

到解壓後的目錄下,執行命令,啟動服務

  • 在控制檯輸入 ./nms運行
  • 在當前程序目錄下執行 sudo ./service.sh install 安裝服務並自動運行
  • 在當前程序目錄下執行 sudo ./service.sh uninstall 停止並卸載服務

服務成功啟動之後,可以在8000端口(默認端口)訪問流媒體服務的後臺系統,這裡面大概長下面這個樣子:

前端如何實現整套視頻直播技術流程

首頁dashboard展示了服務器cpu的使用情況以及網絡帶寬狀況

  • 服務啟動之後,接下來要做的是推流

怎麼推流?這裡涉及到一個很強大的東西ffmpeg,它是可以用來記錄、轉換數字音視頻,並將其轉化為流的開源軟件,通過它可以進行視頻的採集封裝成流,並推送到流媒體服務器,例如在mac上面安裝了這個軟件之後,可以通過它調用攝像頭,並將攝像頭數據封裝成流後推送到流媒體服務器,這個過程就是推流.ffmpeg還可以推送本地的視頻文件到流媒體服務器.


使用ffmpeg進行mac本地攝像頭實時推流到nodeMediaServer:

<code>ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -i 0:0 -vcodec libx264 -preset veryfast -f flv http://ip:8000/live/stream.flv 複製代碼/<code>

這裡涉及到ffmpeg工具,上面的參數不逐一解釋,只是最重要的幾個:

  • -vide_size 表示要輸出的視頻畫面的分辨率尺寸
  • -f 後面的參數 flv表述輸出的格式,再後面的地址 http://ip:8000/live/stream.flv 表示想要輸出的地址,這個地址的stream.flv可以按照自己需求隨意修改,保持後綴是你需要的flv格式即可

另外一種常用的場景是直接拉去攝像頭設備中的視頻流數據,這種方式,nodeMediaServer也支持,只需要在管理後臺配置對應的攝像頭的配置信息,就可以進行推流操作了.這些配置信息包括ip,登錄用戶名和密碼等,配置界面如下所示:

預設配置:

前端如何實現整套視頻直播技術流程

還可以自定義設定配置,如果使用的是自定義的攝像頭,具備rtsp傳輸功能的,就可以使用西面的配置方式進行攝像頭信息的配置,指定輸出流地址,這樣直接從瀏覽器端就可以通過這個輸出流地址進行視頻的播放:

前端如何實現整套視頻直播技術流程

  • 前端頁面支持播放視頻流

前端頁面部分,首要目標是找到支持http-flv和ws-flv協議格式的前端播放器,首先去觀察了B站的直播,發現他們的直播頁面是使用的video標籤,後來進一步發掘,才知道他們用的是自己開源的flv.js庫,這是一個支持在瀏覽器端進行http-flv及ws-flv格式的視頻流進行播放的播放器,正好是播放直播視頻流需要的

視頻流有了,那麼就可以使用flv.js來搭建頁面demo,查看實際效果了

3. 實踐效果

  • 首先搞定推流:

分別實驗了直接從mac上推攝像頭的視頻流數據以及綁定攝像頭設備地址信息,通過nodeMediaServer進行推流和拉流服務.

  • 然後是前端頁面進行視頻流的播放,下面是播放器部分的核心代碼:

live-demo.js

<code>import * as React from 'react';

import { Button, Input, Row, Col } from 'react-x-component';
import flv from 'flv.js';

const { useState, useEffect } = React;

interface LiveDemoProps {
defaultUrl?: string,
onUrlChange?: Function
}

export default function LiveDemo({ defaultUrl = 'http://ip:8000/live/stream.flv', onUrlChange }: LiveDemoProps) {

let player = null;
let playerDom = null;

const [liveUrl, setLiveUrl] = useState(defaultUrl);

useEffect(() => {
if (flv.isSupported) {
player = flv.createPlayer({
type: 'flv',
isLive: true,

hasAudio: false,
hasVideo: true,
url: liveUrl,
cors: true
}, {
enableWorker: false,
lazyLoadMaxDuration: 3 * 60,
seekType: 'range'
});
player.attachMediaElement(playerDom);
player.load();

} else {
console.log('Your browser is not support flv.js');
}
}, []);

function updatePlayer() {
if (player) {
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}

player = flv.createPlayer({
type: 'flv',
isLive: true,
hasAudio: false,
hasVideo: true,
url: liveUrl,
cors: true
}, {
enableWorker: false,
lazyLoadMaxDuration: 3 * 60,
seekType: 'range'
});
player.attachMediaElement(playerDom);
player.load();
}

return (




value={liveUrl}
onChange={(value) => {
setLiveUrl(value);
}}
/>


<button> type={'primary'}
onClick={() => {
updatePlayer();
onUrlChange && onUrlChange(liveUrl);
}}
>修改/<button>



<video> style={{ width: '100%', height: '100%' }}
controls
className='video-demo'
ref={(e) => playerDom = e}
>/<video>

);
}/<code>
  • 播放攝像頭的視頻流效果,右邊是直接獲取的攝像頭數據流,右邊是通過mac電腦推的實時的攝像頭畫面:
前端如何實現整套視頻直播技術流程

OK,這樣就搞定了一整套直播網頁需要的前後端技術服務的搭建了!

4. 後續需要繼續繼續實踐和探索的內容

上面的示例相對而言還過於簡單,只是藉助了第三方的技術和框架搭建了一個流媒體服務器,和前端支持播放視頻流的播放頁面,並通過攝像頭採集數據,推流,打通了整個流程,形成了一個閉環,但是還有很多內容需要進一步深入:

  • 視頻信息實時處理,如何添加更多的信息
  • 高併發場景是如何去實現的,流媒體服務器這塊的實現還是過於簡單,肯定還有需要分發處理的機制
  • 瀏覽器播放性能需要進行壓力測試

總結

本文通過概念學習和介紹,理解了常見視頻直播技術的整體架構流程,基於前端的角度去快速搭建了一套完整的直播網頁的功能,當然其中還有很多不足和需要深入的地方,需要進一步探索,後續如果有更深入的技術沉澱,會繼續形成文章進行分享!

原文鏈接:https://juejin.im/post/5e53411fe51d4526fe650e00


我自己是一名從事了多年的前端老程序員,小編為大家準備了新出的前端編程學習資料,免費分享給大家!

如果你也想學習前端,可以觀看【置頂】文章。也可以私信【1】 領取最新前端練手實戰項目


分享到:


相關文章: