FFmpeg拼接文件时报错channel element 1.0 is not allocated的分析思路和解决方法

FFmpeg拼接视频文件报错原因及解决
本文讲述使用FFmpeg的concat方式拼接多段视频文件时出现报错的问题。报错为“channel element 1.0 is not allocated”,经查看源码发现,是由于concat过程中后续文件流布局与第一个文件不同,流顺序不一致导致拼接失败,统一顺序即可解决。

本文出处:http://blog.youkuaiyun.com/chaijunkun/article/details/117535933,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。

拼接视频文件时的一个报错

书接上回,在上一篇文章:FFmpeg实现音视频同步的精准片段拼接中我在最后提到了使用concat方式拼接多段视频文件的方法。主要还是由于目前的自动化任务中,视频数量不可控。直接使用concat滤镜来进行拼接,内存会被撑爆,因此使用了ffmpeg -f concat -i manifest.txt这样的方式来进行拼接。

但是在拼接过程中,出现了以下的一段报错:

...正常编码信息...
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000017079753400] Auto-inserting h264_mp4toannexb bitstream filter0 speed=1.45x
[aac @ 0000017075f0acc0] channel element 1.0 is not allocated
Error while decoding stream #0:1: Invalid data found when processing input
[aac @ 0000017075f0acc0] channel element 1.4 is not allocated
Error while decoding stream #0:1: Invalid data found when processing input
[h264 @ 0000017075f22700] No start code is found.
[h264 @ 0000017075f22700] Error splitting the input into NAL units.
...以下重复上述错误信息...

主要是“channel element 1.0 is not allocated”,当然中间的数字是可变的,既然报错了,那么就打开FFmpeg的源码,来看看在哪里报这段错误,最终,我在libavcodec/aacdec_template.c中找到了这段错误的细节:

const int elem_type = aac_channel_layout_map[chan_config-1][i][0];
const int elem_id   = aac_channel_layout_map[chan_config-1][i][1];
if (!(che=get_che(ac, elem_type, elem_id))) {
	av_log(ac->avctx, AV_LOG_ERROR,
	"channel element %d.%d is not allocated\n",
	elem_type, elem_id);
	return AVERROR_INVALIDDATA;
}

本错误在处理aac编码的音频流时发生,由于concat过程中,所有流的布局都是以第一个文件为准,那么后续所有文件的流布局必须也和第一个文件相同。例如有如下清单文件:

# manifest.txt
file 'video_01.mp4'
file 'video_02.mp4'

通过ffprobe命令查看流的布局信息:

ffprobe -show_streams -of json video_01.mp4

发现流的布局为:

"index": 0,
"codec_name": "h264",
"codec_type": "video",
...
"index": 1,
"codec_name": "aac",
"codec_type": "audio",

可以看到,流的布局:
0:视频流;
1:音频流。
再查看第二个文件的流布局:

"index": 0,
"codec_name": "aac",
"codec_type": "audio",
...
"index": 1,
"codec_name": "h264",
"codec_type": "video",

可以看到,流的布局:
0:音频流;
1:视频流。
···
流的顺序不一致,导致拼接失败。因此,只要统一顺序就可以了。一般习惯视频文件的第一个流为视频流,第二个流为音频流。

ffmpeg -i video_02.mp4 -c copy -map "0:v" -map "0:a" video_remapping_02.mp4

然后拼接时使用:

# manifest.txt
file 'video_01.mp4'
file 'video_remapping_02.mp4'

命令:

ffmpeg -f concat -i manifest.txt -c copy concat.mp4
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值