HLSは、ライブソースV2実現(H264、AACストリーム入力を、ffmpegの達成、MFC、VC環境、TS、M3U8)

免責事項:この記事はブロガーオリジナル記事ですが、許可ブロガーなく再生してはなりません。https://blog.csdn.net/xjb2006/article/details/78542026

(チャウ・シンチー)があることを!



多くの若者と同じように(と老人今)80,90、周星馳のようなだけでなく、文字葉のように、コスタリカの1が好きな映画俳優であったが、それは陽気な精神のようなものです!(QQの弟16年(チャウ・シンチー)のニックネームになっています)。

再び被験者に:

この記事のデモダウンロードhttp://download.csdn.net/download/xjb2006/10119982


、強力な所望の機能を達成することができ、簡単、しかし、またはいくつかの努力への活用を作りたいので、QQ技術グループでは、多くの人々は、ffmpegのを研究しています。

今日のトピックは、合成TS、M3U8後、すなわちオンデマンドプログラムHLS、AppleデバイスをH264、AACストリームの入力、出力を実現する方法です!

そこインターネットmp4ファイル転送や他のファイル形式上の多くの例がありますが、入力データストリームに、どのようにそれを行うには?多くの人々はまた、何もしません。インターネットは、このコードまたは記事への少しを持っています。

私自身のアイデアのいくつかについていくつかの単語を言うために途中で今日は、私の弟。

ビデオ入力ファイル、私たちにいくつかの参照が、交換するか、H264 AAC入力データストリームについての夕方に多くの例が、それは決してああではありません、があります。

1.何HLSこと?

HLS  (HTTPライブストリーミング)Appleがフラッシュ制御をサポートしていないため、直接使用するための唯一のAppleのブラウザ、Appleの動的ビットレート適応技術(コピー)である(当然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




*私が03年間働いて、「堪能」のオーディオおよびビデオアプリケーションのプログラミング(かろうじてハハ、注目を集めるために、熟練しを追加)、VC、MFCに精通し、マルチメディア教育ソフトを持って、協力ネクタイQQ35744025、详细の技術コンサルタントや技術が提供するコアすることができますが必要ですブロードキャストソフトウェアは、このようなffmpegの技術として、大多数のコア技術を習得しており、記録・放送・ソフトウェアは、のDirectShow技術は、MP4、FLVエンコードされた合成、H264は、AAC、MP3は、あなたがIPP効率的な画像空間変換を使用することができますインテルとCUDAを用いて行うことができますH264コーデックハードウェアは、符号240 1080P、完全同期と滑らか、RTMPの高度、HLSライブ、RTMPサーバ、YV12、YUV422、NV12、RGB24、RGB32馴染みの変換、スケーリング、WAV、AAC、MP3プッシュリアルタイムで実施することができますコーデック、ビデオトランジションエフェクトアルゴリズム、ビデオ透かし、ロゴ、テキスト。ビデオの画面キャプチャ、ビデオキャプチャカメラ、ビデオ画像、キャプチャカードをD3D効率的、OpenCVの、画像ライブラリのXImage、GDI、GDIPlusの熟練したアプリケーション、音声認識およびテキスト変換、認識やマッチング、LANリモート・コントロール、リアルタイムのオーディオおよびビデオ通話を表示再生には、SQLデータベース、アクセス、EXCELデータベース、DOC、抽出することが開いているPDFファイルに加えて、FTPSERVER、クライアントは、上記のコードの全ては、商業となっています。

おすすめ

転載: blog.csdn.net/xjb2006/article/details/78542026