Hardware

Tutoriel : dual PC streaming sans carte d’acquisition avec OBS

Tutoriel : dual PC streaming sans carte d’acquisition avec OBS

Une carte Ethernet comme alternative aux cartes d’acquisition

 

INTRODUCTION

Une carte d’acquisition peut coûter cher (on trouve néanmoins des solutions simples et pratiques), mais il est possible de s’en passer en envoyant son flux vidéo vers une autre machine à l’aide de son réseau local. Dans ce tutoriel, je vais présenter une méthode simple pour envoyer son flux vidéo directement vers un autre PC en utilisant OBS. En soi, nous allons profiter du fait qu’OBS utilise FFmpeg et qu’il nous laisse utiliser des paramètres personnalisés.

Cette méthode va utiliser de simples connexions TCP et présente quelques avantages face aux cartes d’acquisition, comme le fait de pouvoir éditer ses scènes sur la machine envoyant son flux ou le fait de consommer peu de ressources CPU (beaucoup moins que de faire l’encodage directement), mais elle a aussi comme principal inconvénient qu’en cas de décalage, le programme utilisera une quantité de RAM supplémentaire et proportionnelle à celui-ci (je n’ai pas trouvé d’option pour drop des frames en cas de retard).

Il existe d’autres solutions plus ou moins complexes qui permettent d’obtenir le même résultat, comme la mise en place d’un serveur RTMP qui permet de ne pas avoir ce problème de buffer sur la machine envoyant son flux (voir toute à la fin). Il existe aussi un plugin gratuit nommé obs-ndi qui utilise la technologie NDI de NewTek et qui permet de réaliser la même chose, mais qui ne semble pas très configurable et nécessite l’installation d’un programme tiers pour fonctionner, bien qu’il semble aussi très simple à utiliser.

 

CONFIGURATION

Du réseau :

Je vais nous donner une configuration qui limite au maximum l’impact sur le CPU mais qui va en contrepartie utiliser pas mal de bande passante. Il vous faut donc prévoir au minimum une carte Gigabit Ethernet (GbE) et si possible une carte secondaire pour éviter d’augmenter la latence même si cela sera normalement peu perceptible. Avec la carte Ethernet secondaire, branchez vos machines directement entre elles (ad hoc), vous devrez alors configurer à la main vos adresses IP. Dans mon cas, j’utilise le sous-réseau 192.168.0.0/24 (des sous-réseaux plus petits peuvent bien sûr être utilisés comme un /30 si vous reliez seulement deux machines) car le sous-réseau 192.168.1.0/24 est celui utilisé pour mon réseau local et probablement le vôtre puisque il est souvent utilisé par les box Internet pour distribuer les adresses IP (DHCP). Si vous n’utilisez qu’une seule carte Ethernet sur l’une de vos machines, vous devriez avoir une adresse automatiquement distribuer par votre box.

Ainsi dans les options de votre carte Ethernet, puis dans les options IPv4, vous pouvez remplir comme l’image ci-dessous l’adresse IP et le masque de sous-réseau pour la machine recevant le flux audio/vidéo et faire la même chose pour la machine source avec l’IP 192.168.0.2 et le même masque. Vous n’avez pas besoin de spécifier de passerelle car cette connexion ne communiquera pas avec un autre sous-réseau.

 

 

D’OBS :

Dans les paramètres OBS de la machine source, allez dans l’onglet « Sortie » puis sélectionnez le mode « Avancé ». Ensuite, sélectionnez l’onglet « Enregistrement » puis choisissez « Sortie personnalisée (FFmpeg) » comme dans l’image ci-dessous. Dans les options, choisissez « Sortie vers une URL » puis entrez comme chemin d’accès tcp://<IP machine réceptrice>:<port>. Pour ce tutoriel, l’adresse est 192.168.0.1 mais une autre est possible selon votre configuration. Comme port, j’utilise souvent 10 000 car facile à retenir, mais cela peut être plus ou moins n’importe quel nombre non utilisé par d’autres applications. Le numéro de port peut être au maximum 65 535 mais préférez au dessus de 1 024 et en dessous de 49 000 si possible.

