1、如何用nginx+ffmpeg實現蘋果HLS協議
//循環處理命令行參數
while(optindex< argc){
opt = argv[optindex++];
//如果傳入的參數是「-」打頭
if(handleoptions&& opt[0]=='-'&& opt[1]!='\0'){
//如果傳入的參數是「--」打頭
if(opt[1]=='-'&& opt[2]=='\0'){
handleoptions =0;
//略過
continue;
}
//丟棄第一個字元」-」
opt++;
//解析命令行參數
//eg–acodec copy
//對應的 opt和 argv[optindex]為 「acodec」 「copy」
if((ret= parse_option(optctx, opt, argv[optindex], options))<0)
exit_program(1);
optindex += ret;
}else{
//此時 opt的值為輸出文件名如 test.ts
if(parse_arg_function)
//處理輸出文件的相關內容,如 struct OutputFile的初始化
parse_arg_function(optctx, opt);
}
}
在此,ffmpeg 默認的處理輸出文件名參數為:
staticvoid opt_output_file(void*optctx,constchar*filename)
2.2處理命令行參數
int parse_option(void*optctx,constchar*opt,constchar*arg, const OptionDef*options)
2.2.1查找匹配的Option
const OptionDef*po;
int bool_val=1;
int*dstcount;
void*dst;
//從全局變數options數組中查找opt對應的OptionDef
po = find_option(options, opt);
//如果未找到且以」no」打頭
//不需要傳遞參數的選項是bool類型的選項,默認為true
//如果需要設置為false,則需要加上」no」,以下的if則是處理這種情況
if(!po->name&& opt[0]=='n'&& opt[1]=='o'){
//去掉開頭的」no」重新查找
po = find_option(options, opt +2);
//如果仍未找到或者找到的選項不是bool類型
if(!(po->name&&(po->flags& OPT_BOOL)))
//報錯
goto unknown_opt;
bool_val =0;
}
//如果未找到且不是以上的」no」打頭情況
if(!po->name)
//尋找默認配置進行處理
po = find_option(options,"default");
//default配置也未找到,報錯
if(!po->name){
unknown_opt:
av_log(NULL, AV_LOG_ERROR,"Unrecognizedoption '%s'\n", opt);
return AVERROR(EINVAL);
}
//如果選項必須有參數但是沒有可用的參數,報錯
if(po->flags& HAS_ARG&&!arg){
av_log(NULL, AV_LOG_ERROR,"Missingargument for option '%s'\n", opt);
return AVERROR(EINVAL);
}
現在來查看一下find_option方法的實現:
staticconst OptionDef*find_option(const OptionDef*po,constchar*name)
根據name在全局變數options數組中查找OptionDef
//這里先處理參數帶有冒號的情況。比如 codec:a codec:v等
constchar*p= strchr(name,':');
int len= p? p- name: strlen(name);
//遍歷options
while(po->name!=NULL){
//比較option的名稱與name是否相符。
//這里 codec 與 codec:a相匹配
if(!strncmp(name, po->name, len)&& strlen(po->name)== len)
break;
po++;
}
return po;
2.2.2尋找選項地址
以下的代碼用於將 void*dst變數賦值。讓dst指向需要賦值的選項地址。
//如果選項在OptionContext中是以偏移量定位或者是 SpecifierOpt*數組的類型
dst= po->flags&(OPT_OFFSET| OPT_SPEC)?
//dst指向從 optctx地址偏移u.off的位置
(uint8_t*)optctx+ po->u.off:
//否則直接指向 OptionDef結構中定義的位置
po->u.dst_ptr;
//如果選項是SpecifierOpt*數組
if(po->flags& OPT_SPEC){
//數組首地址
SpecifierOpt **so= dst;
char*p= strchr(opt,':');
//這里是取得數組的當前長度+1
//請回顧 1.1中的描述:
//SpecifierOpt *xxx;
//int nb_xxx;
//當so指向xxx時刻,so+1指向nb_xxx
dstcount =(int*)(so+1);
//動態增長數組
*so = grow_array(*so,sizeof(**so), dstcount,*dstcount+1);
//將創建的SpecifierOpt結構體中的specifier賦值
//如codec:v 則specifier值為 「v」
(*so)[*dstcount-1].specifier= av_strp(p? p+1:"");
//dst指針指向數組新增的SpecifierOpt中的 u地址
//此時dstcount的值已經變作新數組的長度,亦即原數組長度+1
dst =&(*so)[*dstcount-1].u;",rich:"0"};
2015-01-09 15:25 提問者採納
//處理window的情況
prepare_app_arguments(&argc,&argv);
optindex=1;
//循環處理命令行參數
while(optindex< argc){
opt = argv[optindex++];
//如果傳入的參數是「-」打頭
if(handleoptions&& opt[0]=='-'&& opt[1]!='\0'){
//如果傳入的參數是「--」打頭
if(opt[1]=='-'&& opt[2]=='\0'){
handleoptions =0;
//略過
continue;
}
//丟棄第一個字元」-」
opt++;
//解析命令行參數
//eg–acodec copy
//對應的 opt和 argv[optindex]為 「acodec」 「copy」
if((ret= parse_option(optctx, opt, argv[optindex], options))<0)
exit_program(1);
optindex += ret;
}else{
//此時 opt的值為輸出文件名如 test.ts
if(parse_arg_function)
//處理輸出文件的相關內容,如 struct OutputFile的初始化
parse_arg_function(optctx, opt);
}
}
在此,ffmpeg 默認的處理輸出文件名參數為:
staticvoid opt_output_file(void*optctx,constchar*filename)
2.2處理命令行參數
int parse_option(void*optctx,constchar*opt,constchar*arg, const OptionDef*options)
2.2.1查找匹配的Option
const OptionDef*po;
int bool_val=1;
int*dstcount;
void*dst;
//從全局變數options數組中查找opt對應的OptionDef
po = find_option(options, opt);
//如果未找到且以」no」打頭
//不需要傳遞參數的選項是bool類型的選項,默認為true
//如果需要設置為false,則需要加上」no」,以下的if則是處理這種情況
if(!po->name&& opt[0]=='n'&& opt[1]=='o'){
//去掉開頭的」no」重新查找
po = find_option(options, opt +2);
//如果仍未找到或者找到的選項不是bool類型
if(!(po->name&&(po->flags& OPT_BOOL)))
//報錯
goto unknown_opt;
bool_val =0;
}
//如果未找到且不是以上的」no」打頭情況
if(!po->name)
//尋找默認配置進行處理
po = find_option(options,"default");
//default配置也未找到,報錯
if(!po->name){
unknown_opt:
av_log(NULL, AV_LOG_ERROR,"Unrecognizedoption '%s'\n", opt);
return AVERROR(EINVAL);
}
//如果選項必須有參數但是沒有可用的參數,報錯
if(po->flags& HAS_ARG&&!arg){
av_log(NULL, AV_LOG_ERROR,"Missingargument for option '%s'\n", opt);
return AVERROR(EINVAL);
}
現在來查看一下find_option方法的實現:
staticconst OptionDef*find_option(const OptionDef*po,constchar*name)
根據name在全局變數options數組中查找OptionDef
//這里先處理參數帶有冒號的情況。比如 codec:a codec:v等
constchar*p= strchr(name,':');
int len= p? p- name: strlen(name);
//遍歷options
while(po->name!=NULL){
//比較option的名稱與name是否相符。
//這里 codec 與 codec:a相匹配
if(!strncmp(name, po->name, len)&& strlen(po->name)== len)
break;
po++;
}
return po;
2.2.2尋找選項地址
以下的代碼用於將 void*dst變數賦值。讓dst指向需要賦值的選項地址。
//如果選項在OptionContext中是以偏移量定位或者是 SpecifierOpt*數組的類型
dst= po->flags&(OPT_OFFSET| OPT_SPEC)?
//dst指向從 optctx地址偏移u.off的位置
(uint8_t*)optctx+ po->u.off:
//否則直接指向 OptionDef結構中定義的位置
po->u.dst_ptr;
//如果選項是SpecifierOpt*數組
if(po->flags& OPT_SPEC){
//數組首地址
SpecifierOpt **so= dst;
char*p= strchr(opt,':');
//這里是取得數組的當前長度+1
//請回顧 1.1中的描述:
//SpecifierOpt *xxx;
//int nb_xxx;
//當so指向xxx時刻,so+1指向nb_xxx
dstcount =(int*)(so+1);
//動態增長數組
*so = grow_array(*so,sizeof(**so), dstcount,*dstcount+1);
//將創建的SpecifierOpt結構體中的specifier賦值
//如codec:v 則specifier值為 「v」
(*so)[*dstcount-1].specifier= av_strp(p? p+1:"");
//dst指針指向數組新增的SpecifierOpt中的 u地址
//此時dstcount的值已經變作新數組的長度,亦即原數組長度+1
dst =&(*so)[*dstcount-1].u;
2、CS HLSEVER如何建立中文名伺服器?
這個簡單
在你cs目錄下的cstrike文件夾里有一個sever.cfg的文件
用記事本打開
在hostname 後的兩個「間 打上你的伺服器名稱就可以了 輸入的是中文 顯示的就是中文
3、Hadoop適合做HLS流媒體點播系統的存儲嗎
使用Hadoop的HDFS存儲TS文件沒什麼問題,關鍵在於用什麼樣的點播伺服器以及你的架版構設計。
首先權,HLS全稱是HTTP Live Streaming,主要應用還是直播場景,做點播並不合適;
其次,HLS以HTTP方式分發TS片段文件,因此存儲系統的選型與點播伺服器的實現方式(選型)有關,點播伺服器能否對接HDFS的介面。
如果僅僅是點播用途,建議使用HTTP方式分發MP4文件,服務端nginx——簡單、可靠。
如果需要分布式存儲,Ceph也是一個備選方案。
4、如何利用七牛雲存儲實現 HLS 的多碼率播放
一,登錄成功後,復中間和右制上角點擊+新建空間 二,建立空間填寫名稱,並設置為公開訪問 三,點擊內容管理,並點擊右上角的「上傳」按鈕 四,七牛不支持直接在網頁上批量上傳,不能分目錄分組管理文件(如果需要區分文件目錄路徑,就添加文件前綴) 。
5、hls流媒體伺服器怎樣才能搭建成功
可以分2種:
1、租用IDC商的伺服器
你只要出錢租一台伺服器就可以,他們會給你一個回IP,用戶名和密碼給你,答你可以自己在裡面安裝iis或apache來做web伺服器,發布你公司的網站
2、託管你的伺服器
這個是要自己買伺服器去託管到IDC商那裡面,他們把伺服器給你拿到機房裡面上架,然後給你一個IP,用戶名和密碼就是你自己設置的伺服器用戶名和密碼,然後你自己在伺服器裡面安裝iis或apache等web伺服器軟體就可以發布你公司的網站了。
6、使用HLS做直播,總會延時在1分30秒或以上,有何減少延時的方法嗎
目前手頁直copy播,主要方案有如下幾種:
1,基於hls切片直播,前前是應用的主流,伺服器可以選fms,wowza,nginx,srs之類
優點:集成方便,支持度高,兼容性好,主流手都支持,是目前直播技術主流。
缺點:延時大,一般伺服器可以控制切片時長(延時可以控制在15-30秒之間)
2,基於瀏覽器mse技術,目前端技術上有B站的flv解碼器。後端技術srs之類。
優點:集成方便,兼容性一般,原有技術平台可以保留,延時可以控制在10秒內
缺點:(主要是部分瀏覽器不支持mse,),目前iOS微信內不支持,延時稍大。
註:有人用h264的解碼,代替flv,效過接近。
3,基於webrtc技術,目前只有wowza支持。
優點:延時少
缺點:兼容性差,目前ios不支持,原技術方案要調整,項目改造大。
4,基於ovmeet技術自建流服務直播,
優點:延時少,超低,可控在1秒內(測試在0.2秒左右),兼容好,所有html5手機平台通吃,技術兼容原平台推流rtmp,rtsp,rtp。
缺點:要自建流服務,
7、搭建了nginx流媒體伺服器支持hls,但是用ffmpeg做了ts跟m3u8但是只要在/tmp/hls文件下過了兩分鍾就會消失
是不是設置了或者觸發了流媒體有效時間
8、HLS實現點播和直播時,M3U8文件的不同
live m3u8文件列表需要不斷更新,更新規則:
移除一個文件播放列表中靠前的(認為已播放的)文件
不斷更新EXT-X-MEDIA-SEQUENCE標簽,以步長為1進行遞增
4.實驗
寫了一個生成live m3u8的小程序,進行測試
Usage:
m3u8_gen.exe start_num list_count ration filename.m3u8 [prefix]
使用示例:
m3u8_gen.exe 1 3 10 live.m3u8 hls/
生成live.m3u8文件為
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:10
#EXTINF:10
hls/1.ts
#EXTINF:10
hls/2.ts
#EXTINF:10
hls/3.ts
寫一個BAT腳本,每10s循環更新live.m3u8文件
@echo off
for /l %%i in (1,1,420) do (
echo m3u8_gen.exe %%i 3 10 live.m3u8 hls/
m3u8_gen.exe %%i 3 10 live.m3u8 hls/
call :SLEEP 10000
)
::延時函數實現
:SLEEP
ping 192.168.11.1 -n 1 -w %1 > nul
經VLC播放測試正常!!
9、視頻直播的實現過程
一個完整的視頻直播過程,包括採集、處理、編碼、封裝、推流、傳輸、轉碼、分發、解碼、播放等。
一、採集
音頻採集 音頻的採集過程主要通過設備將環境中的模擬信號採集成 PCM 編碼的原始數據,然後編碼壓縮成 MP3
等格式的數據分發出去。常見的音頻壓縮格式有:MP3,AAC,HE-AAC,Opus,FLAC,Vorbis (Ogg),Speex 和 AMR等。
圖像採集 圖像的採集過程主要由攝像頭等設備拍攝成 YUV 編碼的原始數據,然後經過編碼壓縮成 H.264
等格式的數據分發出去。常見的視頻封裝格式有:MP4、3GP、AVI、MKV、WMV、MPG、VOB、FLV、SWF、MOV、RMVB 和 WebM 等。
二、處理
視頻或者音頻完成採集之後得到原始數據,為了增強一些現場效果或者加上一些額外的效果,我們一般會在將其編碼壓縮前進行處理。
視頻:美顏、水印、路徑、自定義
音頻:混音、降噪、特效、自定義
三、編碼
對流媒體傳輸來說,編碼非常重要,它的編碼性能、編碼速度和編碼壓縮比會直接影響整個流媒體傳輸的用戶體驗和傳輸成本。
常見的視頻編碼器:
1)H.264/AVC
2)HEVC/H.265
3)VP8
4)VP9
5)FFmpeg
音頻編碼器:Mp3, AAC等。
四、封裝
把編碼器生成的多媒體內容(視頻,音頻,字幕,章節信息等)混合封裝在一起
幾種常見的封裝格式:
1)AVI 格式(後綴為 .avi)
2)DV-AVI 格式(後綴為 .avi)
3)QuickTime File Format 格式(後綴為 .mov)
4)MPEG 格式(文件後綴可以是 .mpg .mpeg .mpe .dat .vob .asf .3gp .mp4等)
5)WMV 格式(後綴為.wmv .asf)
6)Real Video 格式(後綴為 .rm .rmvb)
7)Flash Video 格式(後綴為 .flv)
8)Matroska 格式(後綴為 .mkv)
9)MPEG2-TS 格式 (後綴為 .ts)
目前,我們在流媒體傳輸,尤其是直播中主要採用的就是 FLV 和 MPEG2-TS 格式,分別用於 RTMP/HTTP-FLV 和 HLS 協議。
五、推流
推流是指使用推流工具等內容抓取軟體把直播內容傳輸到伺服器的過程。
推送協議主要有三種:
RTSP(Real Time Streaming Protocol):實時流傳送協議,是用來控制聲音或影像的多媒體串流協議, 由Real
Networks和Netscape共同提出的;
RTMP(Real Time Messaging Protocol):實時消息傳送協議,是Adobe公司為Flash播放器和伺服器之間音頻、視頻和數據傳輸
開發的開放協議;
HLS(HTTP Live Streaming):是蘋果公司(Apple Inc.)實現的基於HTTP的流媒體傳輸協議;
RTMP是目前主流的流媒體傳輸協議,廣泛用於直播領域,市面上絕大多數的直播產品都採用了這個協議。
RTMP協議基於 TCP,是一種設計用來進行實時數據通信的網路協議,主要用來在 flash/AIR 平台和支持 RTMP
協議的流媒體/交互伺服器之間進行音視頻和數據通信。支持該協議的軟體包括 Adobe Media Server/Ultrant Media Server/red5
等。
它有三種變種:
RTMP工作在TCP之上的明文協議,使用埠1935;
RTMPT封裝在HTTP請求之中,可穿越防火牆;
RTMPS類似RTMPT,但使用的是HTTPS連接;
RTMP協議就像一個用來裝數據包的容器,這些數據可以是AMF格式的數據,也可以是FLV中的視/音頻數據。一個單一的連接可以通過不同的通道傳輸多路網路流。這些通道中的包都是按照固定大小的包傳輸的。
六、傳輸
推送出去的流媒體需要傳輸到觀眾,整個鏈路就是傳輸網路。
七、轉碼
視頻直播播流端的碼率是根據推流端決定的,即播流端的碼率是與推流端的碼率一致的。但是遇到以下場景會造成直播效果較差:
推流端碼率與播流端帶寬不相匹配。當推流端碼率較高而客戶端帶寬資源有限就會導致播放出現卡頓,而當推流端碼率較低但是客戶端對於直播效率要求較高時會導致播放效果較差。
播放器插件需要實現多碼率切換。前端播放器插件常可以設置碼率切換,這就需要同一路推流可以同時提供多種碼率的播流地址。
因此,視頻直播提供了實時轉碼功能對同一路推流地址同時提供多路不同碼率播流地址提供服務。
八、分發
流媒體伺服器的作用是負責直播流的發布和轉播分發功能。
九、解碼
編碼器(Encoder):壓縮信號的設備或程序
解碼器(Decoder):解壓縮信號的設備或程序
編解碼器(Codec):編解碼器對
十、播放器流播放
主要是實現直播節目在終端上的展現。因為這里使用的傳輸協議是RTMP, 所以只要支持 RTMP 流協議的播放器都可以使用。
10、怎麼搭建CS伺服器?為什麼我用HLsever搭建後找不到伺服器呢?
你不用去什麼亂七八糟的鏈接,去浩方或QQ對戰平台創個伺服器就行了,我就這樣的,你去試試吧!