[Linux] Transcoder un Concert Blu-ray avec ffmpeg (HEVC + OPUS) x265

TABLE DES MATIÈRES

Introduction & généralités

On va voir comment transcoder en HEVC (x265) le rip blu-ray d'un concert à partir de son format natif. Avant tout, il est bien de savoir que le principe est transposable et que c'est un bon moyen de compresser un .mkv ou .mp4. encodé en H.264. J'ai d'ailleurs créé un petit script Nautilus dédié à cet effet : H.264 to H265

#!/bin/sh
IFS='
'
for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
      destination="${file%.*}best_crf22_hevc_X265.mkv"
      ffmpeg -i $file -c:v libx265 -preset medium -x265-params crf=22 -c:a libopus -b:a 128k $destination   
done
notify-send --urgency=low -i totem "Transcodage Terminé"

N'ayant pas de système 5.1, je ne vais garder que la piste 2.0 et la partie vidéo. Aussi je ne suis pas intéressé par le fichier audio HD qui prend trop de place. Pour cette sauvegarde j'utiliserai un "nouveau" codec audio, Opus, avec un bitrate suffisant pour être exploité sur une chaîne hi-fi. Cependant, Je n'oublierai personne en détaillant la méthode pour les pistes 5.1.

Autant le dire tout de suite, les codecs utilisés ici sont loin d’être compatibles avec la plupart des players du marché, comme ceux intégrés aux TV et certains appareils comme des tablettes peu puissantes etc... Youtube ne les accepte pas encore en upload , d’après un test récent . Dans ce cas, il faudra par exemple utiliser le VP9 le codec "maison" de Google. Concernant HEVC, il faut savoir que les temps d'encodage sont assez long comparé au H.264, mais le gain de place est substantiel et c'est ce qui m' intéresse principalement car je n'ai pas d'écran 4k. Sur un PC récent il n'y aura pas d'incompatibilité. J'ai fait pas mal de tests en lecture (1080p) sur des générations différentes de Laptop et fixes, Celeron SandyBridge (1366x768), Athlon 5350 AM1 (1920x1080), dual core  U9600 (max 1.6 Ghz/1600x900), il n'y a pas de soucis en règle générale, quelques exceptions tout de même... Les players Vidéo sur Linux ont enfin intégrés le codec, du coup les dernières versions de VLC ou Totem sont compatibles, plus besoin d'ajouter de PPA ou autre. Autre avantage, c'est multi-thread nativement, pas besoin d'adapter la commande au nombre de cœurs de la machine pour bénéficier de la puissance de son matériel, comme c'est le cas avec le H.264. Il est à noter que le temps d'encodage est directement lié à la puissance du processeur. Ça peut être assez long sur un laptop milieu de gamme. Il doit y avoir moyen de réduire les temps d'encodage avec l'accélération GPU, mais je ne m'y suis pas penché, cette activité étant pour moi occasionnelle. Pour donner un ordre d'idée, quand je réalise mes encodages avec un I5 2500K overclocké @4.2 Ghz, il faut compter entre 2 et 3 heures par session, sur mon PC à base de AM1 (athlon 5350), une bonne nuit a été nécessaire (10 -12 heures).

Suite à une discussion avec Dada sur Diaspora, j'ai été le mois dernier, confronté à la problématique de trouver le meilleur moyen de compresser une vidéo tout en conservant une très bonne qualité d'image, je me suis intéressé au HEVC (High Efficiency Vidéo Codec) qu'on retrouvera aussi sous les noms x265 ou H.265, le successeur de H.264. Jusqu'à présent j'utilisais le VP8 ou H.264 pour encoder les .MOV de mon APN. Le genre de Codec proprio qui prend 1 Go pour 3 ou 4 minutes de vidéo en 720p, calibré pour qu'on achète de la SD en masse... Inconscients consommateurs que nous sommes !! Utilisons du libre, c'est bon aussi pour le porte monnaie!

Le H264 est encore d'actualité pour des raisons de compatibilité, mais n'est plus celui qui apporte le meilleur ratio qualité/poids. HEVC est 50-75% plus efficace que H.264 pour la même qualité visuelle.

