ffmpeg concat: „Niebezpieczna nazwa pliku”

92

Próbuję przekonwertować kilka plików mts na duży plik 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

Jakieś pomysły, co tu idzie nie tak? Co w tym kontekście oznacza termin „niebezpieczny plik”?

sers
źródło
51
Dodaj -safe 0przed -i. Zobacz ffmpeg.org/ffmpeg-all.html#Options-31
Gyan

Odpowiedzi:

91

Odpowiedź podana przez @Mulvya (dziękuję!) Działa: „Dodaj -safe 0przed -i”. Następnie pojawił się inny problem, find STREAM -name '*' -printf "file '$PWD/%p'\n"który zwraca pustą ścieżkę jako pierwszy wpis. Zmieniono to dla for f in ./*.wav; do echo "file '$PWD/$f'"; done(patrz https://trac.ffmpeg.org/wiki/Concatenate ) i teraz wydaje się, że działa. Hurra!

sers
źródło
1
Możesz także zmienić komendę findna find STREAM -type f -name '*' -printf "file '$PWD/%p'\n"(i nie zapomnij dodać -safe 0komendy ffmpeg).
erik
17

Aby odpowiedzieć dlaczego, musimy zobaczyć działanie demuxerów ffmpeg, które odczytują strumienie multimedialne z pliku wejściowego. W tym przypadku używamy „concat” z następującymi opcjami: (zarchiwizowane dokumenty)

Ten demukser akceptuje następującą opcję:

safeJeśli jest ustawiona na 1, odrzucaj niebezpieczne ścieżki plików. Ścieżka do pliku jest uważana za bezpieczną, jeśli nie zawiera specyfikacji protokołu i jest względna, a wszystkie komponenty zawierają tylko znaki z przenośnego zestawu znaków (litery, cyfry, kropka, podkreślenie i łącznik) i nie mają kropki na początku komponentu.

Jeśli ustawiona na 0, każda nazwa pliku jest akceptowana.

Wartość domyślna to 1.

-1 jest równoważne 1, jeśli format był sprawdzany automatycznie, a 0 w przeciwnym razie.

Okazuje się, find .że ./przed plikiem znajduje się a. Zobacz Jak usunąć początkowe „./” w uniksowym „znajdowaniu”? rozwiązań, jeśli nie chcesz używać -safe 0.

qwr
źródło
16

Odpowiedź @sers jest całkowicie poprawna, po prostu pokazuję ci polecenie, więc nie umieszczaj -safe 0 nigdzie indziej.

ffmpeg.exe -f concat -safe 0 -i "clips.txt" -c copy "video.mp4"
Manthan Patel
źródło
11

W moim przypadku podwójne cudzysłowy powodują błąd.

Używam ffmpeg -f concat -i concat.txt -c copy output.m4apolecenia, które concat.txtzawiera listę plików wejściowych do konkatacji.

Niebezpieczna nazwa pliku (podwójne cudzysłowy są traktowane jako część nazwy pliku, -safe 0nie można tego naprawić):

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

Bezpieczna nazwa pliku (apostrofy):

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

Bezpieczna nazwa pliku (bez cudzysłowów):

file song1.m4a
file song2.m4a

Powyższe pojedyncze cudzysłowy i bez cudzysłowów są bezpieczne tylko wtedy, gdy zawierają tylko „litery, cyfry, kropkę (oprócz przedrostka), podkreślenie i łącznik” . Zatem następująca popularna nazwa pliku nie będzie działać:

  • przestrzeń
  • glif
  • / (ścieżka)
  • prefiks kropka (plik ukryty)

Nadal potrzebujesz -safe 0do tych przypadków.

[Zastrzeżenie dotyczące cytowania i ucieczki]

Zawsze potrzebujesz znaku ucieczki 'w części nazwy pliku . powodem jestfile Im' .avichęć dodania automatycznie zamykającego cudzysłowuIm' .avi', co jest tym samym cofile Im' .avi'. Ostatni nieparzysty cudzysłówfile Im' .avi''''''również doda cudzysłowy zamykającefile Im' .avi''''''', więc nie maNo such file or directorybłędu. Rozumiem to zjawisko, ponieważ spacja nie musi już uciekać przed\przedrostkiem pojedynczym cudzysłowem, bez konieczności dodawania cudzysłowu zamykającego.

Pomimo wyżej (musi uciec 'przez \nie uciec z "), styl ucieczka jest podobna do powłoki . Jeśli nazwa pliku zawiera pojedyncze cudzysłowy, możesz ją zmienić za pomocą stylu I\'m\ .m4a(NIE w apostrofach) lub stylu 'I'\''m .m4a'OR 'I'\''m'\ '.m4a'(w apostrofach), ale ani na, 'I\'m\ .m4a'ani 'I'm .m4a'.

Podczas testowania ffmpeg pamiętaj, że komunikat o błędzieImpossible to open w pierwszej linii może wprowadzać w błąd (plik istnieje), musisz sprawdzić drugą linię, która jest albo No such file or directory(plik nie istnieje) albo Invalid data found when processing input(nieprawidłowy plik multimedialny).

Owoc
źródło
1
dodanie pliku przed każdą nazwą pliku rozwiązało mój problem podczas używania plików z pliku tekstowego.
hdoghmen