Enregistrer le flux vidéo d’une box internet

Pendant longtemps je me suis servi d’un enregistreur AverMedia pour enregistrer le flux TV de ma box internet comme expliqué dans ce post. Il se trouve que mon boîtier AverMedia présentait des signes de faiblesse ces derniers temps avec une mauvaise reconnaissance du disque dur externe et d’autres dysfonctionnements, je me suis décidé à le changer. Plutôt que de partir sur un équivalent actuel avec enregistrement intégré, je suis parti sur quelque chose de plus simple, un dispositif de capture vidéo HDMI qui renvoie le flux via USB pour enregistrement sur un PC, bien moins cher.

J’ai acheté ce modèle pour être précis. Il en reste pas moins qu’il subsiste la problématique du flux HDMI qui est protégé en sortie de la box au format HDCP. En fait il existe des splitters HDMI qui permettent de faire sauter cette protection, celui que j’utilise n’existe plus depuis des années, mais pour mémoire c’est un HDelite HDMI splitter 3D 2 ports qui ressemble à ça :

Je ne peux vous conseiller d’autres splitters, mais il faudra veiller qu’ils soient compatibles avec la version de HDMI renvoyée par la box.

Le schéma du branchement réseau est ci-dessous, le splitter s’intercale entre la box et le boitier de capture vidéo, tout l’enregistrement se fait maintenant sur un PC branché en USB contrairement à mon ancien AverMedia qui disposait d’un enregistrement intégré.

Maintenant sur le PC il existe plusieurs moyens d’enregistrer, beaucoup de personnes sous Linux utilisent OBS Studio qui reconnait très bien ces dispositifs de capture vidéo USB, j’ai opté sur une solution plus simple basée sur ffmpeg.

Je précise tout de suite pour ceux qui auraient quelques craintes sur la légalité de ce dispositif, je vous invite à lire ce post sur l’exception de copie privée.

Revenons à des considérations plus techniques, tout d’abord quand on le branche sur le PC, systemd me renvoie :

déc. 20 19:15:53 cilaos.kervao.fr kernel: usbcore: registered new interface driver snd-usb-audio
déc. 20 19:15:53 cilaos.kervao.fr mtp-probe[19296]: checking bus 2, device 2: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-6"
déc. 20 19:15:53 cilaos.kervao.fr mtp-probe[19296]: bus: 2, device: 2 was not an MTP device
déc. 20 19:15:53 cilaos.kervao.fr systemd[3141]: Reached target sound.target.
déc. 20 19:15:54 cilaos.kervao.fr wireplumber[3158]: s-monitors-utils: skipping device libcamera:\_SB_.PCI0.XHC_.RHUB.SS06-6:1.0-345f:2131

Un lsusb donnera

Bus 002 Device 002: ID 345f:2131 MACROSILICON MiraBox Video Capture

Et la commande v4l2-ctl –list-devices listera les fichiers spéciaux vidéo du périphérique pour pouvoir y accéder :

MiraBox Video Capture: MiraBox  (usb-0000:00:14.0-6):
        /dev/video2
        /dev/video3
        /dev/media1

Integrated Camera: Integrated C (usb-0000:00:14.0-8):
        /dev/video0
        /dev/video1
        /dev/media0

Le périphérique vidéo est identifié sous le terme Mirabox et accessible via /dev/video2. La commande arecord -l donne le numéro de la carte audio pour avoir le son :

