什么是推流,拉流
推流:把視頻,音頻數據采集好傳輸到服務器的過程
拉流:從服務器把視頻,音頻數據拉取下來進行播放的過程
拉流過程:
根據協議類型(如RTMP、RTP、RTSP、HTTP等),與服務器建立連接并接收數據;
- 解析二進制數據,從中找到相關流信息;
- 根據不同的封裝格式(如FLV、TS)解復用(demux);
- 分別得到已編碼的H.264視頻數據和AAC音頻數據;
- 使用硬解碼(對應系統的API)或軟解碼(FFMpeg)來解壓音視頻數據;
- 經過解碼后得到原始的視頻數據(YUV)和音頻數據(AAC);
- 因為音頻和視頻解碼是分開的,所以我們得把它們同步起來,否則會出現音視頻不同步的現象,比如別人說話會跟口型對不上;
- 最后把同步的音頻數據送到耳機或外放,視頻數據送到屏幕上顯示。
推流過程:
- 經過輸出設備(AVCaptureVideoDataOutput)得到原始的采樣數據--視頻數據(YUV)和音頻數據(AAC);
- 使用硬編碼(對應系統的API)或軟編碼(FFMpeg)來編碼壓縮音視頻數據;
- 分別得到已編碼的H.264視頻數據和AAC音頻數據;
- 根據不同的封裝格式(如FLV、TS、MPEG-TS);
- 使用HLS協議的時候加上這一步(HLS分段生成策略及m3u8索引文件)
- 通過流上傳到服務器;
- 服務器進行相關協議的分發
什么是軟解碼,硬解碼
軟解碼:由顯卡核心GPU來對高清視頻進行解碼工作,CPU占用率很低,畫質效果比軟解碼略差一點,需要對播放器進行設置。
硬解碼:由CPU負責解碼進行播放。
優點 | 缺點 | |
---|---|---|
硬解碼 | 播放流暢、低功耗 | 受視頻格式限制、功耗大、畫質沒有軟解碼好 |
軟解碼 | 不受視頻格式限制、畫質略好于硬解 | 會占用過高的資源、對于高清視頻可能沒有硬解碼流暢(主要看CPU的能力) |
什么是RTMP, HTTP-FLV, HLS (傳輸協議)
RTMP: Adobe發布的一個視頻傳輸的協議,底層基于TCP,在瀏覽器端依賴Flash
HTTP-FLV: 將音視頻數據封裝成FIV格式,通過HTTP協議傳輸給客戶端,流式傳輸
WEBSOCKET-FLV:http-flv的websocket版
HLS: Http Live Streaming, 蘋果提出的基于HTTP的流媒體傳輸協議,Html5可以直接打開播放,不用依賴Flash
RTMP | HLS | HTTP-FLV | |
---|---|---|---|
全稱 | Real-Time Messaging Protocol | Http Live Streaming | RTMP over HTTP |
協議 | TCP長連接 | HTTP短連接 | HTTP 長連接 |
原理 | 每個時刻的數據收到后立刻轉發 | 集合一段時間的數據,生成ts切片文件(三片),并更新m3u8索引 | 同RTMP,使用HTTP協議 |
播放器 | Flash | Video | Flash Video |
延時 | 1-3秒 | 5-20秒 | 1-3秒 |
web支持 | H5中需使用插件 | 支持H5 | H5中需使用插件 |
什么是flv.js
flv.js是B站的開源項目,它可以解析flv文件傳給原生的h5 video標簽,使瀏覽器可以不借助flash播放flv文件,即可以在瀏覽器端實現直播
瀏覽器對原生video標簽采用了硬件加速,性能更好
實現一個簡單的直播
- 下載安裝livego(go編寫的直播服務器,主播推流到音視頻服務,音視頻服務再轉發給所有連接的客戶端)
brew install go //安裝go環境
git clone https://github.com/gwuhaolin/livego.git //clone livego
cd livego
go build // 進行編譯
./livego 啟動livego
啟動成功各協議對應接口
image.png
- 使用ffmpeg(多媒體視頻處理工具)給livego推流
brew install ffmpeg //安裝ffmpeg
ffmpeg -f avfoundation framerate -30 -i "0" -vcodec h264 -acodec aac -f flv rtmp://localhost/live/test //生成推流地址
ffplay -i // ffmpeg用來播放視頻的指令
ffplay -i rtmp://localhost:1935/live/test //用該指令可以驗證是否推流成功
livego生成的播放地址
RTMP:rtmp://localhost:1935/live/test
FLV:http://127.0.0.1:7001/live/test.flv
HLS:http://127.0.0.1:7002/live/test.m3u8
- 在web端實現拉流直播(HTTP-FLV協議)
- 西瓜播放器版 (文檔:https://h5player.bytedance.com/)
// npm install xgplayer-flv //安裝西瓜播放器flv插件
import FlvJsPlayer from 'xgplayer-flv';
const flvurl = `http://127.0.0.1:7001/live/test.flv` //livego flv地址
// 不能寫成http://localhost:7001/live/test.flv 否則會獲取不到
class XgPlayer extends Component {
constructor (props) {
super(props)
this.player = null;
}
componentDidMount() {
this.init()
}
init(){
this.player = new FlvJsPlayer({
el:this.playerElement,
url:flvurl,
isLive: true,
preloadTime: 30,
minCachedTime: 5,
cors: true,
})
}
render() {
return (
<div id='livePlayer' ref={el => this.playerElement = el} style={{width:'100%'}}>
</div>
)
}
}
flv.js版
// npm install reflv
import Reflv from 'reflv';
export default class HttpFlv extends PureComponent {
render() {
return (
<Reflv
url='http://127.0.0.1:7001/live/test.flv'
type="flv"
isLive
cors
config={{
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 128,
}}
/>
)
}
}