ffmpeg concat: «Небезопасное имя файла»

92

Пытаемся конвертировать кучу 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

Есть идеи, что здесь не так? Что означает в данном контексте термин «небезопасный файл»?

sers
источник
51
Добавьте -safe 0раньше -i. См. Ffmpeg.org/ffmpeg-all.html#Options-31
Gyan

Ответы:

91

Ответ, указанный @Mulvya (спасибо!), Работает: «Добавить -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 ), и теперь, похоже, он работает. Ура!

sers
источник
1
Вы также можете изменить findподкоманду на find STREAM -type f -name '*' -printf "file '$PWD/%p'\n"(и не забудьте добавить -safe 0к команде ffmpeg).
Эрик
17

Чтобы ответить, почему, нам нужно увидеть работу демультиплексоров ffmpeg, которые читают мультимедийные потоки из входного файла. В этом случае мы используем "concat" со следующими параметрами: (архивные документы)

Этот демультиплексор допускает следующие параметры:

safeЕсли установлено значение 1, отклонять небезопасные пути к файлам. Путь к файлу считается безопасным, если он не содержит спецификации протокола и является относительным, а все компоненты содержат только символы из переносимого набора символов (буквы, цифры, точка, подчеркивание и дефис) и не имеют точки в начале компонента.

Если установлено значение 0, принимается любое имя файла.

По умолчанию 1.

-1 эквивалентно 1, если формат был автоматически проверен, и 0 в противном случае.

Оказывается, find .ставит ./перед файлом. См. Как убрать начало "./" в unix "find"? для решений, если вы не хотите использовать -safe 0.

qwr
источник
16

Ответ @sers совершенно правильный, я просто показываю вам команду, чтобы вы не добавляли -safe 0 в другое место.

ffmpeg.exe -f concat -safe 0 -i "clips.txt" -c copy "video.mp4"
Мантан Патель
источник
11

В моем случае двойные кавычки вызывают ошибку.

Я использую 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ошибок. Я понимаю это явление, потому что больше не нужно убегать\ префикса после одинарной кавычки, без необходимости добавлять закрывающую кавычку.

Несмотря на вышеизложенное (должно экранировать с 'помощью, \а не с помощью "), стиль выхода аналогичен оболочке . Если имя файла содержит одинарные кавычки, вы можете избежать его 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(недопустимый файл мультимедиа).

Фрукты
источник
1
добавление файла перед каждым именем решило мою проблему при использовании файлов из текстового файла.
hdoghmen