ffmpeg concat:“不安全的文件名”

问题描述 投票:0回答:4

尝试将一堆 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

你知道这里出了什么问题吗?在这种情况下,术语“不安全文件”是什么意思?

ffmpeg concatenation
4个回答
124
投票

@Gyan 在评论中提出的解决方案(谢谢!)有效:

  • “在
    -safe 0
    之前添加
    -i
    ”。

然后

find STREAM -name '*' -printf "file '$PWD/%p'\n"
出现了另一个问题,它返回空路径作为第一个条目。

我将其更改为

for f in ./*.wav; do echo "file '$PWD/$f'"; done
(请参阅https://trac.ffmpeg.org/wiki/Concatenate),现在它似乎可以工作。万岁!


33
投票

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

我使用

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

上面的单引号不带引号只有在只包含“字母、数字、句号(前缀除外)、下划线和连字符”时才是安全的。所以下面的通用文件名不起作用:

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

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

-safe 0

[关于引用和转义的警告]

文件名部分总是需要转义

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

尽管有上述情况(必须通过

'
转义
\
,而不是用
"
转义),转义风格与 shell 类似。如果文件名包含单引号,您可以使用
I\'m\ .m4a
(不用单引号括起来)样式或
'I'\''m .m4a'
OR
'I'\''m'\ '.m4a'
(用单引号括起来)样式进行转义,但
'I\'m\ .m4a'
'I'm .m4a'
都不是。 .

当你测试ffmpeg时,请注意第一行错误消息

Impossible to open
可能会误导(文件确实存在),你需要检查第二行是
No such file or directory
(文件不存在)或
 Invalid data found when processing input
(无效媒体文件)。


30
投票

为了回答原因,我们需要了解 ffmpeg 解复用器的操作,它从输入文件读取多媒体流。在本例中,我们使用“concat”,具有以下选项:(存档文档)

此分路器接受以下选项:

safe
如果设置为 1,则拒绝不安全的文件路径。考虑文件路径 如果它不包含协议规范并且是相对的,则安全 并且所有组件仅包含可移植字符中的字符 设置(字母、数字、句点、下划线和连字符)并且没有 组件开头的句点。

如果设置为 0,则接受任何文件名。

默认为 1。

如果自动探测格式,则

-1 相当于 1,否则相当于 0。

原来

find .
在文件前面放了一个
./
。如果您不想使用 -safe 0,请参阅
如何在 UNIX“查找”中去除前导“./”?
以获取解决方案。


28
投票

@sers 的答案是完全正确的,我只是向您展示命令,这样您就不会在其他任何地方放置 -safe 0 。

ffmpeg.exe -f concat -safe 0 -i "clips.txt" -c copy "video.mp4"
© www.soinside.com 2019 - 2024. All rights reserved.