FFMPEG生成M3U8
at 1年前 ca FFmpeg pv 569 by touch
m3u8是一种视频播放标准,准确来说是一种索引文件,使用m3u8文件实际上是通过它来解析服务器上对应的视频地址。视频网站可以根据用户的网络带宽情况,自动为客户端匹配一个合适的码率文件进行播放,从而保证视频的流畅度。
此代码通过FFMPEG函数将视频文件转换成TS和M3U8文件,可以使用此代码完成点播业务。
#include <iostream> #include <string> #include <fstream> #include <thread> #include <functional> extern "C"{ #include <libavformat/avformat.h> #include <libavutil/pixdesc.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> }; void printError(int code) { char buf[1024]={0}; av_strerror(code,buf,sizeof(buf)); std::cout << "error msg :" << buf << std::endl; } AVFormatContext* createFmtCtx(AVFormatContext *inFmtCtx,char* outMediaFilePath){ AVFormatContext *outFmtCtx=avformat_alloc_context(); avformat_alloc_output_context2(&outFmtCtx, NULL, NULL, outMediaFilePath); int videoStrIndex=av_find_best_stream(inFmtCtx,AVMEDIA_TYPE_VIDEO,-1,0,NULL,0); int audioStrIndex=av_find_best_stream(inFmtCtx,AVMEDIA_TYPE_AUDIO,-1,0,NULL,0); AVStream *videoStream=avformat_new_stream(outFmtCtx,NULL); AVStream *audioStream=avformat_new_stream(outFmtCtx,NULL); avcodec_parameters_copy(videoStream->codecpar,inFmtCtx->streams[videoStrIndex]->codecpar); avcodec_parameters_copy(audioStream->codecpar,inFmtCtx->streams[audioStrIndex]->codecpar); avcodec_parameters_to_context(videoStream->codec,videoStream->codecpar); avcodec_parameters_to_context(audioStream->codec,audioStream->codecpar); if (avio_open(&outFmtCtx->pb, outMediaFilePath, AVIO_FLAG_READ_WRITE) < 0) //创建并初始化一个AVIOContext { std::cout << "avio_open error msg " << std::endl; return NULL; } av_dump_format(outFmtCtx, 0, outMediaFilePath, 1); return outFmtCtx; } int main() { av_register_all(); //视频编码主要格式h264/mpeg4,音频为acc/MP3。 //输入视频文件路径 const char* inputMediaFilePath="D:\\1\\1.flv"; //使用指针,方便后面修改文件名称 AVFormatContext *pFmtCtx=avformat_alloc_context(); int ret=avformat_open_input(&pFmtCtx,inputMediaFilePath,NULL,NULL); if(ret!=0) { printError(ret); return 0; } ret=avformat_find_stream_info(pFmtCtx,NULL); if(ret!=0) { printError(ret); return 0; } AVPacket *pkt=av_packet_alloc(); //文件m3u8 char outFileName[]="D:\\1\\ts\\test.m3u8"; //https://www.ffmpeg.org/ffmpeg-all.html#hls-2 AVDictionary* muxer_opts = NULL; //event vod av_dict_set(&muxer_opts, "hls_playlist_type", "vod", 0); //生成ts分段文件的路径 av_dict_set(&muxer_opts, "hls_segment_filename", "D:\\1\\ts\\test_%05d.ts", 0); //hls_time 参数设置切片的duration,单位秒 av_dict_set(&muxer_opts,"hls_time","10",0); av_dict_set(&muxer_opts,"hls_list_size","0",0); //每隔10秒刷新一次m3u8 av_dict_set(&muxer_opts,"master_pl_publish_rate","2",0); AVFormatContext* outFmtCtx=createFmtCtx(pFmtCtx,outFileName); avformat_write_header(outFmtCtx, &muxer_opts); while (av_read_frame(pFmtCtx, pkt) >= 0) { av_interleaved_write_frame(outFmtCtx, pkt); av_packet_unref(pkt); } av_write_trailer(outFmtCtx); av_packet_free(&pkt); avformat_close_input(&pFmtCtx); avformat_free_context(pFmtCtx); return 0; }
版权声明
本文仅代表作者观点,不代表码农殇立场。
本文系作者授权码农殇发表,未经许可,不得转载。
已有0条评论