Si vous souhaitez entrer plus dans les détails, vous trouverez, en plus de la doc ffmpeg, dans le dernier Linux Pratique Essentiel 95 (mai/juin) un article de 6 pages, qui traite du HEVC. Il y est question de conversion de rushs vidéo .MOV vers HEVC. Ici n'est pas la question, j' y reviendrais une autre fois en proposant quelques scripts Nautilus , (ayant édité le billet, le script Nautilus posté plus haut est tout à fait fonctionnel pour le cas présent) utilisant ffmpeg ou mencoder. Mon but ici est de documenter une méthode qui aura un bon rendu dans la plupart des cas, sans trop se faire chauffer les neurones avec la finesse des réglages et qui pourra facilement être adaptée pour l'encodage de films.

Prérequis

avoir installé ffmpeg ou avconv.

Lister les flux

Pour savoir ce qu'il y a à l’intérieur du container on utilise la commande ffprobe (pour ffmpeg) avprobe (pour avconv) afin de lister les flux vidéos, audios et sous-titres le cas échéant. On se place dans le dossier contenant le fichier vidéo et on ouvre un terminal.

ffprobe 00002.m2ts
ffprobe version 3.0.1 Copyright (c) 2007-2016 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avres-enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadeble-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --eibopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschrr --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enablrbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-ve--enable-x11grab
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, mpegts, from '00002.m2ts':
  Duration: 01:53:59.70, start: 600.000000, bitrate: 37628 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 2s, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: pcm_bluray (HDMV / 0x564D4448), 48000 Hz, stereo, s16, 1536 kb/s
    Stream #0:2[0x1101]: Audio: dts (DTS-HD MA) ([134][0][0][0] / 0x0086), 48000 Hz, 5.1(side), s16p

Ce qui nous intéresse ici, ce sont les lignes commençant par "Stream". On voit un flux Vidéo FHD (1920x1080) "Stream #0:0", Un flux audio stéréo "Stream #0:1" et un flux audio 5.1 "Stream #0:2"
On va réaliser un test d'encodage avec des paramètres adaptés à cet effet. Nous les changerons pour l'encodage définitif.  J'ai choisi ici 2 codecs audio différents, juste pour montrer que c'est possible.

ffmpeg \
-i "00002.m2ts" \
-map 0:0 -c:v libx265 -preset ultrafast -x265-params \
crf=23 \
-map 0:1 -c:a libopus -b:a 128k \
-map 0:2 -c:a aac -b:a 320k\
-t 120 \
"MonSuperLive.mkv"
  • ffmpeg -i suivi du nom du container "input", cad le fichier vidéo à transcoder. Ici ffmpeg -i "00002.m2ts"
  • L'option "-map" va appeler le flux correspondant aux lignes Stream #0:0, #0:1, #0:2 etc...
  • -t 120 pour un test de 120 secondes.
  • La dernière ligne sera l' "output", donnez un nom à votre mkv, mp4 ce que vous aurez choisi comme container. Souhaitant utiliser du libre autant que faire ce peut, mon choix sera le mkv.
  • Concernant les options -c:v (codec vidéo) & -c:a (codec audio), c'est à définir selon ce que l'on souhaite, je vais y revenir.

    Les options Vidéo:

    J'ai réalisé plein de tests avec beaucoup d'options différentes, qui en terme de rendu final et de temps d'encodage n'apportent que complications. J'ai décidé de rester sur des réglages simples qui semblent convenir à toutes les situations. Il y a de quoi s'amuser sur la doc x265 . On ne va jouer que sur 2 paramètres, preset & crf.

  • preset Cela détermine la vitesse d'encodage et se fait au détriment de l'efficacité de compression. Si on choisi ultrafast, l'encodage sera plus rapide, mais le fichier de sortie sera plus gros comparé à medium. les options disponibles sont ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow & placebo. Ultrafast est parfait pour un test. Medium semble être le meilleur ratio compression/temps. Faites un test avec l'option slow, ça commence à faire très long pour peu de différence en Mo. Fast pourra convenir si on n' est pas à quelques 100Mo près... La doc FFMPEG indique pour ce parametre ceci :

    Why is placebo a waste of time?

    It helps at most ~1% compared to the veryslow preset at the cost of a much higher encoding time. It's diminishing returns: veryslow helps about 3% compared to the slower preset, slower helps about 5% compared to the slow preset, and slow helps about 5-10% compared to the medium preset.

