Vue lecture

Enregistrement de vidéo à la demande avec Xephyr et PulseAudio

Sommaire

La copie privée a l'honneur de figurer parmi les sujets qui me tiennent à cœur. Concrètement, dans la mesure où, comme tout le monde en France je paie pour bénéficier de ce droit, je ne me prive pas de télécharger ce qui est disponible sur YouTube, et d'enregistrer aussi bien les CD et DVD que j'emprunte à la bibliothèque de ma ville, ainsi que les films en ligne dont je bénéficie grâce à cette même bibliothèque.

Pour ceux que cela intéresserait, je détaillerai un peu plus les aspects légaux de cette pratique dans un commentaire dédié. Ce journal a plutôt vocation à présenter ma technique d'enregistrement de vidéo à la demande DRMisée.

Description du besoin

J'ai donc accès à un film, en l'occurrence sur Arte VOD, mais ça pourrait être sur n'importe quelle plate-forme. Si les distributeurs perçoivent la redevance pour copie privée, en revanche ils n'apprécient pas du tout que leurs utilisateurs exercent le droit correspondant. Les vidéos sont donc verrouillées, de sorte qu'on ne peut pas simplement les télécharger. Même VideoDownloadHelper échoue à cela. En revanche, la lecture se déroule sans problème avec Firefox équipe d'un module Widevine, ou un truc comme ça. Bref, ça marche, du coup on peut au moins enregistrer l'image et le son, le seul inconvénient étant que ça implique de recoder les flux.

Ajoutons quelques critères supplémentaires :

  • Pendant que ça enregistre, je voudrais pouvoir faire autre chose avec mon ordinateur. Y compris le laisser passer en verrouillage d'écran, sans que ça interrompe la capture vidéo.
  • Je voudrais aussi que les éventuels sons émis par mes autres activités ne viennent pas polluer la capture de la bande son.
  • Tant qu'à faire, j'aimerais faire une capture vidéo sans la moindre interpolation, c'est à dire que si la vidéo streamée fait 1280×720, je voudrais l'enregistrer avec exactement cette résolution.

Élements de solution

Xephyr, PulseAudio ou PipeWire module-null-sink et ffmpeg !

Xephyr est un serveur X11 dont l'écran est une fenêtre dans votre affichage X11 actuel. Cela va permettre d'y lancer la lecture vidéo et de capturer cet affichage. À noter qu'on peut très facilement lancer de façon semblable un compositeur Wayland dans une fenêtre, mais que l'enregistrement d'un affichage Wayland est moins bien supporté : je m'en tiendrai donc à Xephyr.

PulseAudio est un serveur de son ; PipeWire est son successeur, qui l'a désormais remplacé sur la plupart des distributions. Parmi leurs sorties sons, il y a notamment un module-null-sink, qui absorbe et jette le son qu'on lui envoie tout en fournissant un « moniteur », c'est à dire une entrée sur laquelle on peut récupérer – et enregistrer – tout ce qu'il reçoit. À noter qu'avec PipeWire, ce genre d'artifice n'est même pas nécessaire puisqu'il permet carrément d'enregistrer directement le son émis par un logiciel indépendamment de toute sortie son. Sauf que l'enregistrement PipeWire, c'est également moins bien supporté : je m'en tiendrai donc à la technique module-null-sink.

Partie graphique : Xephyr

Ça se lance comme ça :

Xephyr :2 -screen 1280x720

Bon, là, vous le lancez sans aucun client dedans. Ça suffirait pour y lancer un navigateur, mais ça ne va pas permettre de lancer une lecture en plein écran. Il faut un gestionnaire de fenêtres : personnellement, j'ai choisi i3, que j'utilisais avant de passer à Wayland. Mais vous pouvez lancer un Gnome entier si ça vous chante :

xinit /usr/bin/i3 -- /usr/bin/Xephyr :2 -screen 1280x720

On peut aussi ajouter quelques extensions à Xephyr, par exemple pour pouvoir régler la disposition du clavier, permettre le redimensionnement de sa fenêtre-écran, de quoi le faire avec XRandR, activer la sécurité X11 (éviter que n'importe qui sur votre ordinateur puisse faire n'importe quoi sur ce Xephyr). On pourra en discuter en commentaire.

Partie son : PiweWire

Il y a un client PipeWire qui devrait permettre de charger ou décharger un module. Sauf que la peinture n'est visiblement pas encore sèche, ça ne marche pas :

