前端如何实现整套视频直播技术流程
目錄大綱:
簡介:
首先說明,本篇文章是概念+實踐,對于希望了解和實踐一個簡單的攝像頭直播網頁功能的人會有幫助,由于篇幅和實踐深入度有限,目前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官網:?鏈接
NodeMediaServer支持:以rtmp,rtsp,hls協議拉進行推流,支持http-flv,ws-flv來進行拉流,也就是支持瀏覽器端使用http或websocket傳輸flv格式的視頻流進行播放
開始搭建流媒體服務器:
-
下載對應的安裝包,使用的Linux環境
下載:
wget https://cdn.nodemedia.cn/nms/3.2.12/nms-linux-amd64-20200222.tar.gz 復制代碼解壓:
tar -zxvf nms-linux-amd64-20200222.tar.gz 復制代碼到解壓后的目錄下,執行命令,啟動服務
- 在控制臺輸入 ./nms運行
- 在當前程序目錄下執行 sudo ./service.sh install 安裝服務并自動運行
- 在當前程序目錄下執行 sudo ./service.sh uninstall 停止并卸載服務
-
服務成功啟動之后,可以在8000端口(默認端口)訪問流媒體服務的后臺系統,這里面大概長下面這個樣子:
首頁dashboard展示了服務器cpu的使用情況以及網絡帶寬狀況
-
-
服務啟動之后,接下來要做的是推流
怎么推流?這里涉及到一個很強大的東西ffmpeg,它是可以用來記錄、轉換數字音視頻,并將其轉化為流的開源軟件,通過它可以進行視頻的采集封裝成流,并推送到流媒體服務器,例如在mac上面安裝了這個軟件之后,可以通過它調用攝像頭,并將攝像頭數據封裝成流后推送到流媒體服務器,這個過程就是推流.ffmpeg還可以推送本地的視頻文件到流媒體服務器.
使用ffmpeg進行mac本地攝像頭實時推流到nodeMediaServer:
ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -i 0:0 -vcodec libx264 -preset veryfast -f flv http://ip:8000/live/stream.flv 復制代碼這里涉及到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
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 } //前端學習裙:950919261 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 (<div className='live-demo'><div className="modify-url"><Row><Col md={6}><Inputvalue={liveUrl}onChange={(value) => {setLiveUrl(value);}}/></Col><Col md={6}><Buttontype={'primary'}onClick={() => {updatePlayer();onUrlChange && onUrlChange(liveUrl);}}>修改</Button></Col></Row></div><videostyle={{ width: '100%', height: '100%' }}controlsclassName='video-demo'ref={(e) => playerDom = e}></video></div>); } -
播放攝像頭的視頻流效果,右邊是直接獲取的攝像頭數據流,右邊是通過mac電腦推的實時的攝像頭畫面:
OK,這樣就搞定了一整套直播網頁需要的前后端技術服務的搭建了!
4. 后續需要繼續繼續實踐和探索的內容
上面的示例相對而言還過于簡單,只是借助了第三方的技術和框架搭建了一個流媒體服務器,和前端支持播放視頻流的播放頁面,并通過攝像頭采集數據,推流,打通了整個流程,形成了一個閉環,但是還有很多內容需要進一步深入:
- 視頻信息實時處理,如何添加更多的信息
- 高并發場景是如何去實現的,流媒體服務器這塊的實現還是過于簡單,肯定還有需要分發處理的機制
- 瀏覽器播放性能需要進行壓力測試
總結
本文通過概念學習和介紹,理解了常見視頻直播技術的整體架構流程,基于前端的角度去快速搭建了一套完整的直播網頁的功能,當然其中還有很多不足和需要深入的地方,需要進一步探索,后續如果有更深入的技術沉淀,會繼續形成文章進行分享!
總結
以上是生活随笔為你收集整理的前端如何实现整套视频直播技术流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端实现多视频上传
- 下一篇: 前端上传视频至阿里云并转码