Jak scalić wiele (więcej niż dwa) wideo na Ubuntu?

38

Chcę scalić filmy w rozmiarze dwudziestu (20) partii. Używam komputera z systemem Linux. Filmy są w formacie MP4 i umiarkowanej jakości. Niektórym brakuje nawet strumienia audio. Do tej pory próbowałem ffmpeg, mencoder, cvlc/vlci MP4Box. Chcę napisać skrypt wiersza polecenia, aby to osiągnąć, ponieważ wykonuję przetwarzanie wsadowe.

Głównym problemem jest to, że niektóre rozwiązania, które próbowałem, działają dobrze w przypadku dwóch filmów, niektóre działają dobrze w przypadku filmów ze strumieniem audio, a jeszcze inne działają dobrze w przypadku niektórych innych podzbiorów mojego zestawu wideo. Nie udało mi się jednak znaleźć kompleksowego rozwiązania dla tego zadania.

Dhruv Singal
źródło
2
Nie zadawaj tego samego pytania na wielu stronach SE: superuser.com/questions/928548/…
Maythux
Czy mógłbyś opublikować konkretnie to, czego próbowałeś do tej pory?
ohaal
1
@ohaal Próbowałem użyć różnych metod konkatenacji podanych w ffmpeg, w tym filtrów i protokołów plików. Próbowałem także użyć concatfunkcji cvlc/vlc. Próbowałem również concatfunkcji mencoder. Wszystkie działały częściowo. To w końcu pomogło mi rozwiązać problem.
Dhruv Singal
Tak, wspomniałeś już o narzędziach, miałem na myśli rzeczywiste polecenia, które wykonałeś. Byłoby również świetnie, gdybyś mógł dołączyć polecenie, które zakończyło się jego rozwiązaniem dla ciebie (w twojej odpowiedzi), dla przyszłych gości.
ohaal
Ach, rozumiem twój punkt widzenia. Niestety nie mogę wymienić poleceń ze względu na samą liczbę. Poleceniem, które rozwiązało mój problem, było tomelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal

Odpowiedzi:

41

Używam mkvmergedo łączenia wielu plików MP4 w jeden:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4
Szabolcs Spindler
źródło
3
Lepiej jest użyć rozszerzenia .mkvpliku wyjściowego, ponieważ jest to kontener Matroska niezależnie od tego, jakie rozszerzenie dajesz.
haridsv
Oto sposób instalacji mkvmerge: tipsonubuntu.com
Morgoth
Działa tylko to polecenie mkvmerge. Wszystkie ffmpeg przynajmniej nie działają z przesuniętym dźwiękiem.
42n4
25

Możesz to zrobić za pomocą ffmpeg:

ffmpeg -i concat:"input1.mp4|input2.mp4" output.mp4

referencje i więcej informacji

Maythux
źródło
2
Próbowałem to zrobić. Problem polega na tym, że nie daje to właściwej odpowiedzi. 1. Ścieżki audio są zamazane. 2. Występują pewne zakłócenia na ścieżce wideo.
Dhruv Singal
Użyłem go więcej niż sam próbka, wynik jest wysokiej jakości, może problemem jest jakość wideo źródłowego?
Maythux,
Prawdopodobnie masz rację. To rozwiązało problem: askubuntu.com/a/637179/420614
Dhruv Singal
2
Nie używaj protokołu concat do konkatenacji MP4. Działa tylko z niektórymi formatami, których nie napotyka większość zwykłych użytkowników. Zamiast tego należy użyć demultipleksera konkat lub filtr konkat .
llogan
Próbowałem ffmpeg z 2 plikami mp4 po 30 minut każdy. Mam plik wyjściowy o długości 7 godzin.
Guus
7

To rozwiązało sprawę: https://stackoverflow.com/a/22324018/5014767

meltto świetne narzędzie do wiersza poleceń. Oto strona

Edytuj z komentarzy: Poleceniem, które rozwiązało mój problem, było to melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264

Dhruv Singal
źródło
4

Napisałem mały skrypt powłoki do konkatowania MP4 bez transkodowania przy użyciu ffmpeg.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

To tworzy pliki pośrednie w kontenerze MPEG, a następnie łączy je w MP4.

RawwrBag
źródło
Należy zauważyć, że ten skrypt zawiedzie, jeśli którykolwiek z nazw plików zawiera spacje lub, w niektórych przypadkach, znaki specjalne. W przypadku pętli znacznie lepiej jest używać tylko for f in *.MP4bez użycia ls. (Zawsze powinieneś unikać używania lsskryptów z kilku ważnych powodów; istnieją lepsze opcje). Ponadto używaj cudzysłowów dla zmiennych, chyba że masz pewność, że nie ma spacji ani innych znaków specjalnych, więc "${f}"(lub po prostu "$f") zamiast cudzysłowów $f.
Paddy Landau
CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")nie działa dobrze z nazwami plików 1, 2, 3 ... 10 ... 20. Kończy je parsowanie jako 1, 10 ... 2, 20 ... itd. Sugeruję, CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")że zapewni to porządek .
tisaconundrum
2

Utwórz plik files.txt ze wszystkimi plikami, które chcesz połączyć w następującej formie (linie zaczynające się od # są ignorowane):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Pamiętaj, że mogą to być ścieżki względne lub bezwzględne. Następnie możesz strumieniowo skopiować lub ponownie zakodować swoje pliki:

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
ShaDeRzz
źródło
0

Mój skrypt, wyłącznie w bashi ffmpeg. Ponownie koduje pliki podane w wierszu poleceń w jeden.

Wymaga, aby pliki były tej samej rozdzielczości. Akceptuje różne rotacje metadanych, co ffmpeg concat:nie.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"
Victor Sergienko
źródło
0

Stworzyłem skrypt w języku Python, który przy użyciu moviepy może łączyć także podsekcje (przydatne, jeśli chcesz na przykład usunąć niektóre części z filmu).

Używaj go z:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>
Antonello
źródło
-1

Oprócz odpowiedzi Maythuxa od :

Kilka kontenerów multimedialnych (MPEG-1, MPEG-2 PS, DV) pozwala na konkatenację wideo poprzez jedynie konkatenację zawierających je plików.

Oznacza to, że filmy, które mają zostać połączone, wykorzystują jeden z wyżej wymienionych kontenerów wideo (do których dodam MPEG-4 część 14 dla osobistego doświadczenia), możesz po prostu:

cat video1.ext video2.ext video3.ext > video4.ext
kos
źródło
1
Próbowałem tego, ale zwraca tylko pierwsze wideo jako wyjście. Czytałem gdzieś, że to nie działa, chociaż nie pamiętam uzasadnienia tego.
Dhruv Singal
@DhruvSingal Tak, mogę to potwierdzić, próbowałem tego na dwóch filmach MP4 z dokładnie takim samym kodowaniem wideo / audio i ponieważ mogłem przeglądać tylko pierwszy film. Co wydaje się rozsądne, ale jestem pewien, że zrobiłem to wcześniej z kilkoma filmami MP4. Być może pamięć nie służy tutaj dobrze lub istnieją inne wymagania, aby to działało. Chcę to zbadać, ponieważ jestem również zainteresowany, jeśli coś znajdę, zaktualizuję odpowiedź i dodam komentarz
Kos
Musimy jakoś zmienić metadane na początku pierwszego filmu, aby objąć całą długość połączonego filmu i prawdopodobnie inne rzeczy. Tylko kilka plików MPEG4 pozwala mi zobaczyć metadane ...
Ken Mollerup