ffmpeg 连接:"Unsafe file name"

ffmpeg concat: "Unsafe file name"

正在尝试将一堆 mts 文件转换成一个大的 mp4 文件:

stephan@rechenmonster:/mnt/backupsystem/archive2/Videos/20151222/PRIVATE/AVCHD/BDMV$ ~/bin/ffmpeg-git-20160817-64bit-static/ffmpeg -v info -f concat -i <(find STREAM -name '*' -printf "file '$PWD/%p'\n") -deinterlace -r 25 -s hd720 -c:v libx264 -crf 23 -acodec copy -strict -2 ~/tmp/Videos/20151222.mp4
ffmpeg version N-81364-gf85842b-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.4.1 (Debian 5.4.1-1) 20160803
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --enable-libass --enable-gnutls --enable-libvidstab --enable-libsoxr --enable-frei0r --enable-libfribidi --disable-indev=sndio --disable-outdev=sndio --enable-librtmp --enable-libmfx --enable-libzimg --cc=gcc-5
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 53.100 / 57. 53.100
  libavformat    57. 46.101 / 57. 46.101
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 51.100 /  6. 51.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
[concat @ 0x56054a0] Unsafe file name '/mnt/backupsystem/archive2/Videos/20151222/PRIVATE/AVCHD/BDMV/STREAM'
/dev/fd/63: Operation not permitted

知道这里出了什么问题吗?术语 "unsafe file" 在这种情况下是什么意思?

@Mulvya 给出的答案(谢谢!)有效:"Add -safe 0 before -i"。 然后 find STREAM -name '*' -printf "file '$PWD/%p'\n" 出现了另一个问题,其中 returns 空路径作为第一个条目。将此更改为 for f in ./*.wav; do echo "file '$PWD/$f'"; done(请参阅 https://trac.ffmpeg.org/wiki/Concatenate),现在它似乎可以工作了。万岁!

@sers 的回答是完全正确的,我只是给你看命令,所以你不要把 -safe 0 放在其他任何地方。

ffmpeg.exe -f concat -safe 0 -i "clips.txt" -c copy "video.mp4"

要回答原因,我们需要看看 ffmpeg 的解复用器的操作,它从输入文件中读取多媒体流。在这种情况下,我们使用“concat”,具有以下选项:(archived docs)

This demuxer accepts the following option:

safe If set to 1, reject unsafe file paths. A file path is considered safe if it does not contain a protocol specification and is relative and all components only contain characters from the portable character set (letters, digits, period, underscore and hyphen) and have no period at the beginning of a component.

If set to 0, any file name is accepted.

The default is 1.

-1 is equivalent to 1 if the format was automatically probed and 0 otherwise.

原来find .在文件前面放了一个./。如果您不想使用 -safe 0.

,请参阅 How to strip leading "./" in unix "find"? 获取解决方案

在我的例子中,双引号导致错误。

我使用 ffmpeg -f concat -i concat.txt -c copy output.m4a 命令,其中 concat.txt 包含要连接的输入文件列表。

不安全的文件名(双引号被视为文件名的一部分,-safe 0无法修复):

file "song1.m4a"
file "song2.m4a"

安全文件名(单引号):

file 'song1.m4a'
file 'song2.m4a'

安全文件名(不带引号):

file song1.m4a
file song2.m4a

上面的 单引号 不带引号 只有包含 才安全。所以下面的通用文件名将不起作用:

  • space
  • 字形
  • /(路径)
  • 前缀句点(隐藏文件)

对于这种情况,您仍然需要 -safe 0

[Caveat about Quoting and escaping]

你总是需要在文件名部分转义'。原因是因为 file Im' .avi 会自动在 Im' .avi' 上添加收盘价,这与 file Im' .avi' 相同。 file Im' .avi'''''' 中的最后一个奇数引号也将添加结束引号成为 file Im' .avi''''''' ,因此它没有 No such file or directory 错误。我发现这种现象是因为 space 不再需要在单引号前缀后通过 \ 转义,而不必添加右引号。

尽管如此(必须通过 \ 转义 ' 而不是使用 " 转义), 转义方式类似于 shell。如果文件名包含单引号,您可以使用 I\'m\ .m4a(不包含单引号)样式或 'I'\''m .m4a''I'\''m'\ '.m4a'(用单引号括起来)样式对其进行转义,但是 'I\'m\ .m4a' 也不 'I'm .m4a'.

测试ffmpeg时,注意第一行错误信息Impossible to open可能误导(文件确实存在),您需要检查第二行,它是 No such file or directory(文件不存在)或 Invalid data found when processing input(无效的媒体文件)。