最近采用ffmpeg做一个流媒体服务器,当录像的时候,前端反应无法打开mp4,仔细一看文件也没有缩略图,通过VLC发现可以打开播放,然后用ffmpeg命令查看了一下格式如下:
ffprobe -show_format 2020.mp4
Input #0, mpegts, from '2020.mp4':
Duration: 00:02:15.04, start: 0.000000, bitrate: 4410 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(progressive), 2560x1440, 25 fps, 25 tbr, 90k tbn, 180k tbc
[FORMAT]
filename=2020.mp4
nb_streams=1
nb_programs=1
format_name=mpegts
format_long_name=MPEG-TS (MPEG-2 Transport Stream)
start_time=0.000000
duration=135.040000
size=74448896
bit_rate=4410479
probe_score=50
[/FORMAT]
猛地一看也没看出什么不对,
然后windows右键属性看了一下:
发现什么信息都没有,
再用linux打开看一下:
注意到这里Container是ts格式,难道格式不对?
想到的第一个办法是用MP4info工具打开看一下
结果是open failed.
那就找一个前端能打开的对比一下,
然后找了一个能打开的MP4文件,发现格式如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '2020.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1iso6mp41
encoder : Lavf58.32.104
Duration: 00:00:57.20, start: 0.000000, bitrate: 601 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 598 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
[FORMAT]
filename=2021.mp4
nb_streams=1
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=57.200000
size=4301534
bit_rate=601613
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2avc1iso6mp41
TAG:encoder=Lavf58.32.104


果然是格式不对导致,这样就好办了,查看代码发现,我在打开输出的时候用这样,
nRet = avformat_alloc_output_context2(&m_outputFmtContext, nullptr, "mpets",
m_rtmpUrl.c_str());
那应该问题就出现在这里,既然手动行不通,那么就用自动:
m_rtmpUrl=“2020.MP4”;
AVOutputFormat *const output_format =
av_guess_format(nullptr, m_rtmpUrl.c_str(), nullptr);
if (!output_format) {
printf("output format not found\n");
break;
}
nRet = avformat_alloc_output_context2(&m_outputFmtContext, output_format,
nullptr, nullptr);
if (nRet < 0) {
AVPrintErr(nRet, "avformat_alloc_output_context2");
break;
}
修改以后发现还不行,我艹,开始百度了一下,
https://github.com/horgh/videostreamer/blob/master/videostreamer.c
https://blog.csdn.net/ET_Endeavoring/article/details/77949850?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-8.control
在编码阶段添加如下:
pAVCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
pAVCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pAVCodecCtx->width = m_width;
pAVCodecCtx->height = m_height;
pAVCodecCtx->time_base.num = 1;
pAVCodecCtx->time_base.den = 25;
pAVCodecCtx->framerate.den = 1;
pAVCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
pAVCodecCtx->bit_rate = 200000;
pAVCodecCtx->gop_size = 10;
pAVCodecCtx->keyint_min = 100;
pAVCodecCtx->qmin = 10;
pAVCodecCtx->qmax = 36;
pAVCodecCtx->has_b_frames = 0;
av_opt_set(pAVCodecCtx->priv_data, "profile", "high", 0);
av_opt_set(pAVCodecCtx->priv_data, "preset", "slow", 0);
av_opt_set(pAVCodecCtx->priv_data, "level", "5", 0);
av_opt_set(pAVCodecCtx->priv_data, "tune", "zerolatency", 0);
Ok,试了一下能打开,但是没有时长,后来觉得是尾部没写,那就把尾部写上:
av_write_trailer(m_outputFmtContext);
发现还是没有时长,不过前端已经可以打开,那就先这样吧,以后解决。
花费了半天功夫。
版权声明:本文为weixin_43360707原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。