hls直播实现源码V2(h264,aac流输入,ffmpeg实现,MFC,VC环境,ts,m3u8)

周星驰来也!



像很多80,90后年轻人(老男人吧)一样,周星驰一直就是哥喜爱的电影演员之一,不仅喜欢星爷的人物形象,更是喜欢这种乐观向上的精神!(哥16年的QQ一直就是周星驰这个昵称)。

转入主题吧:

本文demo下载地址http://download.csdn.net/download/xjb2006/10119982


在QQ技术群里,很多人都在研究ffmpeg,因为功能强大,简单直接就能实现想要的功能,但是想要用好,还是要下一些功夫。

今天的主题就是怎样实现对h264,aac流输入,合成后输出ts,m3u8,即HLS,苹果设备的点播方案!!!!!!!!!!!!!!!!!!!!

网上有很多关于文件转mp4或者其他文件格式的例子,但是换成数据流输入了,怎么办呢?很多人也是一筹莫展。网上也鲜有这种代码或者文章。

今天,哥哥就顺便说几句,关于我自己的一些想法。

晚上有很多例子是关于输入视频文件的,对我们有些参考,但是要换成输入h264或者aac数据流,大家都是没办法啊。

1、HLS是什么?

HLS (HTTP Live Streaming)是Apple的动态码率自适应技术(复制过来的),只有苹果的浏览器才能直接用,因为苹果不支持flash控件(自然也不支持rtmp),所以才有了HLS技术用于点播直播。调试的时候可以下载一个VLC播放器,这个播放器可以打开m3u8。

2、TS文件

百度这样说的:ts是高清摄像机拍摄下进行的封装格式,全称为MPEG2-TS。ts即"Transport Stream"的缩写。MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。先不管这些了,反正HLS就要用到TS格式的文件,一个一个的。贴张图吧,百说不如一见:


3、m3u8文件

M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。

M3U8文件举例,例如使用云图TV点播直播节目时,发送请求:

http://121.199.63.236:7613/m3u8/cckw1/szws.m3u8?

看到没,其实苹果的点播就是http上直接访问。


4、实现过程和思路:

设置存ts,m3u8的路径,输入h264和aac流,根据设置的ts长度和个数,不断更新ts文件和m3u8文件


说了这么多基础,来点实际的吧:

我封装的最后的接口函数:

void StartHLS(CString szPath,CString szName="xiao");//开始启动hls,路径为保存m3u8和ts的路径
void SetAudioProperty(int channels, int samplerate, int bitspersample);
void SetVideoProperty(int width, int height, double framerate);
void StopHLS(void);
void H264In(BYTE* pH264, LONG nH264Len, LONG nTimeStamp=0);
void AACIn(BYTE* pAAC, LONG nAACLen, LONG nTimeStamp=0);

调用ffmpeg的步骤:

av_register_all();

定义几个全局的:

AVFormatContext* output_format_context;//输出文件结构上下文
     AVStream* o_video_stream ;
     AVStream *o_audio_stream ;

输入h264关键帧:

通过关键帧获取视频信息并

avio_alloc_context(这个函数很多文章或者代码里面都没有提到过吧),生成一个自定义输入io,用来探测h264的格式

//读入数据avformat_open_input

//设置输入结构体信息
avformat_find_stream_info

//设置输出文件格式信息
avformat_alloc_output_context2

//打开输出文件
avio_open

//添加音视频流

avformat_new_stream

//写入头

av_dump_format、avformat_write_header

至此,文件初始化工作完成

接下来写数据啦

av_packet_from_data、av_packet_rescale_ts、av_interleaved_write_frame、av_write_trailer

最后记得释放

avio_close、avformat_free_context


完了,搞完收工!!!!!!看看效果



中间有很多困扰:枚举下:比如ts文件格式必须输入的aac为 ADTS编码的,即有7个字节的头,没有就别想播放。

音视频同步,主要还是通过音视频时间戳pts,dts同步的。m3u8及ts文件更新,根据设置的一个ts文件秒数和个数进行不断更新,比如设置的5秒一个,一共3个,那么,每隔3秒,保存ts并创建新的ts,然后更新m3u8文件信息.

我的m3u8文件内容:

#EXTM3U

#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:103
#EXTINF:10,
xiao-103.ts
#EXTINF:10,
xiao-104.ts
#EXTINF:10,
xiao-105.ts

