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;
}
//heliang
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;
}
网友评论