使用ffmpeg进行转换时覆盖文件的问题

19

我正在使用ffpmeg将所有视频转换为mp4格式:

 ffmpeg -i InpuFile -vcodec h264 -acodec aac -strict -2 OutputFile.mp4

问题是,如果我覆盖输入文件,也就是输出文件和输入文件相同:

 ffmpeg -i InpuFile -vcodec h264 -acodec aac -strict -2 InpuFile.mp4 -y
 ffmpeg -i InpuFile -y -vcodec h264 -acodec aac -strict -2 InpuFile.mp4

新文件不好。它只持续了一秒钟,而且大小非常小。

有什么想法吗?

我希望将其用作我的服务器脚本,因此覆盖是最方便的方式,我更喜欢这种方式,而不是创建临时文件,然后用临时文件替换原始文件。


同样的概念适用于大多数Linux工具。克服它的唯一方法是使用临时文件。如果工具有克服它的选项,那基本上就是它们在幕后所做的。 - Ciro Santilli OurBigBook.com
5个回答

21

我也遇到过同样(令人沮丧)的问题。您可能已经注意到这是因为ffmpeg正在写入它正在读取的文件,导致在过程结束之前破坏了源文件... ffmpeg不会将文件放入某些缓冲区,所以您不能以此方式操作,您将不得不使用临时文件。

以防万一


这是正确的。我正在使用PHP shell_exec尝试压缩文件,但它会抛出一个错误。您不能覆盖输入源。因此,是的,请创建一个临时文件,然后稍后重命名它。 - Andy

2

正如其他人所提到的,没有办法在不创建临时文件的情况下完成此操作。你提到你想要压缩所有视频,并使其方便。这里是一个bash一行命令,我用它来压缩目录中所有MP4和MOV格式的视频:

find * -type f \( -iname \*.mp4 -o -iname \*.mov \) -execdir ffmpeg -i {} -vcodec libx265 -crf 24 temp_{} \; -execdir mv temp_{} {} \;

-crf参数控制视频比特率,其取值范围为18-24,数值越小比特率越高。
如果你只想压缩.mp4文件,那么你需要修改命令为:
find * -type f -iname "*.mp4" -execdir ffmpeg -i {} -vcodec libx265 -crf 24 temp_{} \; -execdir mv temp_{} {} \;

希望这对原帖作者或任何想要做类似事情的人有所帮助。

2

在编码过程中,您不能覆盖输入文件。您必须进行编码以输出到另一个文件。

之后,您可以使用新编码的文件替换原始文件。


0

也许这可以帮助到某些人。

我曾经处理过将专辑封面添加到mp3专辑目录中的问题。

for f in ./*.mp3; do ffmpeg -i "$f" -i *jpg -map_metadata 0 -map 0 -map 1 -codec copy tmp_"${f#./}" && mv tmp_"${f#./}" "$f"; done

我也在这里使用了几乎相同的东西here


-1

没有太烦人的临时文件使用。简而言之:

input="InpuFile"; ffmpeg -i "$input" -y -vcodec h264 -acodec aac -strict -2 "/tmp/$input";rm "$input"; mv "/tmp/$input" .;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接