100

Trying to convert a bunch of mts-files into a big mp4-file:

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

Any ideas what goes wrong here? What does the term "unsafe file" mean in this context?

Dharman
  • 21,838
  • 18
  • 57
  • 107
sers
  • 2,496
  • 2
  • 15
  • 23
  • 56
    Add `-safe 0` before `-i`. See https://ffmpeg.org/ffmpeg-all.html#Options-31 – Gyan Aug 17 '16 at 12:43
  • @Gyan why it still requires to add `-safe 0`, even i'm using latest version(i made whole app but i never used this option before and it works well)? – Vivek Thummar Mar 05 '21 at 12:38

4 Answers4

98

The answer stated by @Mulvya (thank you!) works: "Add -safe 0 before -i". Then another problem appeared with find STREAM -name '*' -printf "file '$PWD/%p'\n" which returns the empty path as first entry. Changed this for for f in ./*.wav; do echo "file '$PWD/$f'"; done (see https://trac.ffmpeg.org/wiki/Concatenate) and now it seems to work. Hurray!

Eric Reed
  • 329
  • 1
  • 5
  • 17
sers
  • 2,496
  • 2
  • 15
  • 23
  • 1
    You could also change the `find` subcommand to `find STREAM -type f -name '*' -printf "file '$PWD/%p'\n"` (and don’t forget to add the `-safe 0` to the ffmpeg command). – erik Dec 02 '16 at 13:50
22

To answer why, we need to see the operation of ffmpeg's demuxers, which read the multimedia streams from an input file. In this case, we are using "concat", with the following options: (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.

It turns out find . puts a ./ in front of the file. See How to strip leading "./" in unix "find"? for solutions if you don't want to use -safe 0.

qwr
  • 6,786
  • 3
  • 42
  • 72
17

@sers answer is totally right i just show you command so you don't put -safe 0 at anywhere else.

ffmpeg.exe -f concat -safe 0 -i "clips.txt" -c copy "video.mp4"
Manthan Patel
  • 1,105
  • 10
  • 19
17

In my case, double quotes causes the error.

I use ffmpeg -f concat -i concat.txt -c copy output.m4a command, which the concat.txt contains list of input file to concat.

Unsafe file name (double quotes treats as part of filename, -safe 0 can't fix this):

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

Safe file name (single quotes):

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

Safe file name (without quotes):

file song1.m4a
file song2.m4a

The above single quotes and without quotes only safe if it only contains "letters, digits, period(except prefix), underscore and hyphen". So the following common filename will not works:

  • space
  • glyph
  • / (path)
  • prefix period (hidden file)

You still need -safe 0 for that cases.

[Caveat about Quoting and escaping]

You always need escape ' in the part of filename. the reason is because of file Im' .avi will added closing quote automatically to Im' .avi', which is same as file Im' .avi'. The last odd quote in file Im' .avi'''''' also will added closing quotes become file Im' .avi''''''' , so it doesn't have No such file or directory error. I figure out this phenomena because of space no longer need to escape by \ after prefix with single quote, without have to add closing quote.

Despite of above(must escape ' by \ and not escape with "), the escape style is similar to shell. If filename contains single quotes, you can either escape it with I\'m\ .m4a(NOT surrounded with single quotes) style, or 'I'\''m .m4a' OR 'I'\''m'\ '.m4a'(surrounded with single quotes) style, but neither of 'I\'m\ .m4a' nor 'I'm .m4a'.

When you test ffmpeg, be aware of the first line error message Impossible to open may misleading(the file does exist), you need check the second line which is either of No such file or directory(file not exist) or Invalid data found when processing input(invalid media file).

Fruit
  • 6,309
  • 3
  • 42
  • 57
  • 1
    adding **file** in front of each file name resolved my problem when using files from a text file. – hdoghmen Aug 21 '19 at 10:11