Comme conteneur, j’utilise NUT car on peut mettre à peu près n’importe quel type de format audio/vidéo dedans mais il reste encore assez expérimental. Comme encodeur vidéo, choisissez « rawvideo » et comme encodeur audio « pcm_f32le ». Rawvideo ne compresse pas le flux vidéo, d’où son nom, et donne un résultat qui ressemble à un empilement d’images au niveau binaire. De même, pcm_f32le est une façon de représenter un signal audio sans compression. Soulignons deux points essentiels concernant les flux vidéo non compressés : l’image n’est pas altérée et le débit est constant et très important.
L’intérêt de solutions non compressées est que l’on utilise très peu de ressources pour générer un flux (et un peu pour l’envoyer sur le réseau).

Si le deuxième point vous gêne, car avec une carte GbE il n’est pas possible d’envoyer un flux 1080p 60fps et car cela demande environ 1,5 Gb/s constant (sans toucher aux paramètres avancés), vous pouvez changer le conteneur pour Matroska (le même que pour les .mkv si ça vous dit quelque chose) puis comme encodeur vidéo « huffyuv » qui fait de la compression sans perte sans être gourmand en ressources. Vous pouvez laisser pcm_f32le pour l’encodeur audio car il ne représente que quelques Mb/s.

Si huffyuv est toujours trop important, vous pouvez toujours utiliser l’encodeur de votre carte graphique avec un bon bitrate comme 35000 kbps (car l’encodage par le GPU n’est pas très efficace sur le plan qualité/bitrate) mais vous perdrez l’avantage que procure les deux autres solutions car le but initial est de décharger la compression sur une autre machine mais cela reste envisageable si vous voulez juste faire un stream à partir de plusieurs sources venant d’autres machines comme le fait par exemple de temps en temps la chaîne Solary sur Twitch (ce n’est pas de la pub).

 

 

Sur la machine qui va recevoir le flux, créez une scène avec une source média. Configurez-la comme sur l’image ci-dessous : pour cela, décochez « Fichier local » pour pouvoir entrer une URL, ensuite comme URL vous pourrez mettre au choix l’adresse IP 0.0.0.0 ou celle de votre carte réseau (ici 192.168.0.1). La seule différence est que la première écoute sur toutes vos interfaces alors que l’autre sur une seule. Pensez à décocher « Reprendre la lecture… » car cela arrête la connexion si vous changez de scène et il faudra relancer la source et l’enregistrement. Réutilisez le même port que précédemment (ici 10000) car c’est cette source qui va faire office de serveur TCP.

D’ailleurs, vous pouvez voir qu’il y a des options après le port : listen=1 permet d’écouter une connexion (et seulement une, ce qui est dommage) et recv_buffer_size=33554432 permet de définir un tampon de réception de 32 Mb car par défaut il est défini à 2 Mb. Je le définis pour essayer d’éviter d’augmenter le délai en cas de perte de paquets TCP. Mais je ne peux pas prouver son efficacité, alors considérez-le comme optionnel. Sur votre scène, vous pouvez regrouper plusieurs flux venant de différentes machines, pour cela, il suffit de créer autant de sources média que de machine et de les configurer avec un numéro de port différent (tant que vous ne surchargez pas votre/vos carte(s) réseau). Il est bien sur possible d’utiliser d’autres types de sources, comme un chat ou les notifications d’abonnement, pour une mise en commun ou tout simplement pour décharger la machine émettrice.

 

 

 

TEST

Tout d’abord, faisons un petit point sur la latence induite par cette méthode : comme vous pouvez le voir sur le GIF ci-dessous, la latence reste très correcte. À gauche vous avez la source du flux dans un client RDP (bureau à distance) et à droite le rendu sur la deuxième machine, il y a une différence de délai entre 0,8 et 1 seconde après 4 heures d’émission (plus ou moins le délai initial). Si l’on compare à d’autres solutions comme le passage par un serveur RTMP, c’est plutôt bon car un serveur RTMP donne environ 3 secondes de délai (et jusqu’à 5 secondes relevées en testant rapidement cette solution) mais offre en contrepartie des fonctions qui peuvent être intéressantes (par exemple envoyer le flux, transcoder ou non, sur plusieurs services de streaming en même temps).

 

