使用avconv进行重新封装为MKV时,是否有办法修复打包的AVI输入文件?

由于Plex服务器和松下电视之间的兼容性问题,唯一能够使其正常工作的方法是将所有内容重新封装为MKV格式,并直接复制所有流(视频、音频、字幕)。
看起来很简单。
avconv -i "input.avi" -c copy "output.mkv"

除外:
avconv version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
  built on Apr  2 2013 17:00:59 with gcc 4.6.3
[mpeg4 @ 0x8422140] Invalid and inefficient vfw-avi packed B frames detected
Input #0, avi, from 'input.avi':
  Metadata:
    encoder         : VirtualDubMod 1.5.4.1 (build 2117/release)
  Duration: 00:27:38.52, start: 0.000000, bitrate: 1173 kb/s
    Stream #0.0: Video: mpeg4 (Advanced Simple Profile), yuv420p, 640x352 [PAR 1:1 DAR 20:11], 25 tbr, 25 tbn, 25 tbc
    Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 132 kb/s
File 'output.mkv' already exists. Overwrite ? [y/N] y
Output #0, matroska, to 'output.mkv':
  Metadata:
    encoder         : Lavf53.21.1
    Stream #0.0: Video: mpeg4, yuv420p, 640x352 [PAR 1:1 DAR 20:11], q=2-31, 1k tbn, 25 tbc
    Stream #0.1: Audio: libmp3lame, 48000 Hz, stereo, 132 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press ctrl-c to stop encoding
[matroska @ 0x8422cc0] Can't write packet with unknown timestamp
av_interleaved_write_frame(): Invalid argument

相关的注意事项是:
[mpeg4 @ 0x8422140] Invalid and inefficient vfw-avi packed B frames detected#
<snip>
[matroska @ 0x8422cc0] Can't write packet with unknown timestamp
av_interleaved_write_frame(): Invalid argument

我看不到解压B帧的选项(或者构建VBR时间映射?在avconv中需要这些吗?)
有没有像avidemux那样的方法可以做到这一点?
3个回答

一个解决办法是先转换为.mp4格式:
avconv -i input.avi -c copy temp.mp4
avconv -i temp.mp4 -c copy output.mkv
rm temp.mp4

很遗憾,我们不能简单地在avconv实例之间传输mp4格式:"[mp4 @ 0x80846c0]多路复用器不支持非可搜索输出"。

谢谢,我今晚会试一下。我想知道是否有一个类似缓冲区的命令?等待写入stdin的命令完成后再将其全部传递到stdout。在stdout上进行搜索。那将非常方便。avconv -i xxx | buf | avconv -i stdin xxx - RoboJ1M
1我附加的错误信息是与尝试使用管道和avconv相关的,因为管道本质上是不可寻址的。我们能做的最好的办法就是将temp.mp4定位在tmpfs或类似的内存文件系统上。如果有足够的RAM,/dev/shm/是一个很好的选择。 - rmsr
关于管道,你可以使用命名管道,也称为FIFO。搜索一下mkfifo。基本上,你可以将文件用作标准输出的临时存储。 - Sparhawk
这个解决方案同样适用于ffmpeg。 - c97

截至 在FFmpeg错误跟踪器上的此票号#1979,最简单的解决办法是修复此错误或在命令行中手动添加-fflags +genpts
即更改为
ffmpeg -i inputfile_that_cant_be_muxed_into_mkv.ext -c copy out.mkv

ffmpeg -fflags +genpts -i inputfile_that_cant_be_muxed_into_mkv.ext -c copy out.mkv

1这还是给我同样的错误:/ - Felix
对我来说,使用avconv版本0.8.16效果还不错,直到文件末尾显示了一个奇怪的无法写入未知时间戳的数据包。真是奇怪。 - malat
2确保在输入选项中使用-fflags:它必须放在-i input之前。但如果你没有将+genpts放在正确的位置,可能根本不会起作用。 - Peter Cordes
这在avconv 9.18-6:9.18-0ubuntu0.14.04.1上也能正常工作。 - Elder Geek

感谢Andreas Cadhalpun,现在ffmpeg有了新的滤镜:mpeg4_unpack_bframes(参见ref)。这将允许您摆脱消息:检测到无效和低效的vfw-avi压缩B帧
使用方法非常简单:
ffmpeg -i INPUT.avi -codec copy -bsf:v mpeg4_unpack_bframes OUTPUT.avi