Pour donner une idée plus concrète (je n'ai malheureusement pas conservé le lien), j'ai pu trouver sur un blog ce test, effectué à base d' un sample.ts de 60 secondes, HD (1440×1080), mpeg2 . Cela corrobore le fait que l'option Medium est un bon compromis Taille/temps.

preset

Rapidité de conversion (fps)

Taille de la vidéo

Ultrafast

29,6

81,046,858

Superfast

27,9

58,180,478

Veryfast

20,6

43,968,615

Faster

13

32,981,783

Fast

9,1

35,461,071

Medium

8

35,119,322

Slow

5,6

33,367,247

Slower

2,1

33,698,347

Veryslow

1,3

29,697,663

Placebo

0,6

29,395,288

 

  • CRF (Constant Rate Factor)
    C'est du VBR, et ça fonctionne sur le même principe que l'audio, on ne cible pas un bitrate particulier, mais une qualité uniforme. Comme pour H264 les valeurs disponibles vont de 0 à 51. Des extrêmes que l'on n' utilisera pas. Pour ma part j'ai décidé de rester entre 20 et 27. Un très bon article en English pour ceux qui veulent peaufiner.   Pour ex: Un fichier de 20 Go avec l'option crf23 = 3.8Go, le même avec crf27 = 2.2 Go. Selon les cas, il faudra baisser la valeur du crf si l'image n'est pas nette.

    Les options Audio

    Ça se complique (ou pas) . Il faut être attentif à ne pas faire n'importe quoi avec les pistes. Encoder une piste 5.1 vers 2.0 pourquoi pas pour un film (j' y reviendrai dans un autre volet à ce sujet, voir HEVC 5.1 vers 2.0 (stéréo downmix)), mais pas pour de la musique. L'audio d'un Blu-ray tient une grande place dans le poids final, en effet il y a souvent 3 pistes HD. La HD audio sujet à Troll s'il en est... On peut très bien conserver les pistes intactes pour les oreilles de super héros. Mon sujet sera la compression avec une qualité suffisante pour ne pas être gêné lors de l'écoute et tant pis pour le fruité dans le médium et le velouté des aigus...
    Que dit ffmpeg au sujet des codecs audios ? libopus > libvorbis >= libfdk_aac > aac > libmp3lame >= libfaac >= eac3/ac3 > libtwolame > vorbis > mp2 > wmav2/wmav1. Parfait je vais choisir Opus sachant que la compression est forte en terme de poids et qu' en plus c'est sous licence open source (BSD). Concernant ce codec il est à noter qu'il exerce une coupure des fréquences supérieures à 20Khz. Pas de son en HD dans ce cas. Je vous invite à la lecture de ce billet du Monde "On a testé... la musique en haute définition" ainsi que de la doc de libopus afin de vous forger une idée (si ce n'est déjà le cas) sur le bien fondé des Flac HD.

 


Un petit mémo concernant la compatibilité des containers avec les codecs audios

containers

codecs audios supportés

MKV/MKA

Vorbis, MP2, MP3, LC-AAC, HE-AAC, WMAv1, WMAv2, AC3, eAC3, Opus

MP4/M4A

MP2, MP3, LC-AAC, HE-AAC, AC3

FLV/F4V

MP3, LC-AAC, HE-AAC

3GP/3G2

LC-AAC, HE-AAC

MPG

MP2, MP3

PS/TS Stream

MP2, MP3, LC-AAC, HE-AAC, AC3

M2TS

AC3, eAC3

VOB

MP2, AC3

RMVB

Vorbis, HE-AAC

WebM

Vorbis, Opus

OGG

Vorbis, Opus


Les notions CBR & VBR

Bitrate Constant (CBR). Quand vous encodez un fichier en bitrate constant (CBR), vous choisissez un bitrate prédéfini et LAME cible ce bitrate sur la totalité du fichier. Cela signifie que chaque seconde du fichier comporte le même nombre de bits, quelque soit la complexité du son. Chaque seconde sur un fichier encodé en CBR a la même qualité. Comme le silence possède le même nombre de bits que des sons complexes, les fichiers encodés en CBR sont plus lourds que ceux encodés en VBR ou ABR. Cela signifie également que les fichiers encodés en CBR ont une taille prévisible.
Bitrate Variable (VBR). Quand vous encodez un fichier en bitrate variable (VBR), vous choisissez une qualité donnée et LAME cible cette qualité, laissant le bitrate varier tout au long du fichier. Cela signifie que chaque seconde du fichier comporte un nombre de bits différent, nombre qui dépend de la complexité du son à cet instant. Par exemple, une seconde de silence recevra bien moins de bits qu’une seconde forte et tonitruante. Comme les fichiers encodés en VBR ciblent une qualité donnée au lieu d’un bitrate donné, leur taille est moins prévisible. LAME possède certains préréglages VBR qui vont de V0 à V9. V0 est la meilleure qualité et V9 la moins bonne. Les deux préréglages les plus communs sont le V0 (avec un bitrate cible de 245 kbps) et le V2 (avec un bitrate cible de 190 kbps).


