Vuelva a codificar la biblioteca de video en x265 (HEVC) sin pérdida de calidad

43

Estoy tratando de convertir mi biblioteca de videos al formato HEVC para ganar espacio. Ejecuté el siguiente comando en todos los archivos de video en mi biblioteca:

#!/bin/bash
for i in *.mp4;
do 
    #Output new files by prepending "X265" to the names
    avconv -i "$i" -c:v libx265 -c:a copy X265_"$i"
done

Ahora, la mayoría de los videos se convierten bien y la calidad es la misma que antes. Sin embargo, algunos videos que son de muy alta calidad (por ejemplo, una impresión de película que es de 5 GB) pierde calidad: el video está pixelado.

No estoy seguro de qué hacer en este caso. ¿Necesito modificar el crfparámetro en mi línea de comando? ¿O algo mas?

La cosa es que estoy haciendo una conversión masiva. Por lo tanto, necesito un método en el que avconvse ajuste automáticamente cualquier parámetro que necesite ajuste, para cada video.

ACTUALIZACIÓN-1

Descubrí que esa crfes la perilla que necesito ajustar. El CRF predeterminado es 28. Para una mejor calidad, podría usar algo menor que 28. Por ejemplo:

avconv -i input.mp4 -c:v libx265 -x265-params crf=23 -c:a copy output.mp4

Sin embargo, el problema es que para algunos videos el valor CRF de 28 es lo suficientemente bueno, mientras que para algunos videos se requiere un CRF más bajo. Esto es algo que debo verificar manualmente al convertir pequeñas secciones de los videos grandes. Pero en la conversión masiva, ¿cómo verificaría cada video manualmente? ¿Es su forma de avconvajustar CRF de acuerdo con el video de entrada de forma inteligente?

ACTUALIZACIÓN-2

Descubrí que hay una --losslessopción en x265: http://x265.readthedocs.org/en/default/lossless.html .

Sin embargo, no sé cómo usarlo correctamente. Intenté usarlo de la siguiente manera, pero arrojó resultados opuestos (el video estaba aún más pixelado):

avconv -i input.mp4 -c:v libx265 -x265-params lossless -c:a copy output.mp4
shivams
fuente
1
--losslessde hecho, podría agrandar el archivo si decodifica el códec con pérdida previa y luego descubre lo que decodificó sin pérdida. La calidad se mantendrá exactamente igual que la entrada.
Golar Ramblar
2
Si sus fuentes están codificadas en pérdida (lo que es más probable), entonces lo que está tratando de lograr es imposible. Cualquier transcodificación que no sea sin pérdida degradará aún más la calidad (incluso si no es inmediatamente visible para usted) y si convierte de pérdida a pérdida, obtendrá archivos de mayor tamaño.
Sarge Borsch

Respuestas:

58

Desde mi propia experiencia, si no desea absolutamente ninguna pérdida de calidad, sin pérdida es lo que está buscando.

No estoy seguro, avconvpero el comando que escribió parece idéntico al que hago FFmpeg. En FFmpegpuedes pasar el parámetro así:

ffmpeg -i INPUT.mkv -c:v libx265 -preset ultrafast -x265-params lossless=1 OUTPUT.mkv

La mayoría de los x265interruptores (opciones sin valor) se pueden especificar de esta manera (excepto aquellos que solo son CLI, solo se usan con x265binario directamente).

Con eso fuera del camino, me gustaría compartir mi experiencia con la x265codificación. Para la mayoría de los videos (ya sea WMV, o MPEG, o AVC / H.264) que uso crf=23. x265decide el resto de los parámetros y generalmente hace un trabajo lo suficientemente bueno.

Sin embargo, a menudo, antes de comprometerme a transcodificar un video en su totalidad, pruebo mi configuración al convertir una pequeña porción del video en cuestión. Aquí hay un ejemplo, suponga que un archivo mkv con la secuencia 0 es video, la secuencia 1 es audio DTS y la secuencia 2 es un subtítulo:

ffmpeg -hide_banner \
-ss 0 \
-i "INPUT.mkv" \
-attach "COVER.jpg" \
-map_metadata 0 \
-map_chapters 0 \
-metadata title="TITLE" \
-map 0:0 -metadata:s:v:0 language=eng \
-map 0:1 -metadata:s:a:0 language=eng -metadata:s:a:0 title="Surround 5.1 (DTS)" \
-map 0:2 -metadata:s:s:0 language=eng -metadata:s:s:0 title="English" \
-metadata:s:t:0 filename="Cover.jpg" -metadata:s:t:0 mimetype="image/jpeg" \
-c:v libx265 -preset ultrafast -x265-params \
crf=22:qcomp=0.8:aq-mode=1:aq_strength=1.0:qg-size=16:psy-rd=0.7:psy-rdoq=5.0:rdoq-level=1:merange=44 \
-c:a copy \
-c:s copy \
-t 120 \
"OUTPUT.HEVC.DTS.Sample.mkv"