**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC298 Analog [ALC298 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Capture [MiraBox Video Capture], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Le périphérique audio sera accessible via hw,1. Pour visualiser la vidéo (sans le son), on tapera ffplay -f v4l2 -i /dev/video2 et pour le son (sans la vidéo) ffplay -f alsa -i hw:1. Ces fichiers spéciaux audio et vidéo ne sont pas toujours les mêmes. Pour l’enregistrement en utilisant le conteneur mp4 et le codec vidéo H264 la commande à taper sera :

ffmpeg -f alsa -i hw:1 -f video4linux2 -i /dev/video2 -vcodec h264 -preset ultrafast -max_muxing_queue_size 9999 essai.mp4

L’option max_muxing_queue_size est mise pour contrer l’erreur Too many packets buffered for output stream. Le résultat de l’enregistrement donne :

Input #0, alsa, from 'hw:1':
  Duration: N/A, start: 1734898311.920705, bitrate: 1536 kb/s
  Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video2':
  Duration: N/A, start: 208.942297, bitrate: 1990656 kb/s
  Stream #1:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1920x1080, 1990656 kb/s, 60 fps, 60 tbr, 1000k tbn
Stream mapping:
  Stream #1:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
  Stream #0:0 -> #0:1 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x284a08c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x284a08c0] profile High 4:2:2, level 4.2, 4:2:2, 8-bit
[libx264 @ 0x284a08c0] 264 - core 164 - H.264/MPEG-4 AVC codec - Copyleft 2003-2024 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to '/ginette/video/essai.mp4':
  Metadata:
    encoder         : Lavf61.1.100
  Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv422p(progressive), 1920x1080, q=2-31, 60 fps, 15360 tbn
      Metadata:
        encoder         : Lavc61.3.100 libx264
      Side data:
        cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
  Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s
      Metadata:
        encoder         : Lavc61.3.100 aac
[out#0/mp4 @ 0x2849f700] video:6438195KiB audio:122390KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.212900%
frame=468000 fps= 60 q=-1.0 Lsize= 6574553KiB time=02:10:00.00 bitrate=6905.0kbits/s dup=16 drop=14626 speed=   1x
[libx264 @ 0x284a08c0] frame I:1872  Avg QP:16.84  size:145122
[libx264 @ 0x284a08c0] frame P:466128 Avg QP:19.62  size: 13561
[libx264 @ 0x284a08c0] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 0x284a08c0] mb P  I16..4:  3.2%  0.0%  0.0%  P16..4: 24.2%  0.0%  0.0%  0.0%  0.0%    skip:72.6%
[libx264 @ 0x284a08c0] coded y,uvDC,uvAC intra: 20.6% 41.3% 5.2% inter: 9.1% 11.2% 0.4%
[libx264 @ 0x284a08c0] i16 v,h,dc,p: 51% 21% 14% 14%
[libx264 @ 0x284a08c0] i8c dc,h,v,p: 46% 16% 26% 11%
[libx264 @ 0x284a08c0] kb/s:6761.75
[aac @ 0x284a4f00] Qavg: 1717.494

Les options du preset ultrafast du codec vidéo H264 apparaissent dans le détail de la commande, il faut éventuellement se référer à la page sur le codec H264 sur le site de ffmpeg.

Voilà un script que j’ai appelé record qui va d’abord renvoyer les résultats de commande pour bien identifier les sorties vidéo et audio du périphérique et les modifier au besoin, puis il faudra entrer la durée d’enregistrement et le nom du fichier.

#!/bin/bash
echo "**********************************************"
echo "*                                            *"
echo "*  Enregistrement flux video USB             *"
echo "*                                            *"
echo "**********************************************"
echo ""
echo "Résultat commande arecord -l"
echo ""
arecord -l
numcarteaudio=1
echo ""
read -p "Numéro de la carte audio (par défaut 1) :" newnumcarteaudio
[ -n "$newnumcarteaudio" ] && numcarteaudio=$newnumcarteaudio
echo ""
echo "Résultat commande v4l2-ctl --list-devices"
echo ""
v4l2-ctl --list-devices
numcartevideo=0
read -p "Numéro de la carte vidéo (par défaut 0) :" newnumcartevideo
[ -n "$newnumcartevideo" ] && numcartevideo=$newnumcartevideo
read -p "Durée (seconde par défaut, format hh:mm:ss) : " duree
read -p  "Nom du fichier (extension mp4 par défaut) : " nom 
nomfile="/ginette/video/${nom}.mp4"
cartevideo="/dev/video${numcartevideo}"
carteaudio="hw:${numcarteaudio}"
heure=$(date +%H:%M:%S)
echo ""
echo "Enregistrement du fichier $nomfile à partir de la carte video $cartevideo et de la carte audio $carteaudio, durée $duree, début d'enregistrement $heure"
/usr/local/bin/ffmpeg -hide_banner -f alsa -i $carteaudio -f video4linux2 -i $cartevideo -vcodec h264 -preset ultrafast -max_muxing_queue_size 9999 -y -t $duree $nomfile

J’estime que la qualité d’enregistrement est largement acceptable car pour un film de 2h, cela me donne 10Go d’enregistrement à peu près. J’ai tenté également un enregistrement direct avec le codec HEVC, mais ça demande trop de ressource. Je fais face également à un problème non encore résolu, je ne peux lancer qu’en enregistrement lors d’une session, sinon j’ai l’erreur Dequeued v4l2 buffer contains corrupted data (0 bytes) qui nécessite que je reboote le PC.

Le détail pour le réencodage en HEVC sous avidemux est donné ici, cela me donne des fichiers entre 1 et 2Go pour 1h30, 2h de durée à peu près.

Laisser un commentaire