Quelques exemples de codecs audio qu'on peut utiliser :

sans compression (permet de conserver les pistes en HD) Voyez je ne suis pas sectaire 🙂

-c:a copy

MP3 VBR
Contrôle la qualité avec -qscale:a (alias -q:a). les valeurs sont à définir pour libmp3lame de 0 à 9. La plus basse valeur 0, étant la meilleure.

-codec:a libmp3lame -q:a 2

♦ MP3 CBR

constant bitrate (CBR) MP3 audio, vous devez utiliser l'option -b:a (pour bitrate audio) à la place de -qscale:a. et spécifier un nombre bits par seconde,
par exemple -b:a 256k. les options disponibles sont: 8, 16, 24, 32, 40, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320. La meilleure qualité étant le 320k. Je vous conseille de ne pas aller en dessous de 192K.

-c:a libmp3lame -b:a 320k

♦ aac CBR

-c:a aac -b:a 320k

♦ aac VBR

-c:a aac -q:a 2

♦ opus

-c:a libopus -b:a 256k

La Doc ffmpeg recommande pour de l'audio de haute qualité de ne pas descendre sous 128k. Si on laisse le réglage par défaut, soit la commande -c:a libopus cela correspond à 96 kbps. (Pour ça, on ne mettra pas d'argument -b:a ) Nous aurons tout de même une bonne qualité, qui conviendra sans problème pour un film. Plus bas dans la section "cas concret" j'ai réalisé le test avec le bitrate par défaut, à l'écoute mon ressenti est plutôt bon. Le wiki d' hydrogenaud.io indique :

  • 96 kbps Full bandwidth stereo music, good quality approaching transparency. Music storage & high quality streaming. Beat LC-AAC, Vorbis, MP3.
  • 128 kbps Very close to transparency (needs more testing). Most modern codecs competitive (AAC-LC, Vorbis, MP3). Music storage & streaming. Future download music sales.
  • 256 kbps Transparent with very low chance of artifacts (a few killer samples still detectable). Most old & new lossy codecs competitive. Music storage & streaming, dedicated limited-bandwidth audio links.

Cas concret (avec toutes les pistes audio)

Terminons par l' exemple avec un autre rip.

ffprobe mon_concert.m2ts

qui retourne 4 flux :

[...]
Stream #0:0[0x1011]: Video: vc1 (Advanced) (VC-1 / 0x312D4356), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc
    Stream #0:1[0x1100]: Audio: truehd (AC-3 / 0x332D4341), 96000 Hz, 5.1(side), s32 (24 bit)
    Stream #0:2[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 640 kb/s
    Stream #0:3[0x1101]: Audio: pcm_bluray (HDMV / 0x564D4448), 96000 Hz, stereo, s32 (24 bit), 4608 kb/s

Je souhaite conserver toutes les pistes et les transcoder en HEVC+ OPUS .

Je lance le test de transcodage de 2 minutes :

ffmpeg \
-i "input.m2ts" \
-map 0:0 -c:v libx265 -preset ultrafast -x265-params \
crf=23 \
-map 0:1 -c:a libopus \
-map 0:2 -c:a libopus \
-map 0:3 -c:a libopus \
-t 120 \
"output[2.0+5.1].mkv"

Que nous dit Mediainfo sur ce test ? On constate que la particularité des pistes est conservée, la stéréo et le 5.1 sont seulement ré-encodés avec perte (lossy).

Format                                   : Matroska
Format version                           : Version 4 / Version 2
File size                                : 25.9 MiB
Duration                                 : 1mn 16s
Overall bit rate                         : 2 837 Kbps
Writing application                      : Lavf57.25.100
Writing library                          : Lavf57.25.100 / Lavf57.25.100

