ffmpeg无法处理带有空格的文件名

22

我正在使用FFMPEG测量存储在亚马逊S3存储桶中的视频的时长。

我已经阅读了FFMPEG文档,并且它们明确指出,为了让FFMPEG正确处理所有空格和特殊字符,它们需要进行转义:

请参见文档2.1和2.1.1:https://ffmpeg.org/ffmpeg-utils.html

然而,当处理文件名包含空格的文件时,FFMPEG无法呈现结果。

我尝试了以下方法,但没有成功:

ffmpeg -i "http://s3.mybucketname.com/videos/my\ video\ file.mov" 2>&1 | grep Duration | awk '{print $2}' | tr -d
ffmpeg -i "http://s3.mybucketname.com/videos/my video file.mov" 2>&1 | grep Duration | awk '{print $2}' | tr -d
ffmpeg -i "http://s3.mybucketname.com/videos/my'\' video'\' file.mov" 2>&1 | grep Duration | awk '{print $2}' | tr -d
ffmpeg -i "http://s3.mybucketname.com/videos/my\ video\ file.mov" 2>&1 | grep Duration | awk '{print $2}' | tr -d

然而,如果我在文件名中删除空格 - 一切都好了,并返回视频的持续时间。


4
ffmpeg -i "my video file.mov" - fedorqui
3
你应该:1)用空格引用整个名称,或者2)用\\转义空格 - 不要同时使用两种方式。 - clt60
感谢您的帮助 - 看起来这仅适用于URL,而不是直接的文件名。例如:对“file name.mov”运行cmd可以工作。但是,对“http://domain.com/videos/file name.mov”运行它则不行。 - cmw
5
啊,那你需要检查一下 URL 是否被编码了。通常空格会被转换为 "%20"。只需用浏览器打开该 URL,查看地址栏中的内容即可。 - fedorqui
@fedorqui 就是这样!如果您将您的评论转换为答案,我会标记它。谢谢! - cmw
如果你使用PHP,那么你需要使用rawurlencode($video_url) - Fthr
7个回答

35

如果你的文件名中有空格,只需用引号将它们括起来:

ffmpeg -i "my video file.mov"
在URL中不能包含空格。最好将每个空格都替换为%20,这样才能得到正确的格式:
ffmpeg -i http://myurl.com/my%20video%20file.mov
                             ^^^     ^^^

1
如果我不知道路径...例如,我正在从设备中获取所有视频路径并在应用程序中显示...我不知道它们存储在哪个目录中...那么如何处理带有空格的文件名..请查看此链接..http://stackoverflow.com/questions/31774778/handling-commands-with-spaces-in-filenames ..谢谢 - Android Developer
@BhuvneshVarma 通常情况下,文件名要用双引号括起来,这样空格就不会破坏你的代码。 - fedorqui
请查看我的类似问题,我已经尝试过双引号了。http://stackoverflow.com/questions/33149606/ffmpeg-command-fails-for-file-path-with-white-spaces - user3904345
@fedorqui 的解决方法是创建一个没有空格的文件副本,并将其用作输入,输出也同理。我是偶然发现这个方法的。 - Akash Kava
@Brackets,你需要使用单引号(')来防止它们被扩展。否则,如果你不使用引号或使用双引号,情况可能会变得糟糕。在任何有内容的目录中比较 echo *echo '*' 以及 echo "*" - fedorqui
显示剩余3条评论

3

FFmpeg使用%来定义模式并处理多个文件。例如,如果您的文件名已进行URI编码,则必须使用“-pattern_type none”以避免FFmpeg的误解:

ffmpeg -pattern_type none -i file%20name.mp4

2

为了让ffmpeg能够处理带有空格的文件名/路径,您应该:

  1. 使用Pushd设置工作目录
  2. 将文件名放在引号""

这是一个可行的示例:

cls

REM ++++++++++++++++++++++++++
REM Cut an audio file by right-cliking it (works also on multiple selected audio)
REM 1) save this file
REM 2) open registry, browse to  Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\SystemFileAssociations\audio\shell. On the left panel, right-click on "shell" and select "New", then "Key". Type "Cut audio 5min". Right click on the newly created folder "Cut audio 5min" and select again "New" and then "Key". Type “command”. On the right pane, double-click the "(default)" value name and type the following:  "C:\Users\Me\Cut audio.cmd" "%1"
REM  optional: if you want an Icon : in the left pane, right click  "Cut audio 5min", and select String value, then in the right pane, rename the new value to Icon, then double click on it and past this "%SystemRoot%\\System32\\shell32.dll,186"     (; list icon: https://diymediahome.org/windows-icons-reference-list-with-details-locations-images/ )

REM 3) right click an audio file and select "Cut audio 5min": the chunks will be created in the same folder. 