pw-cli
>> load-module null-sink
Error: "Could not load module"
>> load-module  module-null-sink
Error: "Could not load module"
>> load-module  pulseaudio-module-null-sink
Error: "Could not load module"
>> unload-module
Error: "Command "unload-module" not yet implemented"

Heureusement, PipeWire est largement compatible avec le protocole de PulseAudio, en fait la plupart des usages utilisent cette compatibilité. Le chargement et déchargement de modules aussi, visiblement. En tout cas, ça marche :

pactl load-module module-null-sink
536870913

Notez le numéro que cela vous a renvoyé : c'est l'identifiant du module chargé, qui servira pour le décharger ensuite. Enfin, si vous souhaitez le décharger : personnellement, je ne vois pas l'intérêt, j'aurais plutôt tendance à le laisser en permanence, ça peut toujours servir.

Pour info, ça a demandé au serveur PulseAudio, qui est en fait un PipeWire, de charger ce module. C'est donc un module PipeWire qui vient d'être chargé. Mais peu importe, il est d'ores et déjà utilisable, c'est à dire que n'importe quel logiciel produisant du son peut désormais l'envoyer vers cette sortie virtuelle qui ne fait rien.

Lecture vidéo

Maintenant, pour enregistrer une vidéo à la demande, il va falloir la lancer. Vous pouvez lancer un navigateur depuis l'intérieur de votre Xephyr, ou depuis l'extérieur, ainsi :

DISPLAY=:2 firefox

Firefox est un peu casse-pied avec sa mutualisation d'exécution, concrètement, si vous avez déjà un Firefox lancé, vous n'allez pas pouvoir lancer une nouvelle fenêtre dans ce nouvel affichage X11. Il faut passer par un profil, et si vous faites ça, vous perdez au passage la possibilité d'ouvrir des liens depuis d'autres applications. Bref, personnellement, je lance plutôt un Chromium pour l'occasion, histoire qu'il n'interfère pas avec mon usage courant de Firefox.

À noter que si votre environnement principal est une session Wayland, il va d'abord vous falloir effacer les variables d'environnement qui permettraient au navigateur de savoir qu'il y a un serveur Wayland disponible :

unset XDG_CURRENT_DESKTOP
unset XDG_SESSION_TYPE
unset WAYLAND_DISPLAY
DISPLAY=:2 chromium

Ensuite, naviguez jusqu'au site de VOD et lancez la lecture, passez-la en plein écran pour vérifier que ça prend bien toute la place dans la fenêtre Xephyr. Il reste encore à envoyer le son sur la sortie nulle : vous pouvez faire ça avec l'outil pavucontrol, lancé depuis l'extérieur de Xephyr (ou depuis l'intérieur, peu importe en fait, c'est pour contrôler PulseAudio, ou plutôt contrôler PipeWire comme si c'était un PulseAudio, ce qui n'est pas lié à l'affichage).

Ffmpeg

Voilà, on va pouvoir enregistrer tout ça avec Ffmpeg, qui dispose de modules pour enregistrer un affichage X11 et une entrée PulseAudio. Ça donne quelque chose comme ça, qu'on peut lancer depuis l'éxtérieur de Xephyr :

ffmpeg -f x11grab -i :2 -f pulse -i null-sink.monitor \
       -c:a libopus -b 128k\
       -c:v libsvtav1 -preset 7 -crf 32 \
       enregistrement.mkv

On peut également limiter la capture à une portion de l'écran virtuel de Xephyr. Je vous laisse regarder la documentation à ce sujet. Pareil pour les codecs et leurs options. Reste à remettre la lecture au début de la vidéo, et à attendre que ça lise jusqu'au bout en vaquant à ses activités. À la fin, il suffit d'interrompre Ffmpeg avec un simple Ctrl + C.

L'avantage d'utiliser Xephyr et module-null-sink, c'est que vous pouvez faire ce que vous voulez à côté, ça n'interférera pas avec la lecture et l'enregistrement. Enfin, tant que vous ne vous amusez pas à lancer des trucs sur l'affichage X11 :2 ou à envoyer du son sur la sortie nulle, évidemment.

Post-production

Si vous avez bien choisi la taille de l'écran de Xephyr, ou la portion de cet écran capturée par Ffmpeg, vous n'avez par besoin de rogner la vidéo. En revanche, il faut couper correctement le début et la fin. Ça peut se faire avec mkvmerge :

mkvmerge -o recoupé.mkv --split parts:0:00:02-1:38:49 enregistrement.mkv

Commentaires : voir le flux Atom ouvrir dans le navigateur

  •