Tenga en cuenta que la línea de señal de barra diagonal inversa se rompe en un comando largo, lo hago para ayudarme a realizar un seguimiento de varios bits de una entrada CLI compleja. Antes de explicarlo línea por línea, la parte donde convierte solo una pequeña porción de un video es la segunda línea y la segunda última línea: -ss 0significa buscar 0 segundos antes de comenzar a decodificar la entrada y -t 120significa dejar de escribir en la salida después de 120 segundos. También puede usar los formatos de hora hh: mm: ss o hh: mm: ss.sss.

Ahora línea por línea:

  1. -hide_bannerevita FFmpegmostrar información de compilación al inicio. Simplemente no quiero verlo cuando me desplazo hacia arriba en la consola;
  2. -ss 0busca 0 segundos antes de comenzar a decodificar la entrada. Tenga en cuenta que si este parámetro se proporciona después del archivo de entrada y antes del archivo de salida, se convierte en una opción de salida y le dice ffmpegque decodifique e ignore la entrada hasta x segundos, y luego comience a escribir en la salida. Como una opción de entrada, es menos precisa (porque la búsqueda no es precisa en la mayoría de los formatos de contenedor), pero casi no lleva tiempo. Como opción de salida, es muy preciso, pero toma una cantidad considerable de tiempo decodificar todo el flujo antes del tiempo especificado, y para propósitos de prueba no desea perder tiempo;
  3. -i "INPUT.mkv": Especifique el archivo de entrada;
  4. -attach "COVER.jpg": Adjunte una portada (imagen en miniatura, póster, lo que sea) a la salida. La portada generalmente se muestra en exploradores de archivos;
  5. -map_metadata 0: Copie todos y cada uno de los metadatos de la entrada 0, que en el ejemplo es solo la entrada;
  6. -map_chapters 0: Copie la información del capítulo (si está presente) de la entrada 0;
  7. -metadata title="TITLE": Establece el título del video;
  8. -map 0:0 ...: Asigna la secuencia 0 de la entrada 0, lo que significa que queremos que la primera secuencia de la entrada se escriba en la salida. Dado que esta transmisión es una transmisión de video, es la primera transmisión de video en la salida , de ahí el especificador de transmisión :s:v:0. Establezca su etiqueta de idioma en inglés;
  9. -map 0:1 ...: Similar a la línea 8, mapee la segunda transmisión (audio DTS) y configure su idioma y título (para una identificación más fácil al elegir entre reproductores);
  10. -map 0:2 ...: Similar a la línea 9, excepto que esta secuencia es un subtítulo;
  11. -metadata:s:t:0 ...: Establecer metadatos para la portada. Esto es necesario para el formato de contenedor mkv;
  12. -c:v libx265 ...: Opciones de códec de video. Es tan largo que lo he dividido en dos líneas. Esta configuración es buena para video bluray de alta calidad (1080p) con bandas mínimas en gradiente (que x265 es una mierda). Es muy probable que sea una exageración para DVD y programas de TV y videos telefónicos. Esta configuración se roba principalmente de esta publicación de Doom9 ;
  13. crf=22:...: Continuación de los parámetros del códec de video. Vea la publicación del foro mencionada anteriormente;
  14. -c:a copy: Copia sobre audio;
  15. -c:s copy: Copiar sobre subtítulos;
  16. -t 120: Deja de escribir en la salida después de 120 segundos, lo que nos da un clip de 2 minutos para previsualizar la calidad de la transcodificación;
  17. "OUTPUT.HEVC.DTS.Sample.mkv": Nombre del archivo de salida. Etiqueto mis nombres de archivo con el códec de video y el códec de audio primario.

Uf. Esta es mi primera respuesta, así que si hay algo que me perdí, por favor deje un comentario. No soy un experto en producción de video, solo soy un tipo que es demasiado vago para ver una película poniendo el disco en el reproductor.

PD. Tal vez esta pregunta pertenece a otro lugar, ya que no está muy relacionada con Unix y Linux.

