导航:首页 > IDC知识 > hls服务器实现

hls服务器实现

发布时间:2020-11-21 16:40:23

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对战平台创个服务器就行了,我就这样的,你去试试吧!

与hls服务器实现相关的知识