gif délai après 4h

 

Je profite aussi de ce tutoriel pour faire un point sur la qualité visuelle d’une vidéo en fonction de sa résolution et du bitrate utilisé car un des intérêt de faire l’encodage sur une autre machine est aussi d’utiliser des paramètres plus gourmands en ressources.

Pour les deux tests suivants, j’utilise un segment vidéo de dix minutes d’une partie de League of Legends. J’ai pris ce jeu car je pense qu’il représente encore bien la majorité des streams actuels. Encoder ce genre de vidéo n’est pas particulièrement difficile car la scène reste plutôt statique et les couleurs ne changent pas trop. Ainsi il n’est pas compliqué d’avoir un bon rendu tant que l’on est pas en teamfight, moments où l’on aura le plus d’artefacts. Le segment vidéo d’origine est encodé en 1080p 30fps « lossless », cela veut dire que la qualité est théoriquement la même que ce qui est affiché à l’écran et ce dans toutes les situations, ainsi le bitrate moyen de ce segment est de 118 000 Kb/s ce qui donne 8,13 Go pour les 10 minutes. Des versions 720p et 480p sont aussi générées pour les besoins du tutoriel.

Vous trouverez ci-dessous deux tableaux contenants les résultats des méthodes PSNR (rendu des frames) et VMAF (perception visuelle) pour des bitrates vidéo de 800 Kb/s (ADSL2), 2000/3500 Kb/s (VDSL2 et/ou connexion limitée à 5 Mb/s en upload) et 5 000 Kb/s (Fibre) pour les presets x264 ultrafast (le moins bon mais le moins lourd en calculs), veryfast (souvent recommandé) et medium (plus lourd mais plus efficace). Il existe aussi d’autres presets au-delà de medium avec par exemple slower mais ils se sont pas adaptés à de l’encodage en temps réel, medium étant déjà assez limite par rapport au gain qu’il apporte.

 

PSNR (Peak Signal to Noise Ratio) :

PSNR est une méthode qui se base sur l’erreur quadratique moyenne, aussi nommée MSE (somme des carrés des différences), d’une image par rapport à une référence. J’ai eu l’occasion d’utiliser cette mesure durant mes études pour ce qui touche la compression et la restauration d’image, elle ne donne pas un indice de qualité mais de ressemblance. Par exemple, si vous faites une zone noire sur un image plutôt claire, l’indice va baisser même si l’image reste parfaitement lisible.

Cette méthode ne tient pas compte de la succession de frames dans une vidéo et donc ne sert qu’à avoir une idée de la dégradation due à la compression sans tenir compte de la qualité visuelle. Dans le tableau, les valeurs sont des moyennes exprimées en dB. Un bon exemple de perte de qualité due à la compression est disponible sur la page Wikipédia anglaise du PSNR.

 

Presetultrafastveryfastmedium
Bitrate vidéo800200035005000800200035005000800200035005000
480pxxxx37,2041,5844,38x38,0242,4445,39x
720p32,3335,3138,0440,0034,8039,0641,7743,5235,3739,6742,4844,42
1080p28,3032,5835,2537,1032,2635,7838,4440,2433,1336,2438,9240,86

 

Les résultats des mesures du PSNR montrent un gain conséquent entre les presets ultrafast et veryfast de 3,4 dB en moyenne tandis que le gain l’est beaucoup moins entre veryfast et medium (autour de 0,7 dB de moyenne).

À partir d’ici, nous rentrons dans le domaine du subjectif, ainsi les éléments qui suivent ne sont que des interprétations personnelles. En regardant chaque segment, je trouve que l’on est devant une qualité que je considère au minimum correcte dès que l’on dépasse 39 dB de moyenne. Vers 39 dB, des artefacts peuvent encore être visibles durant un mouvement rapide de caméra mais ils restent suffisamment discrets pour ne pas être dérangeants.

