Batch mengkonversi H.265 mkv ke H.264 dengan ffmpeg untuk membuat file yang kompatibel untuk pengkodean ulang

31

Saya memiliki file yang disandikan H.265 yang begitu padat sumber daya sehingga tidak dapat diputar dengan baik dan perangkat lunak konversi saya (mencoder) tidak (saat ini) mendukung format H.265. Dapatkah saya mengonversinya menjadi H.264 dalam file batch baris perintah untuk dengan cepat mengkonversi file untuk kompresi ulang menggunakan Devede / OGMrip? Setelah mencari situs ini saya belum menemukannya sehingga saya akan memposting apa yang saya rasa merupakan pertanyaan dan jawaban yang berguna untuk pertanyaan itu.

TheMegolith
sumber

Jawaban:

37

Ya, menggunakan ffmpeg.

Buka terminal dan arahkan ke direktori yang berisi file yang dikodekan H.265, dengan asumsi Anda memiliki ffmpegdan pustaka yang sesuai diinstal dan dengan asumsi mereka dalam copy format MKV dan rekatkan yang berikut ke jendela terminal.

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

Itu dia. Ini akan dikonversi ke h.264 dalam wadah MPG di direktori yang sama.

Penjelasan dari sakelar perintah:

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

    Ini mengatur semua file .mkv dalam direktori untuk dimasukkan dalam proses batch. Ini dapat diubah untuk mengakomodasi ekstensi kontainer dari file yang ingin Anda proses.

  • ffmpeg -i "$i" Menjalankan ffmpeg program dan meminta file diproses.

    • -bsf:v mengaktifkan filter aliran bit video untuk digunakan.

    • h264_mp4toannexb - Apakah filter bit stream yang diaktifkan.

      Konversi bitstream H.264 dari mode awalan panjang untuk memulai mode kode awalan (sebagaimana didefinisikan dalam Lampiran B dari spesifikasi ITU-T H.264).

      Ini diperlukan oleh beberapa format streaming, biasanya format stream transport MPEG-2 ( mpegts) yang memproses MKV h.264 (saat ini) mengharuskan ini, jika tidak termasuk Anda akan mendapatkan kesalahan di jendela terminal yang memerintahkan Anda untuk menggunakannya.

    • -sn menghentikan streaming subtitle stream (bagi mereka yang tidak ingin subtitle dalam video mereka) Ini adalah opsional dan dapat dihapus.

    • -map 0:0 -map 0:1Memberitahu ffmpeg untuk hanya memproses dua aliran pertama dari file ( 0:0adalah aliran video, 0:1adalah aliran audio pertama dari file). Ini melakukan dua hal, menghapus aliran audio berlebih, biasanya aliran audio pertama adalah bahasa Inggris tetapi tidak selalu. Streaming lain seperti subtitle tertanam dihapus mengurangi ukuran file. Ini juga merupakan string opsional. Anda dapat menggunakan ffprobeuntuk melihat stream yang tersedia di file. -mapbersifat opsional dan dapat dibuang dari perintah.

    • -vcodec libx264 Ini memberitahu ffmpeg untuk menyandikan output ke H.264

    • "$i.ts" Menyimpan output ke format .ts, ini berguna agar tidak menimpa file sumber Anda.

  • mv "$i.ts" "$i.mpg"Mengonversi ekstensi file ke MPG di direktori yang sama. Ini dapat diatur untuk mengirimkannya ke direktori yang Anda suka.

  • sleep 3 - memungkinkan proses untuk beristirahat memberikan waktu ffmpeg untuk mengantri file berikutnya

TheMegolith
sumber
3
Luar biasa! Sekarang kita dapat menghapus komentar di bawah pertanyaan. Saya akan mengatakan sleep 3itu tidak perlu (tapi mungkin berguna untuk mengakhiri loop), dan INPUT=$1tidak ada artinya karena Anda menjalankan ini secara langsung dalam shell interaktif.
muru
11
Pertimbangkan streaming menyalin audio dengan -c:a copybukan pengodean ulang. Selain itu, 0:0mungkin tidak selalu merujuk ke video, dan 0:1mungkin tidak selalu merujuk ke audio. Anda dapat menggunakan penspesifikasi aliran untuk menghindari masalah potensial: -map 0:v -map 0:ajika Anda ingin semua video dan audio stream dari input 0, atau -map 0:v:0 -map 0:a:0jika Anda hanya ingin video dan audio stream pertama dari input 0. Jika Anda hanya ingin stream audio bahasa Inggris: -map 0:m:language:eng(dengan asumsi diberi label).
Logan
1
@ LordNeckbeard saya akan memilih Anda untuk menulis jawaban yang lengkap.
Fran Marzoa
1
@ Fran Tidak memperhatikan ada banyak upvotes pada komentar itu. Saya menambahkan jawaban dengan menggunakan metode yang lebih sederhana, lebih sedikit kesalahan, dan lebih efisien.
llogan
1
Saya benar-benar akan pergi dengan sederhana ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT. Sesuatu yang saya gunakan setiap hari dan benar-benar dapat menghafal yang bertentangan dengan rentetan bendera tidak berarti yang mana setiap jawaban ffmpeg begitu terkenal.
Ben Sinclair
20

Konversi batch H.265 ke H.264

Contoh-contoh ini ditulis untuk saat ini ffmpeg. Simpan sendiri beberapa masalah dan unduh versi terbaru. Kemudian masukkan ffmpegbiner ~/binatau /usr/local/bin(Anda mungkin harus logout lalu login agar diperhatikan).

Output 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
  • Contoh ini akan menampilkan ke direktori bernama h264vids.

  • Contoh ini mengasumsikan input Anda .mp4. Jika tidak, ubah .mp4instance pada contoh menjadi tipe file input Anda, atau gunakan saja serakah *itu sendiri.

  • Menyesuaikan -crfkualitas dan -presetkecepatan / efisiensi penyandian. Atau hapus saja opsi-opsi ini dan gunakan default yang cukup baik dan cukup untuk sebagian besar (contohnya adalah menggunakan nilai default untuk opsi ini). Lihat FFmpeg Wiki: H.264 untuk info lebih lanjut tentang opsi ini.

Output MP4

Yang ini sedikit lebih rumit. Ini akan melakukan pengkodean bersyarat tergantung apakah input audio AAC atau tidak. Jika input audio AAC maka audio akan disalin streaming (muxed kembali) apa adanya dan re-encoding yang tidak perlu dihindari. Jika audio input bukan AAC maka akan disandikan ulang ke AAC.

Berikut ini skrip sederhana yang menunjukkan cara melakukan ini menggunakan ffprobedan ffmpeg. Salin dan simpan ke direktori yang berisi video Anda untuk dikonversi, berikan izin untuk menjalankannya chmod +x yourscriptname, lalu jalankan dengan ./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
  • Contoh ini akan menampilkan ke direktori bernama h264vids.

  • Contoh ini mengasumsikan input Anda .mkv. Jika tidak, ubah .mkvinstance pada contoh menjadi tipe file input Anda, atau gunakan saja serakah *itu sendiri.

  • Lihat catatan di atas tentang -crfdan -preset.

  • Anda dapat menjeda pengodean dengan ctrl+ zdan melanjutkan dengan fg.

llogan
sumber
0

Mempertimbangkan jawaban sebelumnya, saya datang dengan yang berikut:

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

Ini mengasumsikan, bahwa file selalu memiliki nama yang berakhir dengan 265.mkv. Akhiran ini akan diganti dengan 264.mkv.

Jika penamaan file Anda berbeda, Anda perlu menyesuaikan perintah yang sesuai.

kerner1000
sumber