REM because ffmpeg has trouble with path/filename with space, we set the working directory to the folder of the audio file and the we run the command not on a full path but just on the filename, with "" around it

REM get https://dev59.com/N2Up5IYBdhLWcg3wCUGx#15568171
REM fullpath of rightclicked file %1
REM full path (letter drive + path ithout letter drive)    %~d1%~p1
REM filename (filename + extension)   %~n1%~x1 

REM https://windowsloop.com/split-mp3-files-with-ffmpeg/
REM ffmpeg -i "input_audio_file.mp3" -f segment -segment_time 300 -c copy output_audio_file_%%03d.mp3
REM 300= 5min chunk

REM ++++++++++++++++++++++++++


REM set working directory
Pushd %~d1%~p1

REM  to let the windows open cmd /k ffmpeg -i "%~n1%~x1" -f segment -segment_time 300 -c copy "%~n1"_%%03d.mp3
cmd /k ffmpeg -i "%~n1%~x1" -f segment -segment_time 300 -c copy "%~n1"_%%03d.mp3

1
许多人已经指出,最好的选择是引用字符串。它适用于所有其他特殊字符。以下是我在ffmpeg文档页面中找到的一些示例。我附上了屏幕截图,以防将来无法使用。

Quoting Special Characters


1
for fileOne in *.mp4
do
  baseName=$(basename "$fileOne" .mp4) # "$fileOne" quotes are necessary because of special chars in it
  echo "input: " $fileOne
  echo "var: " $baseName
  echo "target: " $baseName".mp3"
  cp "$fileOne" "tmp.mp4"
  # ffmpeg problem with specialchars like whitespaces and '-'
  # ffmpeg -i \"$fileOne\" "$baseName..mp3"
  ffmpeg -i "tmp.mp4" "tmp.mp3"
  mv "tmp.mp3" "$baseName".mp3""
done
rm "tmp-mp4"

`只需重命名文件进行转换 :)

`


0

您正在使用视频URL作为输入,因此您需要对该URL进行编码,因为据我所知,CURLWGET也需要对URL进行编码,例如SPACE变成%20,如果您使用PHP,请像这样操作:rawurlencode($video_url)


0

我通过在包含文件路径的参数上添加引号来解决了这个问题。在我的情况下,路径存储在%1参数中(在注册表中写入时带有转义的引号:“\“%1 \””)。我使用PowerShell脚本检索它(使用内置参数$arg)。然后,我使用它获取一些文件信息,例如:

# Get the File path:  
$FilePath = $args

# Get the complete file name:
$file_name_complete = [System.IO.Path]::GetFileName("$FilePath")

# Get File Name Without Extension:
$fileNameOnly = [System.IO.Path]::GetFileNameWithoutExtension("$FilePath")

# Get the Extension:
$fileExtensionOnly = [System.IO.Path]::GetExtension("$FilePath")

不要忘记在$FilePath周围加上引号。

然后你可以像这样简单地将音频文件分成5分钟的部分:

ffmpeg -i $file_name_complete -f segment -segment_time 300 -c copy $fileNameOnly"_"%03d$fileExtensionOnly #

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