Le preset ultrafast semble vraiment inefficace, il faut utiliser un bitrate élevé pour obtenir un résultat correct et ne peut pas être conseillé sauf peut-être pour les personnes ne pouvant vraiment pas faire autrement ou ceux ayant de grosses connexions. Par contre attention, car les spectateurs devront eux aussi avoir un débit descendant en adéquation, surtout si vous n’avez pas d’options de transcodage proposées par votre plateforme de streaming (plusieurs résolutions proposées pour les partners Twitch par exemple).

Si vous avez les capacités de choisir le preset medium, vous pouvez l’utiliser de deux façons : soit pour augmenter la qualité visuelle en gardant le même bitrate, soit pour réduire le bitrate nécessaire pour obtenir une qualité visuelle similaire. Veryfast reste bien sur un compromis plus que légitime, ce n’est pas pour rien qu’il est recommandé (il existe aussi 2 presets entre veryfast et medium, faster et fast, si vous voulez un compromis entre les deux presets testés).

 

VMAF (Video Multi-Method Assessment Fusion) :

VMAF est une méthode développée par Netflix qui a pour but de donner une note sur la qualité perçue d’une vidéo par rapport à une référence. En soi, elle utilise plusieurs métriques, dont le PSNR calculé plus tôt, pour aboutir à un score sur 100. Ce score reste très subjectif puisque ce genre d’algorithme essaie de reproduire la même chose que si vous vouliez l’avis de personnes sur la qualité visuelle d’une vidéo. Étrangement, comparer une vidéo à elle-même ne donne pas toujours 100 mais par exemple 98,7.

Il n’est pas facile de trouver des informations sur ce que représentent ces scores mais à force de chercher j’ai pu trouver un post d’une personne qui avait posé une question similaire et dont la réponse était qu’une différence de 6 points est perceptible par le spectateur.

 

Presetultrafastveryfastmedium
Bitrate vidéo800200035005000800200035005000800200035005000
480pxxxx83,2093.7296,78x88,0095,6897,84x
720p62,2979,5990,0994,5169,2187,6993,6496,0276,1991,0595,6497,45
1080p36,5763,1778,1686,1151,7873,9985,6190,8153,5979.8089,3993,63

 

Si je compare ces scores à ma notion de qualité correcte lors du test précédent, cela donne au moins 86 en score VMAF. Encore une fois, ce test montre les limites du preset ultrafast : si l’on prend la ligne 1080p, il faut presque se déplacer d’une colonne pour obtenir un score similaire avec par exemple 78,16 et 86,11 pour respectivement 3500 et 5000 kbps pour ultrafast contre 73,99 et 85,61 pour respectivement 2000 et 3500 kbps pour veryfast (je trouve au passage que du 5000 kbps ultrafast est moins beau que du 3500 kbps veryfast contrairement au score dans le tableau).

Ce test montre aussi de manière plus prononcée la différence de qualité que l’on peut obtenir entre veryfast et medium. Il semble que le gain est plus important pour des flux avec un petit bitrate avec par exemple un passage de 83,20 à 88,00 pour du 480p 800 kbps ou encore de 87,69 a 91,05 pour du 720p 2000 kbps, mais reste encore correct même si vous utilisez un bitrate élevé avec de 93,64 à 95,64 pour du 720p 3500 kbps et 90,81 à 93,63 pour du 1080p 5000 kbps soit au moins 2 points de plus (les dernières colonnes pour 480p et 720p sont des bitrates « overkill » et ne sont pas pertinents).

Il faut savoir que les scores VMAF ne sont comparables qu’à résolution similaire, ainsi vous ne pouvez pas comparer du 720p à du 1080p directement. Ainsi après ajustement, on a par exemple un score de 72,10 pour une vidéo 720p 3500 kbps convertie en 1080p sans dégrader la qualité. De même, une vidéo 1080 3500 kbps donne 82,93 une fois convertie en 720p.

