基於 Nginx 和 FFmpeg 搭建流媒體服務器


什么是流媒體

流媒體就是將視頻文件分成許多小塊兒,將這些小塊兒作為數據包通過網絡發送出去,實現一邊傳輸視頻數據 包一邊觀看視頻。

什么是流式傳輸

客戶端通過鏈接視頻服務器實時傳輸音、視頻信息,實現“邊下載邊播放”。

  • 順序流式傳輸
    即順序下載音、視頻文件,可以實現邊下載邊播放,不過,用戶只能觀看已下載的視頻內容,無法快進到未下載的視頻部分,順序流式傳輸可以使用Http服務器來實現,比如Nginx、Apache等。

  • 實時流式傳輸
    實時流式傳輸可以解決順序流式傳輸無法快進的問題,它與Http流式傳輸不同,它必須使用流媒體服務器並 且使用流媒體協議來傳輸視頻,它比Http流式傳輸復雜。常見的實時流式傳輸協議有RTSP、RTMP、RSVP 等。

業務流程

1.將原始的視頻文件通過編碼器轉換為適合網絡傳輸的流格式,編碼后的視頻直接輸送給媒體服務器

2.媒體服務獲取到編碼好的視頻文件,對外提供流媒體數據傳輸接口,接口協議包括 :HTTP、RTSP、 RTMP等

3.播放器通過流媒體協議與媒體服務器通信,獲取視頻數據,播放視頻

視頻點播方案
  • 方案1
    播放器通過 http協議從http服務器上下載視頻文件進行播放
    問題: 「必須等到視頻下載完才可以播放」,不支持快進到某個時間點進行播放

  • 方案2
    播放器通過rtmp協議連接媒體服務器以實時流方式播放視頻
    問題: 使用rtmp協議需要架設媒體服務器,「造價高」,對於直播多采用此方案

  • 方案3
    播放器使用HLS協議連接http服務器(Nginx、Apache等)實現近實時流方式播放視頻
    「HLS協議」:基於Http協議,視頻封裝格式為ts,視頻的編碼格式為H264,音頻編碼格式為MP3、AAC或者AC- 3。
    采用HLS方案可以實現邊下載邊播放,並且不用使用rtmp流媒體協議,不用構建專門的媒體服務器,節省成本
    「所以我們這里選擇方案3」

什么是HLS

HLS (HTTP Live Streaming)是Apple的動態碼率自適應技術。主要用於PC和Apple終端的音視頻服務。包括一個m3u(8)的索引文件,TS媒體分片文件和key加密串文件。

iOS、Android設備、及各大瀏覽器都支持HLS協議。

  • HLS的工作方式
    將視頻拆分成若干ts格式的小文件,通過m3u8格式的索引文件對這些ts小文件建立索引。一般 10秒一個ts文件,播放器連接m3u8文件播放,當快進時通過m3u8即可找到對應的索引文件,並去下載對應的ts文 件,從而實現快進、快退以近實時 的方式播放視頻。

  • HLS視頻編碼
    將視頻編碼成HLS格式,最終會輸出兩類文件,m3u8文件和ts文件

  • 視頻播放
    1.客戶端先下載m3u8文件
    2.根據m3u8文件列表下載ts文件
    3.客戶端播放ts文件

什么是視頻編碼

所謂視頻編碼方式就是指通過壓縮技術,將原始視頻格式的文件轉換成另一種視頻格式文件的方式。

  • 文件格式
    指.mp4、.avi、.rmvb等 這些不同擴展名的視頻文件的文件格式。

  • 編碼格式
    通過音視頻的壓縮技術,將視頻格式轉換成另一種視頻格式,通過視頻編碼實現流媒體的傳輸。比如:一個.avi的視頻文件原來的編碼是a,通過編碼后編碼格式變為b,音頻原來為c,通過編碼后變為d。

  • 常見音視頻編碼格式

MPEG系列 (由ISO[國際標准組織機構]下屬的MPEG[運動圖象專家組]開發 )視頻編碼方面主要是Mpeg1(vcd用 的就是它)、Mpeg2(DVD使用)、Mpeg4(的DVDRIP使用的都是它的變種,如:sectionx,xvid等)、Mpeg4 AVC(正熱門);

音頻編碼方面主要是MPEG Audio Layer 1/2、MPEG Audio Layer 3(大名鼎鼎的mp3)、 MPEG-2 AAC 、MPEG-4 AAC等等。注意:DVD音頻沒有采用Mpeg的。

H.26X系列 (由ITU[國際電傳視訊聯盟]主導,側重網絡傳輸,注意:只是視頻編碼) 包括H.261、H.262、 H.263、H.263+、H.263++、H.264(就是MPEG4 AVC-合作的結晶)

目前最常用的編碼標准是視頻H.264,音頻AAC。

FFmpeg

FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,並能將其轉化為流的開源計算機程序。采用LGPL或GPL許可證。

它提供了錄制、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec里很多code都是從頭開發的。

FFmpeg在Linux平台下開發,但它同樣也可以在其它操作系統環境中編譯運行,包括Windows、Mac OS X等。這個項目最早由Fabrice Bellard發起,2004年至2015年間由Michael Niedermayer主要負責維護。

許多FFmpeg的開發人員都來自MPlayer項目,而且當前FFmpeg也是放在MPlayer項目組的服務器上。項目的名稱來自MPEG視頻編碼標准,前面的"FF"代表"Fast Forward"

FFmpeg被許多開源項目采用,QQ影音、暴風影音等。

  • Linux下安裝ffmpeg