Yifeng Mu
fuente
2
¡Exactamente lo que estaba buscando! Buena cobertura de opciones. ¿Sabes si ffmpeg se resistirá c:s copysi no hay contenido de subtítulos?
Élder Geek
1
@ElderGeek No, ffmpeg solo dirá algo si esa opción tiene algún efecto.
Yifeng Mu
¿Esta opción genera el tamaño de archivo más pequeño posible para una codificación h265 verdaderamente sin pérdidas? Si no, ¿hay alguna manera de que pueda hacer esto?
Buffer Over Leer el
1
@TheBitByte No creo que haya un nivel de compresión sin pérdidas en h265. Para la opción sin compresión, es justo --lossless. Busqué en vano una conversión sin pérdidas de h264 a h265, y lo que aprendí me dice que es matemáticamente imposible.
Yifeng Mu
1
Realmente debería editar el comando que contiene el --losslesscambio de esta respuesta, porque puesto allí como respuesta a esta pregunta, parece que está diciendo que es una compresión sin pérdidas, lo que es engañoso.
Hashim
8

Recientemente he tenido problemas para transcodificar todo mi catálogo de videos a HEVC. Uso https://github.com/FallingSnow/h265ize con la siguiente configuración.

h265ize -v -m mediano -q 20 -x --no-sao --aq-mode 3 --delete --stats

-v - Salida detallada
-m medio - Velocidad de codificación media (menor calidad más alta, cualquier cosa más lenta que encuentro no vale el tiempo / calidad dif)
-q 20 - el CRF utilizado, 20 es similar a 18 más o menos en x264 pero bueno. Esto es para contenido de 1080p (90% de mi televisor) .Tengo a usar 22 para mis películas 4K
-x - Usar comandos definidos centrales x265
--no-sao desactiva la compensación adaptativa de muestra (mejora la velocidad de codificación)
--aq-mode 3 : use la cuantificación adaptativa con varianza automática, ayuda a las codificaciones de 8 bits, especialmente en áreas oscuras, detiene la mayoría de las bandas que pueden ocurrir (a expensas del tiempo de codificación) -
borra - reemplaza el archivo de codificación con un archivo codificado (prueba antes de usar este )
--estad - Escriba estadísticas en un archivo csv en la raíz de la ruta desde la que corrió.

Las velocidades de codificación son de alrededor de 30 fps (para la mayoría de las cosas de 1080p) en mi equipo. Dual Xeon E5 2687W v2, pero obligo al proceso FFMPEG a no usar el primer lado de uno de los procesadores (es mi servidor Plex, así que tengo que asegurarme de que haya sobrecarga para la transcodificación si es necesario en la reproducción, etc.)

Sí, me llevó un tiempo convertir la mayor parte, y ahora tengo una tarea programada que se ejecuta dos veces al día para codificar las cosas desde ese día hasta x265.

El ahorro de espacio ha sido enorme. Mi SAN inicial estaba en uso de 20Tb, ahora es alrededor de 12 pero obviamente también se ha agregado con 6 meses más de contenido.

También empecé a transcodificar todas mis películas, sin embargo, ese es un proceso continuo, ya que tengo que identificar los niveles de calidad (Radarr afortunadamente las etiqueta muy bien) y usar una de las tres configuraciones de transcodificación:

-m slower -q 18 -x --no-sao --aq-mode 3para transcodificaciones de 720p
-m medium -q 20 -x --no-sao --aq-mode 3para 1080p
-m medium -q 22 -x --no-saopara 2160p

Espero que ayude a algunas personas. Grita si alguien necesita una mano para configurarlo todo. Y antes de codificar todo a x265, piense en la reproducción, si el cliente no es compatible con x265 nativo, entonces la transcade puede ser costosa en términos de CPU y calidad.

Ashleigh-Paul Charlesworth
fuente
Con x265 2.4 y posterior (con las nuevas tablas lambda que dan codificaciones más nítidas), SAO suele ser bueno para la calidad por bitrate. Todavía mancha un poco, pero reduce otros artefactos lo suficiente como para que valga la pena.
Peter Cordes
-q 20no es CRF 20, es constante QP ratecontrol . El modo predeterminado y recomendado, CRF, aumenta el QP en escenas de alta complejidad para que no gaste demasiados bits en escenas que son demasiado difíciles de codificar. (Si desea un QP más cercano al uniforme, suba qcompdel valor predeterminado 0.6 a quizás 0.7 o 0.8. Más cerca de 1.0 está más cerca de CQP.)
Peter Cordes
3

La sintaxis correcta para habilitar el modo sin pérdidas para el codificador x265 en ffmpeg es -x265-params lossless=1(debe agregar =1).

Sin embargo, para la codificación sin pérdida hay mejores opciones de códec. Al probarlo, descubrí que FFV1 comprime mucho mejor (tamaño de archivo = ~ 80% de x265) al menos en algunos tipos de video (si se eligen las mejores configuraciones para ambos códecs). Y también funciona más rápido, y (AFAIK) no está gravado por patentes. Es decir, es superior al H.265 sin pérdidas en todos los sentidos para el archivo de video.

Sarge Borsch
fuente