Dans les deux cas, la valeur est plus basse que son homologue. Cela est dû au compromis que vous voulez faire : dans le cas d’une vidéo 720p vue en 1080p, celle-ci est est moins nette qu’une vidéo 1080p native, et pour une vidéo 1080p vue en 720p, c’est le fait quelle contienne plus d’artefacts de compression qu’une vidéo en 720p.

Ainsi c’est un choix que vous devrez faire entre un stream plus stable mais moins net (720p) ou plus net mais sensible aux artefacts de compression sur des scènes plus difficiles à rendre (1080p). Sachez aussi que, pour rappel, l’encodage en 1080p est plus gourmand qu’en 720p, cela peut avoir son importance.

 

CONCLUSION

Dans ce tutoriel, je vous ai présenté une méthode à base de connexions TCP pour envoyer un flux audio/vidéo d’une machine à une autre. Cette méthode a l’avantage de ne rien coûter car elle utilise des composants déjà présent sur votre machine, à savoir votre carte réseau. Je trouve qu’elle correspond bien à la catch phrase que les anglais utilisent, « the cheap way », car je pense que l’on peut difficilement faire plus basique sauf peut-être avec le plugin obs-ndi.

Je vous ai proposé une configuration qui limite au maximum l’impact CPU sur la machine émettrice mais cela a tendance à amplifier le principal désavantage de cette méthode, à savoir le fait de stocker en RAM une partie du flux qui n’a pas encore été réceptionné par l’autre machine et qui est proportionnelle au bitrate utilisé (centaines de Mb/s ici). Comme on a pu le voir, le délai reste très correct si le réseau est stable (pas de perte de paquet).

Je me suis permis de faire une petite comparaison de compression avec différentes résolutions, car déporter l’encodage permet aussi d’allouer plus de ressources pour avoir un encodage de meilleur qualité. Augmenter le preset semble plus avantageux pour des personnes ne disposant pas d’une grosse connexion Internet mais reste tout de même appréciable pour les autres.

Si cette méthode ne vous convient pas, je vous laisse en bonus la configuration d’un serveur RTMP (rapide car beaucoup de tutoriels sur Internet), méthode que j’ai beaucoup utilisée en comparaison de la mienne.

 

BONUS

Préférez l’utilisation de votre carte graphique pour l’encodage avec cette méthode. Je me base sur ce tuto mais pour Windows.

Pour commencer, téléchargez cette version de nginx (ce n’est pas la plus récente mais connue comme ayant le module RTMP), puis extrayez les fichiers de l’archive.

Dans le dossier « conf », créez un fichier « nginx.conf » et copiez cette configuration :

worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
}
}
}

Ainsi, configurez dans les options d’OBS, onglet « flux », choisissez « Serveur de streaming personnalisé », comme URL rtmp://<IP du serveur>/live et comme clé ce que vous voulez. Ensuite comme pour ma méthode avec la source média, utilisez comme URL la même que pour la première machine mais avec la clé choisie à la fin : rtmp://<IP du serveur>/live/<clé>.

Si vous voulez envoyer directement votre flux sur un service de streaming, vous pouvez ajouter la ligne « push rtmp://live.twitch.tv/app/<clé_twitch>; » juste après « record off; » (le transcodage est recommandé pour cela).

Dans le cas ou vous voudriez transcoder votre flux, la version Windows ne semble pas le permettre car elle ne supporte pas la commande « exec » d’après la documentation. Si vous avez une machine sous linux et une version de nginx avec le module RTMP, vous pouvez créer un nouveau block application pour le transcodage par exemple au-dessus de « application live { » :

application transcode {
live on;
record off;
exec ffmpeg -i rtmp://localhost:1935/transcode/$name -vf scale=-1:720 -c:v libx264 -preset medium -b:v 2000k -maxrate 2000k -minrate 2000k -bufsize 4000k -c:a copy -f flv rtmp://localhost:1935/live/$name;
}

Hardware
Cliquer pour ajouter un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Plus Hardware