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.


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

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


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


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.


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

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}"

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>

-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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.