Video
ID                                       : 1
Format                                   : HEVC
Format/Info                              : High Efficiency Video Coding
Format profile                           : Main@L4@Main
Codec ID                                 : V_MPEGH/ISO/HEVC
Width                                    : 1 920 pixels
Height                                   : 1 080 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Variable
Original frame rate                      : 23.976 fps
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Writing library                          : x265 1.9:[Linux][GCC 5.3.0][64 bit] 8bit+10bit+12bit
Encoding settings                        : wpp / ctu=64 / min-cu-size=8 / max-tu-size=32 / tu-intra-depth=1 / tu-inter-depth=1 / me=1 / subme=2 / merange=57 / no-rect / no-amp / max-merge=2 / temporal-mvp / no-early-skip / rdpenalty=0 / no-tskip / no-tskip-fast / strong-intra-smoothing / no-lossless / no-cu-lossless / no-constrained-intra / no-fast-intra / open-gop / no-temporal-layers / interlace=0 / keyint=250 / min-keyint=23 / scenecut=40 / rc-lookahead=20 / lookahead-slices=6 / bframes=4 / bframe-bias=0 / b-adapt=2 / ref=3 / limit-refs=3 / no-limit-modes / weightp / no-weightb / aq-mode=1 / qg-size=32 / aq-strength=1.00 / cbqpoffs=0 / crqpoffs=0 / rd=3 / psy-rd=2.00 / rdoq-level=0 / psy-rdoq=0.00 / signhide / deblock / sao / no-sao-non-deblock / b-pyramid / cutree / no-intra-refresh / rc=crf / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=51 / qpstep=4 / ipratio=1.40 / pbratio=1.30
Default                                  : Yes
Forced                                   : No
DURATION                                 : 00:01:16.500000000

Audio #1
ID                                       : 2
Format                                   : Opus
Codec ID                                 : A_OPUS
Duration                                 : 1mn 16s
Channel(s)                               : 6 channels
Channel positions                        : Front: L C R, Rear: L R, LFE
Sampling rate                            : 48.0 KHz
Bit depth                                : 32 bits
Compression mode                         : Lossy
Writing library                          : Lavc57.24.102 libopus
Default                                  : Yes
Forced                                   : No
DURATION                                 : 00:01:15.868000000

Audio #2
ID                                       : 3
Format                                   : Opus
Codec ID                                 : A_OPUS
Duration                                 : 1mn 16s
Channel(s)                               : 6 channels
Channel positions                        : Front: L C R, Rear: L R, LFE
Sampling rate                            : 48.0 KHz
Bit depth                                : 32 bits
Compression mode                         : Lossy
Writing library                          : Lavc57.24.102 libopus
Default                                  : Yes
Forced                                   : No
DURATION                                 : 00:01:15.868000000

Audio #3
ID                                       : 4
Format                                   : Opus
Codec ID                                 : A_OPUS
Duration                                 : 1mn 16s
Channel(s)                               : 2 channels
Channel positions                        : Front: L R
Sampling rate                            : 48.0 KHz
Bit depth                                : 32 bits
Compression mode                         : Lossy
Writing library                          : Lavc57.24.102 libopus
Default                                  : Yes
Forced                                   : No
DURATION                                 : 00:01:16.488000000

Cas concret (avec uniquement la piste 2.0)

Si le test est concluant, on va jouer sur le paramètre "-preset ultrafast" qu'on passera à medium. Je ne souhaite conserver que la piste 2.0 contenue dans le Stream #0:3 (et je retire l'option -t120, pour encoder la totalité) :

ffmpeg \
-i "input.m2ts" \
-map 0:0 -c:v libx265 -preset medium -x265-params \
crf=23 \
-map 0:3 -c:a libopus \
"output[2.0].mkv"

une image spectrale pour corroborer tout ça :

Pour finir le résultat du transcodage du BR (vidéo + piste 2.0) : 1/2 23.6 Go -> 1.4 Go + 2/2 20 Go -> 1.2 Go, pour un total de 43.6Go -> 2.6 Go. Pas mal ! Ne pouvant mettre un sample d'une œuvre commerciale, je remplace par un screenshot, même si ce n'est pas l'idéal pour juger de la qualité, cela permet tout de même un aperçu.

 

Ajout du 24.07.2017

2 ou 3 fois j'ai pu rencontrer le cas particulier où le film n'est pas d'un seul tenant (00000.m2ts + 00000.1.m2ts) comme le dernier cas ci-dessus. Il faudra alors joindre (concatenate) les 2 parties pour en obtenir une seule. Voici comment procéder lorsque les fichiers vidéos ont les mêmes codecs ( tiré de la doc ffmpeg ) :

Il faut créer un fichier mylist.txt avec tous les fichiers que l'on veut mettre bout à bout comme ceci :


# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

Puis lancer la commande suivante :

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mkv

 

FMR

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *