Próbuję połączyć dwa pliki mp4 za pomocą ffmpeg. Potrzebuję, aby był to proces automatyczny, dlatego wybrałem ffmpeg. Konwertuję dwa pliki na pliki .ts, a następnie łączę je, a następnie próbuję zakodować ten skonsolidowany plik .ts. Pliki są zakodowane w formacie h264 i aac i mam nadzieję, że jakość pozostanie taka sama lub jak najbardziej zbliżona do oryginału.
ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4
Niestety otrzymuję następujący komunikat o błędzie wracający z ffmpeg podczas kodowania:
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s
av_interleaved_write_frame(): Error while opening file
Dzieje się tak mniej więcej w połowie kodowania, co sprawia, że myślę, że nie można połączyć dwóch plików .ts i sprawić, by działało.
ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv
(mkv akceptuje więcej kodeków niż mp4, ale możesz także wypróbować go z mp4).-safe 0
Jest dla nowszych wersji ffmpeg narzekających nazwy plików uznanych za niebezpieczne , i-type f
to tylko dla wymieniając pliki. Dodałem,| sort
aby posortować pliki alfabetycznie; ponieważfind
odczytuje je w kolejności zapisanej w systemie plików. Działa również w przypadku plików z białymi spacjami.ffmpeg -i "concat:input1|input2" -codec copy output
. Nie ma potrzeby ucieczki od znaku potoku.DLA PLIKÓW MP4
W przypadku plików .mp4 (które otrzymałem z DailyMotion.com: 50-minutowy odcinek telewizyjny, do pobrania tylko w trzech częściach, jako trzy pliki wideo .mp4) poniższe rozwiązanie było skutecznym rozwiązaniem dla systemu Windows 7 i NIE wymaga ponownego kodowania akta.
Zmieniłem nazwy plików (na file1.mp4 , file2.mp4 , file3.mp4 ), tak aby części były w odpowiedniej kolejności do oglądania całego odcinka telewizji.
Następnie utworzyłem prosty plik wsadowy (concat.bat) o następującej treści:
Plik wsadowy i ffmpeg.exe , musi być zarówno umieścić w tym samym folderze co pliki .mp4 mają być połączone. Następnie uruchom plik wsadowy. Uruchomienie zajmuje zwykle mniej niż dziesięć sekund.
.
Dodatek (2018/10/21) -
Jeśli to, czego szukałeś, to metoda określania wszystkich plików mp4 w bieżącym folderze bez konieczności ponownego wpisywania, spróbuj tego w pliku wsadowym systemu Windows ( MUSI zawierać opcję -safe 0 ):
Działa to w systemie Windows 7 w pliku wsadowym. Nie próbuj używać go w wierszu poleceń, ponieważ działa tylko w pliku wsadowym!
źródło
C:\blah>type mylist.txt<ENTER>
(aby zobaczyli zawartość tego pliku). Następnieffmpeg -f concat -i mylist.txt -c copy output.mp4<ENTER>
powinieneś również dołączyć referencję trac.ffmpeg.org/wiki/Concatenate (ta referencja używa nawet tej samej nazwy pliku, mylist.txt)-i
parametrów. W Linuksie zrobiłem to:ls -1 P1041*.mp4 | sed s/"P"/" file P"/g > mylist.txt
co jest jeszcze fajniejsze niż kodowanie skryptu wsadowego. W każdym razie-c copy
działa bardzo szybko (czego nie byłem świadomy) i to jest prawdziwa magia tej odpowiedzi.Oto szybki (zajmuje mniej niż 1 minuta) i bezstratny sposób na zrobienie tego bez potrzeby używania plików pośrednich:
„Ls” zawiera pliki do przyłączenia „perl” tworzy plik konkatenacji w locie do potoku Część „-i -” informuje ffmpeg, aby czytał z potoku
(uwaga - w moich plikach nie było spacji ani dziwnych rzeczy - będziesz potrzebował odpowiedniego ucieczki od powłoki, jeśli chcesz zrobić ten pomysł z „twardymi” plikami).
źródło
ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne '$_ =~ s/\n$//; print "file '"'"'$_'"'"'\n"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4
jeśli twoje pliki są dobrze nazwane i uporządkowane. Działa świetnie dla mnie na OS X, dokładnie to, czego chciałem.ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv
(mkv akceptuje więcej kodeków niż mp4, ale możesz także wypróbować go z mp4).-safe 0
Jest dla nowszych wersji ffmpeg narzekających nazwy plików uznanych za niebezpieczne , i-type f
to tylko dla wymieniając pliki. Dodałem,| sort
aby posortować pliki alfabetycznie; ponieważfind
odczytuje je w kolejności zapisanej w systemie plików. Działa również w przypadku plików z białymi spacjami.ffmpeg
aby działał:-protocol_whitelist file,tcp,http,pipe
dla plików MP4:
Jeśli nie są one dokładnie takie same (100% taki sam kodek, ta sama rozdzielczość, ten sam typ) plików MP4, najpierw musisz je przekodować do strumieni pośrednich:
UWAGA! : Dane wyjściowe będą jak pierwszy plik (a nie drugi)
źródło
Próbowałem połączyć trzy
.mp3
pliki audio w jeden.m4a
plik i to polecenie ffmpeg działa.Komenda wejściowa:
Znaczenie: "-filter_complex concat = n = 3: v = 0: a = 1" :
Aby uzyskać więcej informacji: użyj
ffmpeg -h full
opcji drukowania wszystkich opcji (w tym wszystkich opcji specyficznych dla formatu i kodeka, bardzo długo)źródło
-f concat -safe 0 -i "file.txt" -c copy -y "OutPut.mp4"
to się konkatuje, ale kiedy niektóre filmy są z dźwiękiem, a niektóre bez dźwięku, nie działa, jak mogę to rozwiązać. Dzięki -Skończyło się na tym, że używałem mpg jako formatu pośredniego i zadziałało (UWAGA to niebezpieczny przykład, -qscale 0 ponownie zakoduje wideo ...)
źródło
-sameq
został usunięty. Użyj-qscale 0
zamiast tego.-sameq
nie oznacza „tej samej jakości” i został usunięty z ffmpeg, jak wspomniano w @XavierHo.concat
polecenia w ffmpeg, jak to robi @rogerdpack powyżej.Szczegółową dokumentację na temat różnych sposobów łączenia w ffmpeg można znaleźć tutaj .
Możesz użyć „filtru Concat” do szybkiego połączenia.
Wykonuje ponowne kodowanie. Ta opcja jest najlepsza, gdy wejścia mają różne formaty wideo / audio.
W przypadku łączenia 2 plików:
W przypadku łączenia 3 plików:
Działa to tak samo, jak dla wielu typów plików wejściowych.
źródło
ouput.mp4
szybkość transmisji mojego wideo jest znacznie niższa niż szybkość transmisji wideo na wejściuOdkryłem, że operator potoku nie działał dla mnie, gdy użyłem opcji 3 do konkatowania kilku MP4 na komputerze Mac w przyjętej odpowiedzi.
Następujący jednowierszowy działa na komputerze Mac (High Sierra) w celu połączenia plików MP4, bez konieczności tworzenia plików pośrednich.
ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
źródło
Tutaj 2 rozwiązania czysto bash używają tylko
ffmpeg
i nie używająJednowarstwowe rozwiązanie przy użyciu
ls
Funkcja, która przyjmuje argumenty 0 lub 2+
Uwaga: wypróbowałem kilka rozwiązań w tym wątku i żadne mnie nie usatysfakcjonowało
źródło
na podstawie odpowiedzi Rogerdpack i Ed999 stworzyłem swoją wersję .sh
łączy wszystkie
*.mp4
pliki w bieżącym folderze wjoined-out.mp4
testowany na Mac.
wynikowy rozmiar pliku to dokładna suma moich 60 przetestowanych plików. Nie powinno być żadnej straty. Dokładnie to, czego potrzebowałem
źródło
to zadziałało dla mnie (w systemie Windows)
przykład...
Pyton
Używając kodu Pythona, aby zrobić to z tyloma plikami mp4, które znajdują się w folderze (zainstaluj python z python.org, skopiuj i wklej i zapisz ten kod w pliku o nazwie mp4.py i uruchom go z cmd otwartego w folderze z pythonem plik mp4.py i wszystkie pliki mp4 w folderze zostaną połączone)
Wersja 2 z Python
Zaczerpnięte z mojego postu na moim blogu , tak to robię w Pythonie:
źródło
Dla
.mp4
plików, znalazłem to działa lepiej i szybciej korzystać z narzędzia wiersza polecenia opensource:mp4box
. Następnie możesz użyć tego w ten sposób:Pobierz go tutaj na większość platform: https://gpac.wp.imt.fr/mp4box/
źródło
Oto skrypt, który napisałem, aby połączyć kilka GoPro MP4 w 720p MP4. Mam nadzieję, że to pomoże.
źródło
Z dokumentacji tutaj: https://trac.ffmpeg.org/wiki/Concatenate
To podejście działa na wszystkich platformach.
Potrzebowałem możliwości kapsułkowania tego w skrypcie wieloplatformowym, więc skorzystałem
fluent-ffmpeg
i wymyśliłem następujące rozwiązanie:źródło
źródło
Scalanie wszystkich plików MP4 z bieżącego katalogu
Osobiście lubię nie tworzyć plików zewnętrznych, które muszę później usunąć, więc moje rozwiązanie było następujące, które zawiera listę numeracji plików (np.
file_1_name, file_2_name, file_10_name, file_20_name, file_100_name
...)źródło
Po różnych próbach poniżej skrypt działał dla mnie w Windows 10 PowerShell.
Tutaj pierwsze dwa wiersze tworzą plik tekstowy temp.txt, który ma następującą treść
Trzeci, czwarty wiersz sprawdza, czy ffmpeg jest dostępny na ścieżce i utwórz plik „join.mp4”
Kluczowe różnice w stosunku do innych odpowiedzi są następujące
w przypadku mojego powyższego pliku mp4 może być konieczne użycie innych alternatyw, takich jak poniżej, w zależności od kodowania wideo.
Wszystkie takie możliwe filtry Bitstream można znaleźć na stronie https://ffmpeg.org/ffmpeg-bitstream-filters.html
źródło
Oto moja metoda dołączania do katalogu pełnego plików MP4 przy użyciu podstawiania poleceń i filtru concat wideo (spowoduje to ponowne kodowanie) - pomyślałem, że ktoś inny skorzysta z tego jednowierszowego, szczególnie jeśli masz wiele plików (po prostu dołączył do 17 plików za jednym zamachem):
Uwaga: to polecenie łączy twoje pliki w kolejności, w której są nazwane (tj. W takiej samej kolejności, w jakiej są wyświetlane, jeśli uruchomisz
ls *.mp4
) - w moim przypadku każdy z nich miał numer ścieżki, więc działało świetnie.źródło
Protokół concat opisany tutaj; https://trac.ffmpeg.org/wiki/Concatenate#protocol
Po wdrożeniu za pomocą nazwanych potoków, aby uniknąć plików pośrednich
Jest bardzo szybki (czytaj: natychmiastowy), nie ma opuszczonych ramek i działa dobrze.
Pamiętaj, aby usunąć nazwane pliki potoków i pamiętaj, aby sprawdzić, czy wideo to H264 i AAC, które możesz zrobić za pomocą
ffmpeg -i filename.mp4
(sprawdź h264 i wspomnienia)źródło
Akceptowana odpowiedź w formie skryptu PowerShell wielokrotnego użytku
źródło