hls協議
Ⅰ HLS,RTMP,HTTP這些協議有什麼區別
HLS (HTTP Live Streaming)
Apple的動態碼率自適應技術。主要用於PC和Apple終端的音視頻服務。包括一個m3u(8)的索引文件,TS媒體分片文件和key加密串文件。
常用的流媒體協議主要有 HTTP 漸進下載和基於 RTSP/RTP 的實時流媒體協議,這二種基本是完全不同的東西,目前比較方便又好用的是用 HTTP 漸進下載方法。在這個中 apple 公司的 HTTP Live Streaming 是這個方面的代表。它最初是蘋果公司針對iPhone、iPod、iTouch和iPad等移動設備而開發的流.現在見到在桌面也有很多應用了,HTML5 是直接支持這個。
但是HLS協議的小切片方式會生成大量的文件,存儲或處理這些文件會造成大量資源浪費。如果要實現數天的時移,索引量將會是個巨額數字,並明顯影響請求速度。因此,HLS協議對存儲I/O要求相當苛刻。對此,也有公司提出了非常好的解決方案。
新型點播伺服器系統,獨創了內存緩存數據實時切片技術,顛覆了這種傳統實現方法,從根本上解決了大量切片的碎片問題,使得單台伺服器的切片與打包能力不再是瓶頸。其基本原理如下:
不將TS切片文件存到磁碟,而是存在內存當中,這種技術使得伺服器的磁碟上面不再會有「數以噸計」的文件碎片,極大減少了磁碟的I/O次數,延長了伺服器磁碟的使用壽命,極大提高了伺服器運行的穩定性。同時,由於使用這種技術,使得終端請求數據時直接從伺服器的內存中獲取,極大提高了對終端數據請求的反應速度,優化了視頻觀看體驗。
RTSP協議,這應該是實時性最好的了,如果要想實時性要求很高,比如0.5s以內,這個是不錯的選擇。前陣子模仿spydroid寫了個建議的rtsp 伺服器,其實就是options,describe,setup,play,pause,teardown這幾步了,這個協議用的最廣泛,網上介紹也比較 多。要想真正深入了解rtsp協議,c++語言功底好的可以查看live555 。
Ⅱ Edge瀏覽器為什麼要支持蘋果HLS協議
HLS協議允許流媒體分段下載,不過這種HTTP分段點播的方式已經用於很多流媒體服務網站。版但HLS的特別之處在權於,它的分段非常小,而這種小的分段方式也讓HLS獨特的在線視頻直播方式成為可能。
HLS直播最大的特色,同時也是不同傳統網路直播的方式在於,直播客戶端獲取到的,一直都不是一個完整的數據流。HLS協議在伺服器端將直播數據流截取並存儲為連續的、時長很短的媒體文件,客戶端則不斷下載並播放這些小文件,因為伺服器端總是會將最新的直播數據生成新的小文件,這樣客戶端只要不停的按順序播放從伺服器獲取到的文件,並利用生成的m3u8文件進行索引,從而實現完整地視頻直播。
此外與實時傳輸協議(RTP)不同,HLS只請求基本的HTTP報文,因此可以穿過任何允許HTTP數據通過的防火牆或者代理伺服器,而它也很容易使用內容分發網路來傳輸媒體流。
Ⅲ 求推薦幾個同時支持hls和rtmp協議的監控攝像頭
iOS在調用一個攝像頭的同時另外一個攝像頭會停止工作。
Ⅳ HLS什麼意思
HTTP Live Streaming(縮寫是抄HLS)是一個由襲蘋果公司提出的基於HTTP的流媒體網路傳輸協議。
HLS協議是蘋果推出的解決方案,將視頻分成5-10秒的視頻小分片,然後用m3u8索引表進行管理,由於客戶端下載到的視頻都是5-10秒的完整數據,故視頻的流暢性很好,但也同樣引入了很大的延遲(HLS的一般延遲在10-30s左右)。
相比於FLV,HLS在iPhone和大部分android手機瀏覽器上的支持非常給力。
(4)hls協議擴展閱讀:
HLS協議客戶端支持簡單, 只需要支持 HTTP 請求即可, HTTP 協議無狀態, 只需要按順序下載媒體片段即可,而且網路兼容性好, HTTP 數據包也可以方便地通過防火牆或者代理伺服器。
但是相比RTMP 這類長連接協議, 用到互動直播場景延時較高。HLS(HTTP Live Streaming)是蘋果公司推出的流媒體協議, 用於直播或點播場景, 應該算是當前平台兼容性最好的流媒體協議了. 其他主流的流媒體協議還有RTP(內容傳輸使用UDP)和Adobe的RTMP(基於TCP).
Ⅳ Firefox是不是不支持hls協議
恩,不支持。
Ⅵ 有沒有既支持HLS協議,又支持H265的android播放器
泰捷的盒子(we20s),完美支持H265解碼+HLS協議(點播+直播)
Ⅶ 流媒體協議RTMP、RTSP與HLS有什麼不同
1.HLS(HTTPLiveStreaming):Apple的動態碼率自適應技術。主要用於PC和Apple終端的音視頻服務。
2.http為計算機網路中進行數據交換而建立的規則,網路中一個微機用戶和一個大型主機的操作員進行通信。
3.流媒體協議是用來描述進程之間信息交換數據時的規則術語。
Ⅷ 如何用nginee+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
//對應的 opt和 argv[optindex]為 「acodec」 「」
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
//對應的 opt和 argv[optindex]為 「acodec」 「」
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++;
}
Ⅸ hls直播協議最小延遲是幾秒
我們測試過,正在做,延遲22s以上,和pc沒法比,pc都是用flash做的
Ⅹ 如何用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
//對應的 opt和 argv[optindex]為 「acodec」 「」
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
//對應的 opt和 argv[optindex]為 「acodec」 「」
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;