Convierta por lotes H.265 mkv a H.264 con ffmpeg para hacer que los archivos sean compatibles para volver a codificar

31

Tengo archivos codificados H.265 que requieren tantos recursos que no funcionan bien y mi software de conversión (mencoder) (actualmente) no es compatible con el formato H.265. ¿Puedo convertirlos a H.264 en un archivo por lotes de línea de comandos para convertir rápidamente los archivos para volver a comprimirlos usando Devede / OGMrip? Al buscar en este sitio no lo he encontrado discutido, así que publicaré lo que considero que es una pregunta útil y responderé a la pregunta.

TheMegolith
fuente

Respuestas:

37

Sí, utilizando ffmpeg.

Abra un terminal y diríjalo al directorio que contiene los archivos codificados H.265, suponiendo que tenga ffmpeginstaladas las bibliotecas apropiadas y que estén en formato MKV, copie y pegue lo siguiente en la ventana del 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

Ahí tienes. Esto se convertirá a h.264 en un contenedor MPG en el mismo directorio.

Explicación de los interruptores de comando:

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

    Esto configura todos los archivos .mkv en un directorio para que se incluyan en el proceso por lotes. Esto se puede cambiar para acomodar la extensión del contenedor de los archivos que desea procesar.

  • ffmpeg -i "$i" Ejecuta el programa ffmpeg y pide que se procesen los archivos.

    • -bsf:v activa el filtro de flujo de bits de video a utilizar

    • h264_mp4toannexb - ¿Está activado el filtro de flujo de bits?

      Convierta un flujo de bits H.264 del modo prefijado de longitud al modo prefijado de código de inicio (como se define en el Anexo B de la especificación H.264 de ITU-T).

      Algunos formatos de transmisión lo requieren, por lo general, el formato de transmisión de transporte MPEG-2 ( mpegts) que procesa MKV h.264 (actualmente) lo requiere; si no está incluido, recibirá un error en la ventana del terminal que le indica que lo use.

    • -sn detiene la transmisión de transmisiones de subtítulos (para aquellos que no quieren subtítulos en su video) Esto es opcional y se puede eliminar.

    • -map 0:0 -map 0:1Le dice a ffmpeg que solo procese las dos primeras transmisiones del archivo ( 0:0es la transmisión de video, 0:1es la primera transmisión de audio del archivo). Esto hace dos cosas, elimina el exceso de secuencias de audio, generalmente la primera secuencia de audio es en inglés, pero no siempre. Se eliminan otras transmisiones, como los subtítulos integrados, lo que reduce el tamaño del archivo. Esta también es una cadena opcional. Puede usar ffprobepara ver las transmisiones disponibles en el archivo. -mapes opcional y se puede descartar del comando.

    • -vcodec libx264 Esto le dice a ffmpeg que codifique la salida a H.264

    • "$i.ts" Guarda la salida en formato .ts, esto es útil para no sobrescribir sus archivos fuente.

  • mv "$i.ts" "$i.mpg"Convierte la extensión de archivo a MPG en el mismo directorio. Esto se puede configurar para enviarlo a cualquier directorio que desee.

  • sleep 3 - permite que el proceso descanse dando tiempo a ffmpeg para poner en cola el siguiente archivo

TheMegolith
fuente
3
¡Excelente! Ahora podemos eliminar los comentarios debajo de la pregunta. Yo diría que sleep 3es innecesario (pero posible útil para terminar el ciclo), y no INPUT=$1tiene sentido ya que lo está ejecutando directamente en un shell interactivo.
muru
11
Considere la posibilidad de copiar el audio en -c:a copylugar de volver a codificar. Además, es 0:0posible que no siempre se refiera al video y 0:1no siempre al audio. Puede usar un especificador de transmisión para evitar posibles problemas: -map 0:v -map 0:asi desea todas las transmisiones de video y audio de la entrada 0, o -map 0:v:0 -map 0:a:0si solo desea las primeras transmisiones de video y audio de la entrada 0. Si solo desea la transmisión de audio en inglés: -map 0:m:language:eng(suponiendo que está etiquetado).
llogan
1
@ LordNeckbeard Voy a votar para que escriba una respuesta completa.
Fran Marzoa
1
@Fran no se dio cuenta de que había tantos votos a favor en ese comentario. Agregué una respuesta usando métodos más simples, menos propensos a errores y más eficientes.
llogan
1
Iría totalmente con simplemente ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT. Algo que uso todos los días y que realmente puedo memorizar en lugar de ese aluvión de banderas sin sentido por el que cada respuesta ffmpeg es tan infame.
Ben Sinclair
20

Conversión por lotes de H.265 a H.264

Estos ejemplos fueron escritos para recientes ffmpeg. Ahórrese algunos problemas y descargue una versión reciente. Luego ponga el ffmpegbinario ~/bino /usr/local/bin(puede que tenga que cerrar la sesión y luego iniciar sesión para que se note).

Salida de 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
  • Este ejemplo se enviará a un directorio llamado h264vids.

  • Este ejemplo supone que sus entradas son .mp4. Si no, cambie la .mp4instancia en el ejemplo a su tipo de archivo de entrada, o simplemente use el codicioso *por sí mismo.

  • Ajuste -crfpor calidad y -presetpor velocidad / eficiencia de codificación. O simplemente elimine estas opciones y use los valores predeterminados que son bastante buenos y deberían ser suficientes para la mayoría (el ejemplo es usar los valores predeterminados para estas opciones). Consulte FFmpeg Wiki: H.264 para obtener más información sobre estas opciones.

Salida MP4

Este es un poco más complicado. Esto realizará una codificación condicional dependiendo de si el audio de entrada es AAC o no. Si el audio de entrada es AAC, el audio se copiará en secuencia (re-muxed) como está y se evitará una nueva codificación innecesaria. Si el audio de entrada no es AAC, se volverá a codificar en AAC.

Aquí hay un script simple que muestra cómo hacer esto usando ffprobey ffmpeg. Cópielo y guárdelo en el directorio que contiene sus videos para convertir, dele permiso de ejecución chmod +x yourscriptnamey luego ejecútelo ./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
  • Este ejemplo se enviará a un directorio llamado h264vids.

  • Este ejemplo supone que sus entradas son .mkv. Si no, cambie la .mkvinstancia en el ejemplo a su tipo de archivo de entrada, o simplemente use el codicioso *por sí mismo.

  • Consulte la nota anterior sobre -crfy -preset.

  • Puede pausar la codificación con ctrl+ zy reanudar con fg.

lema
fuente
0

Teniendo en cuenta las respuestas anteriores, se me ocurrió lo siguiente:

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

Esto supone que los archivos siempre tienen un nombre que termina en 265.mkv. Este final será reemplazado por 264.mkv.

Si su nombre de archivo es diferente, debe adaptar el comando en consecuencia.

kerner1000
fuente