# 1.安裝ffmpeg時需要提前安裝yasm插件
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -xvf yasm-1.3.0.tar.gz
cd yasm-1.3.0/
./configure && make && make install
# 2.安裝ffmpeg
wget http://www.ffmpeg.org/releases/ffmpeg-3.4.tar.gz
tar -xvf ffmpeg-3.4.tar.gz
cd ffmpeg-3.4/
./configure && make && make install
# 3.查看版本號
[root@centos7-app ffmpeg-3.4]# ffmpeg -version
ffmpeg version 3.4 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-28)
configuration:
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
  • windows下環境搭建

1.下載FFmpeg
FFmpeg下載地址

FFmpeg下載

  1. 配置環境變量
    把解壓后的軟件路徑E:\soft\ffmpeg-20191029-d3dee67-win64-static\bin加到環境變量

  2. 是否安裝成功

C:\Users\Administrator>ffmpeg -version
ffmpeg version git-2019-10-29-d3dee67 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20191010
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --e
nable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-
libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 35.101 / 56. 35.101
libavcodec 58. 60.100 / 58. 60.100
libavformat 58. 33.100 / 58. 33.100
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 66.100 / 7. 66.100
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
  • 把avi格式轉為mp4

ffmpeg -i test.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\test.mp4

-c:v 視頻編碼為x264 ,x264編碼是H264的一種開源編碼格式。
-s 設置分辨率
-pix_fmt yuv420p:設置像素采樣方式,主流的采樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0,它的作用是 根據采樣方式來從碼流中還原每個像素點的YUV(亮度信息與色彩信息)值。
-b 設置碼率,-b:a和-b:v分別表示音頻的碼率和視頻的碼率,-b表示音頻加視頻的總碼率。碼率對一個視頻質量有 很大的作用,后邊會介紹。
-r:幀率,表示每秒更新圖像畫面的次數,通常大於24肉眼就沒有連貫與停頓的感覺了。

# 碼率
碼率又叫比特率即每秒傳輸的bit數,單位為bps(Bit Per Second),碼率越大傳送數據的速度越快。
碼率的計算公式是:文件大小(轉成bit)/ 時長(秒)/1024 = kbps 即每秒傳輸千位數
例如一個1M的視頻,它的時長是10s,它的碼率等於
1*1024*1024*8/10/1024 = 819Kbps
  • mp4生成m3u8

# 將test.mp4視頻文件按每10秒生成一個ts文件,最后生成一個m3u8文件,m3u8文件就是ts的索引文件
ffmpeg ‐i test.mp4 ‐hls_time 10 ‐hls_list_size 0 ‐hls_segment_filename ./hls/test_%05d.ts ./hls/test.m3u8

-hls_time 設置每片的長度,單位為秒
-hls_list_size n: 保存的分片的數量,設置為0表示保存所有分片
-hls_segment_filename :段文件的名稱,%05d表示5位數字
播放器選擇

視頻編碼后要使用播放器對其進行解碼、播放視頻內容。在web應用中常用的播放器有flash播放器、H5播放器或 瀏覽器插件播放器,其中以flash和H5播放器最常見。

flash播放器:缺點是需要在客戶機安裝Adobe Flash Player播放器,優點是flash播放器已經很成熟了,並且瀏覽 器對flash支持也很好。

H5播放器:基於h5自帶video標簽進行構建,優點是大部分瀏覽器支持H5,不用再安裝第三方的flash播放器,並且隨着前端技術的發展,h5技術會越來越成熟。

這里我們采用H5播放器,使用Video.js開源播放器。

Video.js:https://github.com/videojs/video.js
videojs-contrib-hls:https://github.com/videojs/videojs-contrib-hls#installation (videojs-contrib-hls是播放hls的一個插件) 使用文檔:http://docs.videojs.com/tutorial-videojs_.html

我們這里使用 video.js 6.7.3 版本,videojs-contrib-hls 5.14.1版本。

搭建媒體服務器

HLS協議是基於Http協議的,我們這里使用Nginx作為視頻服務器。

  • nginx.conf

# nginx.conf
server {
listen 80;
server_name localhost;
#視頻目錄
location /{
root /usr/share/nginx/html; # 項目路徑
index index.html index.htm;
}
}
  • 測試代碼

./html/
├── index.html
├── video
│ ├── test_00000.ts
│ ├── test_00001.ts
│ ├── test_00002.ts
│ ├── test_00003.ts
│ ├── test_00004.ts
│ ├── test_00005.ts
│ ├── test_00006.ts
│ ├── test_00007.ts
│ ├── test_00008.ts
│ ├── test_00009.ts
│ ├── test_00010.ts
│ └── test.m3u8
└── videojs
├── video.js
├── videojs-contrib-hls.js
└── video-js.css
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>視頻播放</title>
<link href="./videojs/video-js.css" rel="stylesheet">
</head>
<body>

<video
id=example-video
width=800 height=600
class="video-js vjs-default-skin vjs-big-play-centered"
controls
poster="http://192.168.5.134/video/add.jpg">
<source src="http://192.168.5.134/video/test.m3u8" type="application/x-mpegURL">
</video>

<input type="button" onClick="resetVideo()" value="switch"/>

<script src="./videojs/video.js"></script>
<script src="./videojs/videojs-contrib-hls.js"></script>
<script>
var player = videojs('example-video');
//player.play();

function resetVideo(){
player.src({
src: 'http://192.168.5.134/video/test.m3u8',
type: 'application/x-mpegURL',
withCredentials: true
});
player.play();
}
</script>
</body>
</html>
  • 測試

http://192.168.5.134

作者:iDevOps

來源:https://www.jianshu.com/p/b1680d3ecd4f


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM