Konwersja wsadowa H.265 mkv na H.264 za pomocą ffmpeg, aby pliki były kompatybilne z ponownym kodowaniem

31

Mam pliki zakodowane w formacie H.265, które są tak intensywne pod względem zasobów, że nie odtwarzają się dobrze, a moje oprogramowanie do konwersji (mencoder) nie obsługuje (obecnie) formatu H.265. Czy mogę przekonwertować je na H.264 w pliku wsadowym wiersza polecenia, aby szybko przekonwertować pliki do ponownej kompresji za pomocą Devede / OGMrip? Podczas przeszukiwania tej witryny nie znalazłem jej omówionej, więc opublikuję to, co uważam za przydatne pytanie i odpowiedź na to pytanie.

TheMegolith
źródło

Odpowiedzi:

37

Tak, używając ffmpeg.

Otwórz terminal i skieruj go do katalogu zawierającego pliki zakodowane w H.265, zakładając, że masz ffmpegzainstalowane i odpowiednie biblioteki oraz że są w formacie MKV, skopiuj i wklej poniższe w oknie terminala.

INPUT="$1"
for i in *.mkv ; do
    ffmpeg -i "$i" -bsf:v h264_mp4toannexb -sn -map 0:0 -map 0:1 -vcodec libx264 "$i.ts"
    mv "$i.ts" "$i.mpg"
    sleep 3
done

Masz to. Spowoduje to konwersję do h.264 w kontenerze MPG w tym samym katalogu.

Objaśnienie przełączników poleceń:

  • for i in *.mkv ; do ... done

    Spowoduje to skonfigurowanie wszystkich plików .mkv w katalogu, które zostaną uwzględnione w procesie wsadowym. Można to zmienić, aby uwzględnić rozszerzenie kontenera plików, które chcesz przetworzyć.

  • ffmpeg -i "$i" Wykonuje program ffmpeg i wzywa do przetworzenia plików.

    • -bsf:v aktywuje używany filtr strumienia bitów wideo.

    • h264_mp4toannexb - Czy filtr strumienia bitów jest włączony.

      Konwertuj strumień bitów H.264 z trybu z prefiksem długości, aby uruchomić tryb z prefiksem kodu (zgodnie z definicją w załączniku B do specyfikacji ITU-T H.264).

      Jest to wymagane przez niektóre formaty przesyłania strumieniowego, zwykle mpegtswymaga tego format strumienia transportu MPEG-2 ( ) przetwarzający MKV h.264 (obecnie), jeśli nie zostanie uwzględniony, pojawi się błąd w oknie terminala instruujący o jego użyciu.

    • -sn zatrzymuje przesyłanie strumieni napisów (dla tych, którzy nie chcą napisów w swoim filmie) Jest to opcjonalne i można je usunąć.

    • -map 0:0 -map 0:1Informuje ffmpeg, aby przetwarzał tylko dwa pierwsze strumienie pliku ( 0:0jest strumieniem wideo, 0:1jest pierwszym strumieniem audio pliku). Robi to dwie rzeczy, usuwa nadmiar strumieni audio, zwykle pierwszy strumień audio jest angielski, ale nie zawsze. Inne strumienie, takie jak osadzone napisy, są usuwane, co zmniejsza rozmiar pliku. Jest to również opcjonalny ciąg. Możesz użyć, ffprobeaby wyświetlić strumienie dostępne w pliku. -mapjest opcjonalny i można go odrzucić z polecenia.

    • -vcodec libx264 To każe ffmpeg zakodować dane wyjściowe do H.264

    • "$i.ts" Zapisuje dane wyjściowe w formacie .ts, jest to przydatne, aby nie zastępować plików źródłowych.

  • mv "$i.ts" "$i.mpg"Konwertuje rozszerzenie pliku na MPG w tym samym katalogu. Można to skonfigurować, aby przesyłać go do dowolnego katalogu, który ci się podoba.

  • sleep 3 - pozwala procesowi na odpoczynek, dając ffmpeg czas na umieszczenie w kolejce następnego pliku

TheMegolith
źródło
3
Doskonały! Teraz możemy usunąć komentarze pod pytaniem. Powiedziałbym, że sleep 3jest niepotrzebny (ale możliwy do zakończenia pętli) i INPUT=$1nie ma znaczenia, ponieważ uruchamiasz go bezpośrednio w interaktywnej powłoce.
muru,
11
Rozważ skopiowanie strumienia za pomocą -c:a copyzamiast ponownego kodowania. Ponadto 0:0nie zawsze może odnosić się do wideo i 0:1nie zawsze może odnosić się do dźwięku. Możesz użyć specyfikatora strumienia, aby uniknąć potencjalnych problemów: -map 0:v -map 0:ajeśli chcesz wszystkich strumieni wideo i audio z wejścia 0 lub -map 0:v:0 -map 0:a:0jeśli chcesz tylko pierwszych strumieni wideo i audio z wejścia 0. Jeśli chcesz tylko angielski strumień audio: -map 0:m:language:eng(zakładając, że jest oznaczony).
llogan
1
@ LordNeckbeard Głosuję za napisaniem pełnej odpowiedzi.
Fran Marzoa
1
@Fran Nie zauważyłem, że było tak wiele pozytywnych opinii na temat tego komentarza. Dodałem odpowiedź przy użyciu prostszych, mniej podatnych na błędy i bardziej wydajnych metod.
llogan
1
Po prostu bym po prostu poszedł ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT. Coś, z czego korzystam na co dzień i które potrafię zapamiętać, w przeciwieństwie do zapory bezsensownych flag, dla której każda odpowiedź ffmpeg jest tak niesławna.
Ben Sinclair,
20

Konwersja partii z H.265 na H.264

Te przykłady zostały napisane dla ostatnich ffmpeg. Zaoszczędź sobie kłopotów i pobierz najnowszą wersję. Następnie umieść ffmpegplik binarny w ~/binlub /usr/local/bin(może być konieczne wylogowanie, a następnie zalogowanie się, aby zostać zauważonym).

Wyjście Matroska

mkdir h264vids
for f in *.mp4; do ffmpeg -i "$f" -map 0 -c copy -c:v libx264 -crf 23 -preset medium h264vids/"${f%.*}.mkv"; done
  • Ten przykład wyświetli się w katalogu o nazwie h264vids.

  • W tym przykładzie założono, że dane wejściowe są .mp4. Jeśli nie, zmień .mp4instancję w przykładzie na typ pliku wejściowego lub po prostu użyj sam chciwości *.

  • Dostosuj -crfjakość i -presetszybkość / wydajność kodowania. Lub po prostu usuń te opcje i zastosuj wartości domyślne, które są dość dobre i powinny wystarczyć dla większości (w przykładzie zastosowano wartości domyślne dla tych opcji). Zobacz FFmpeg Wiki: H.264, aby uzyskać więcej informacji na temat tych opcji.

Wyjście MP4

Ten jest trochę bardziej skomplikowany. Spowoduje to wykonanie kodowania warunkowego w zależności od tego, czy wejściowym dźwiękiem jest AAC, czy nie. Jeśli wejściowym dźwiękiem jest AAC, wówczas dźwięk zostanie skopiowany strumieniowo (ponownie zmiksowany) tak, jak jest, i można uniknąć niepotrzebnego ponownego kodowania. Jeśli wejściowy dźwięk nie jest AAC, zostanie ponownie zakodowany w AAC.

Oto prosty skrypt pokazujący, jak to zrobić za pomocą ffprobei ffmpeg. Skopiuj i zapisz go w katalogu zawierającym filmy, które chcesz przekonwertować, daj mu uprawnienia chmod +x yourscriptname, a następnie uruchom je ./yourscriptname.

#!/bin/bash

mkdir h264vids

for f in *.mkv
do
  audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
  if [ "$audioformat" = "aac" ]; then
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a copy -movflags +faststart h264vids/"${f%.*}.mp4"
  else
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart h264vids/"${f%.*}.mp4"
  fi
done
  • Ten przykład wyświetli się w katalogu o nazwie h264vids.

  • W tym przykładzie założono, że dane wejściowe są .mkv. Jeśli nie, zmień .mkvinstancję w przykładzie na typ pliku wejściowego lub po prostu użyj sam chciwości *.

  • Uwaga powyżej dotycząca -crfi -preset.

  • Możesz wstrzymać kodowanie za pomocą ctrl+ zi wznowić za pomocą fg.

Llogan
źródło
0

Biorąc pod uwagę poprzednie odpowiedzi, wpadłem na następujące:

for file in *265.mkv; do nice -n19 ffmpeg -i $file -c copy -c:v libx264 ${file/%265.mkv/264.mkv}; done

Zakłada się, że pliki mają zawsze nazwę kończącą się na 265.mkv. To zakończenie zostanie zastąpione przez 264.mkv.

Jeśli nazwa pliku jest inna, musisz odpowiednio dostosować polecenie.

kerner1000
źródło