测试的时候,装备一台苹果手机(肾没了没办法就下载个VLC播放器也行),一个免费的http服务器软件,我下的免费的easywebserver。准备h264数据源和AAC数据源,这方面办法很多,读h264,aac文件,截取屏幕或者摄像头,aac获取麦克风转成AAC,或者输入音频文件转成AAC(编码一定要有 ADTS 头啊,切记切记

但是上面说了这么多,应该也能自己做了吧。什么时候传个DEMO上来,有空再说吧

传点代码(关键的一段):

[cpp]  view plain  copy
  1.   
[cpp]  view plain  copy
  1. void CHLSSend::H264In(BYTE* pH264, LONG nH264Len, LONG nTimeStamp)  
  2. {  
  3.     MP4ENC_NaluUnit nalu;  
  4.     int pos = 0, len = 0;  
  5.     bool bKeyFrame=false;  
  6.     while (len = ReadOneNaluFromBuf((const unsigned char *)pH264,nH264Len,pos,nalu))  
  7.     {  
  8.         if(nalu.type==0x05)  
  9.         {  
  10.             bKeyFrame=true;  
  11.             break;  
  12.         }  
  13.         pos += len;  
  14.     }  
  15.     if(bKeyFrame)  
  16.     {  
  17.         try  
  18.         {  
  19.             s_write_file_head(pH264, nH264Len);  
  20.         }  
  21.         catch(...)  
  22.         {  
  23.             TRACE("写入文件头异常!\n");  
  24.             isfirst=true;  
  25.             return;  
  26.         }  
  27.     }  
  28.     if (isfirst)  
  29.         return;  
  30.     if(nTimeStamp==0)  
  31.         nTimeStamp=::GetTickCount();  
  32.     if(m_bFirstVideo)  
  33.     {  
  34.         m_uFirstVideo=nTimeStamp;  
  35.         m_u64VideoPTS = nTimeStamp;  
  36.         m_bFirstVideo=false;  
  37.     }  
  38.   
  39.   
  40.     AVPacket pkt;  
  41.     av_init_packet(&pkt);  
  42.     uint8_t* avdata = (uint8_t*)av_malloc(nH264Len + AV_INPUT_BUFFER_PADDING_SIZE);  
  43.     memcpy(avdata, pH264, nH264Len);  
  44.     //   
  45.     int iiiii = av_packet_from_data(&pkt, (uint8_t*)avdata, nH264Len);  
  46.     if (iiiii == 0)  
  47.     {  
  48.         Lock.Lock();  
  49.         int pts=PTS2TIME_SCALE(nTimeStamp, m_uFirstVideo, m_fps);  
  50.         //TRACE("视频时间:%0.2f  视频时间2: %d\n",(double)pts*1000/(double)m_fps,(m_nVideoCount));  
  51.         pkt.pts = (m_nVideoCount++);//音频帧率=48000/1024  视频帧率:30=30*1024/1024    
  52.         pkt.dts = pkt.pts;  
  53.   
  54.         av_packet_rescale_ts(&pkt, o_video_stream->codec->time_base, o_video_stream->time_base);  
  55.         pkt.stream_index = o_video_stream->index;  
  56.         pkt.duration = 1;  
  57.         pkt.pos = -1;  
  58.         if(bKeyFrame)  
  59.             pkt.flags |= AV_PKT_FLAG_KEY;  
  60.         int result = av_interleaved_write_frame(output_format_context, &pkt);     
  61.         if(result!=0)  
  62.         {  
  63.             printf("fail2\n");  
  64.             //MessageBox(0,"111",0,MB_OK);  
  65.         }  
  66.   
  67.         //判断一个TS是否完成  
  68.         m_nOneTsTime=GetVideoTime(m_nVideoCount);  
  69.         int current_segment_duration = (int)(m_nOneTsTime-m_nFirstTime + 0.5);  
  70.         //actual_segment_durations[last_segment] = (current_segment_duration > 0 ? current_segment_duration: 1);  
  71.         if(m_nOneTsTime-m_nFirstTime>=ONETSLEN)//  
  72.         {  
  73.             StopWriteAndNewTs();  
  74.             m_nFirstTime=m_nOneTsTime;//第一次文件写入时间  
  75.             TRACE("10秒到,写入文件并创建新文件\n");  
  76.         }  
  77.   
  78.   
  79.         Lock.Unlock();  
  80.   
  81.     }  
  82.     else  
  83.     {  
  84.         printf("fail\n");  
  85.         //MessageBox(0,"222",0,MB_OK);  
  86.     }  
  87.   
  88.     av_free_packet(&pkt);//他会把buff清理掉  
  89. }  

今天花了2个小时把DEMO做好了,可以下载看看效果,有问题或者需要交流,可以联系我,谢谢(前面一个是v2版本,后面是v1版本)

http://download.csdn.net/download/xjb2006/10119982

http://download.csdn.net/download/xjb2006/10106146




*需要合作的联系QQ35744025,可以当当技术顾问或者核心技术提供,本人03年从事工作,“精通”音视频应用编程技术(勉强加个精通,吸引眼球,哈哈),精通VC,MFC,多媒体教学软件,录播软件,直播软件的核心技术大部分已掌握,如ffmpeg技术,Directshow技术,MP4,FLV编码合成,H264,AAC,MP3,可以运用IPP进行高效图像空间转换等,可以运用INTEL和cuda进行硬件H264编解码,可以实现240帧1080P实时编码,完全同步及平滑度极高,rtmp,HLS直播推送,rtmp服务器,YV12,YUV422,NV12,RGB24,RGB32熟悉转换,缩放,wav,AAC, mp3的编码解码,视频切换特效算法,视频水印,LOGO,文字。屏幕截取录像,摄像头捕获录像,D3D高效视频图像显示,OPENCV,图像库ximage,GDI,GDIPLUS熟练应用,语音识别及文字转换,人脸识别及匹配,局域网内远程控制,音视频实时通话,声卡捕获回放等,另外SQL数据库,ACCESS,EXCEL数据库,DOC,PDF文件打开提取,FTPServer,Client,以上所有代码均已商用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周星星的星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值