22

I'm using FFMPEG to measure the duration of videos stored in an Amazon S3 Bucket.

I've read the FFMPEG docs, and they explicitly state that all whitespace and special characters need to be escaped, in order for FFMPEG to handle them properly:

See docs 2.1 and 2.1.1: https://ffmpeg.org/ffmpeg-utils.html

However, when dealing with files whose filenames contain whitespace, ffmpeg fails to render a result.

I've tried the following, with no success

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

However, if I strip out the whitespace in the filename – all is well, and the duration of the video is returned.

Zoe
  • 27,060
  • 21
  • 118
  • 148
cmw
  • 946
  • 2
  • 11
  • 26
  • 4
    If you quote, just leave the name as it is: `ffmpeg -i "my video file.mov"` – fedorqui Mar 31 '14 at 15:46
  • 3
    you should: 1.) quote the whole name with spaces, or 2.) escape the spaces with `\\` - not both. – clt60 Mar 31 '14 at 15:49
  • thanks for the help – it seems this only applies to URL's, and not straight filenames. IE: running the cmd against "file name.mov" works. However, running it against "http://domain.com/videos/file name.mov" does not. – cmw Mar 31 '14 at 15:54
  • 5
    Aaaah then you have to check how the URL is encoded. Normally a space is converted into `%20`. Just open the URL with your browser and see what is written in the address bar. – fedorqui Mar 31 '14 at 16:11
  • @fedorqui that was it! If you convert your comment to an answer, I'll mark it as such. Thanks! – cmw Mar 31 '14 at 22:08
  • Oh you need `rawurlencode($video_url)` if you using PHP – Fthr Jan 29 '21 at 02:03

7 Answers7

35

If you happen to have spaces in your file name, just quote them:

ffmpeg -i "my video file.mov"

In a URL, a space cannot be there. Most probably you have to replace every single space with a %20, so that you get:

ffmpeg -i http://myurl.com/my%20video%20file.mov
                             ^^^     ^^^
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 1
    and if i don't know the path...example.i am fetching all paths of videos from device and displaying in app..i don't know in which directory they are stored..then how to handle filenames with whitespaces..check out this..http://stackoverflow.com/questions/31774778/handling-commands-with-spaces-in-filenames ..thanks – Android Developer Aug 03 '15 at 04:00
  • @BhuvneshVarma in general, always double quotes file names, so that spaces don't make your code break. – fedorqui Aug 03 '15 at 08:41
  • Please check my similar issue..i tried double quoting.. http://stackoverflow.com/questions/33149606/ffmpeg-command-fails-for-file-path-with-white-spaces –  Oct 15 '15 at 14:01
  • @fedorqui double quotes do not work in Android even for filenames. – Akash Kava May 08 '16 at 07:08
  • @AkashKava that is very strange. – fedorqui May 09 '16 at 08:31
  • @fedorqui workaround is to create a copy of file that does not have spaces and use that as input, same for output. I found this accidentally. – Akash Kava May 09 '16 at 08:44
  • @AkashKava ok, but still I can't see why double quotes wouldn't work in any *NIX based OS. – fedorqui May 09 '16 at 08:45
  • @Brackets you'll need to use single quotes (`'`) to prevent them from being expanded. Otherwise, if you do not use quotes or use double quotes, things can get bad. Compare `echo *` with `echo '*'`and `echo "*"` in any dir with some content. – fedorqui Nov 07 '18 at 19:43
3

ffmpeg uses % to define a pattern and handle multiple files. For instance if your filename is URI encoded you must use "-pattern_type none" to avoid misinterpretation from ffmpeg:

ffmpeg -pattern_type none -i file%20name.mp4
Rodrigo Fava
  • 318
  • 3
  • 12
2

To make ffmeg works with filename/path that have whitespaces, you should:
1) set the working directory with Pushd
2) put your filename inside quote ""


here is a working example:

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://stackoverflow.com/a/15568171/3154274
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
MagTun
  • 5,619
  • 5
  • 63
  • 104
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"

`just rename the file for the conversion :)

christian
  • 19
  • 2
1

As many have pointed out, the best option is to quote the string. It works for all other special characters.Here are some examples I found of the ffmpeg documentation page. I am attaching a screen shot just in in case it is unavailable in the future.

Quoting Special Characters

rocksyne
  • 1,264
  • 15
  • 17
0

I solved it by "enquoting" the arg that contain the file path. In my case, the path was stored in the %1 argument (which was written in the registry under quote that are escaped: \"%1\" ). I retrieve it (with a PowerShell script), simply using $arg (inbuilt argument). I then used it get some file information such as:

# 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")

Don't forget the quote around $FilePath.

Then you can use it to divide audio filesin 5min parts simply like this:

ffmpeg -i $file_name_complete -f segment -segment_time 300 -c copy $fileNameOnly"_"%03d$fileExtensionOnly #
J. Does
  • 785
  • 3
  • 10
  • 23
0

You are using video URL for the input, so you need to encode that URL, because as I know CURL or WGET also need URL to be encoded, like SPACE become %20, if you use PHP do like this: rawurlencode($video_url)

Fthr
  • 769
  • 9
  • 10