- En remontant à la source du bruit blanc sur un ordinateur portable Linux, on découvre qu’un onglet Firefox maintient le sink audio de PulseAudio éveillé en permanence, même sans aucun son réel
module-suspend-on-idleétait configuré pour arrêter le périphérique audio après 10 secondes, mais lorsqu’un site web crée un AudioContext, le sink ne redescend plus versIDLE/SUSPENDED- Le même phénomène a été observé avec les notifications web d’Outlook, un clic sur x.com, la lecture vocale de Google Translate et l’application web Discord, et
new AudioContext()seul suffit à déclencher le bruit - D’après les mesures, sans bruit, l’utilisation CPU de
pulseaudioétait de 0,0 %, mais avec le bruit elle montait à 4,7 %, et la consommation du système augmentait d’environ 1,5 W AudioContext.suspend()peut interrompre l’accès au matériel audio pour réduire l’usage CPU/batterie, mais Firefox n’arrête pas automatiquement ce gaspillage après un certain temps comme le fait Chrome
Le problème du sink audio qui ne s’endort pas
- Sur un nouvel ordinateur portable, un bruit blanc faible mais agaçant sortait des haut-parleurs même lorsqu’aucune musique ni aucun audio n’était en lecture
- Pour vérifier l’état de PulseAudio sous Linux, la commande
pactl list sinks shorta été utilisée- L’état d’un sink audio apparaît comme
IDLE,SUSPENDEDouRUNNING - Quand le sink était en
SUSPENDED, les haut-parleurs restaient silencieux - En
IDLEouRUNNING, un bruit blanc pouvait apparaître même sans lecture réelle
- L’état d’un sink audio apparaît comme
- Dans
/etc/pulse/default.paet/etc/pulse/system.pa,module-suspend-on-idleétait chargé- En théorie, après 10 secondes d’inactivité, le sink audio devait s’arrêter automatiquement
- Mais dans certaines situations, le sink ne passait même pas en
IDLEet n’atteignait donc jamaisSUSPENDED
Pourquoi un audio inactif consomme de l’énergie
module-suspend-on-idledéconnecte côté backend les sinks et sources qui ne sont reliés à aucun flux pendant un certain temps- Son effet principal est l’économie d’énergie
- Si PulseAudio continue d’envoyer des données vides à la carte son même au repos, ALSA consomme davantage de cycles CPU
- Sauf si l’on prévoit de maintenir en permanence un flux actif, régler un timer court est préférable pour économiser l’énergie
La cause se resserre sur des onglets Firefox et des sites web
- Chaque fois que le bruit blanc apparaissait,
pactl list sink-inputsservait à identifier quel programme utilisait le sink audio - Le responsable était toujours Firefox
- Aucun onglet ouvert n’était censé lire un son réel
- Il n’y avait pas non plus de vidéo en sourdine
- Un petit script a été ajouté à la barre d’état i3 pour afficher un indicateur rouge lorsque le sink audio passait en
RUNNING - Au départ, cela semblait venir du son de notification de outlook.office.com, laissé ouvert en onglet épinglé
- À la réception d’un e-mail, le bruit blanc commençait
- Il ne s’arrêtait qu’après rechargement de l’onglet ou redémarrage de Firefox
- Le même comportement a ensuite été confirmé sur d’autres sites
- Sur x.com, le bruit démarrait dès le moindre clic
- Sur translate.google.com, il apparaissait aussi lors de l’écoute de la prononciation
- L’application web Discord produisait le même effet simplement en restant ouverte
Résultats des mesures CPU et consommation
- Sans bruit blanc, l’utilisation CPU de
pulseaudios’affichait à 0,0 % - Dans les mêmes conditions, la consommation mesurée se situait en général entre 4,2 et 5,1 W
- Avec le bruit blanc, l’utilisation CPU de
pulseaudiomontait à 4,7 % - La consommation mesurée se situait alors plutôt entre 5,8 et 6,7 W
- La différence est loin d’être négligeable et se résume à une hausse d’environ 1,5 W
WebAudio API et AudioContext
- En HTML/JavaScript, il existe deux façons de lire de l’audio : la balise
<audio>et la WebAudio API - Pour des sons joués de manière dynamique, comme dans Outlook, on utilise la WebAudio API, et il faut d’abord créer un
AudioContext - Le problème est que le simple fait d’exécuter
const audioCtx = new AudioContext();suffit à provoquer du bruit blanc dans les haut-parleurs - Une page de test est fournie : https://editor.43z.one/sqare/i
AudioContext.suspend()arrête la progression temporelle du contexte audio et suspend l’accès au matériel audio afin de réduire l’usage CPU/batterieAudioContext.resume()relance la progression temporelle d’un contexte audio suspendu
Différence entre Firefox et Chrome
- De nombreux sites créent un
AudioContextmême lorsqu’ils n’ont pas besoin d’émettre un son immédiatement, puis ne le suspendent pas - Chrome met automatiquement fin à ce gaspillage de CPU/batterie après un certain temps
- Firefox, lui, ne l’arrête pas automatiquement et continue à maintenir l’état qui produit le bruit blanc
- Le site web est la cause directe, mais le reproche demeure que Firefox ne protège pas l’utilisateur contre ce type de gaspillage de ressources
- Il existe aussi un soupçon qu’avec un casque Bluetooth connecté, un clic sur x.com déclenche également l’envoi de ce bruit blanc, gaspillant potentiellement la batterie du casque
Réponse temporaire : AudioContext Suspender
- Pour atténuer le problème, une extension a été créée afin de suspendre automatiquement
AudioContext, puis de le relancer lorsqu’un site tente de lire un son - L’extension n’est pas parfaite
- Le redémarrage prend un peu de temps
- Comme il existe plusieurs chemins pour lancer l’audio, la reprise peut parfois ne pas se produire
- Malgré cela, elle reste suffisante pour l’usage visé
- Liens associés
- Tickets Bugzilla liés
1 commentaires
Avis sur Hacker News
Comme on peut l’imaginer, c’est beaucoup plus complexe que de mettre en pause un
AudioContextaprès un certain temps de silence, mais je pense que c’est corrigeable malgré tout. D’autres navigateurs l’ont déjà fait, et il existe des compromis acceptables.Source : j’ai implémenté beaucoup de fonctionnalités autour de cela dans Firefox et je suis aussi éditeur du standard Web Audio API.
La plupart des gens comprennent la situation décrite ici. Il y a beaucoup à faire et le temps est limité.
J’ai vu directement les développeurs de Firefox aller au-delà de ce qui était attendu pour que des sites très utilisés fonctionnent correctement pour les utilisateurs. Je sais jusqu’où vous allez quand un problème affecte les utilisateurs, donc courage et continuez.
Comme le traitement audio est implémenté différemment selon les moteurs de navigateur et les systèmes d’exploitation, si l’on lit un son totalement inaudible puis qu’on le réenregistre via l’API, on obtient une signature.
Cette signature permet de vérifier si le navigateur falsifie son user-agent, s’il tourne en mode headless, ou s’il s’agit de toutes sortes de cas atypiques qui ne correspondent pas à un vrai utilisateur en train d’acheter un produit.
https://github.com/fingerprintjs/fingerprintjs/blob/3201a7d6...
L’icône de lecture n’apparaît pas sur l’onglet, et couper le son de l’onglet n’arrête pas le bruit.
Même en coupant Firefox dans le mélangeur de volume de Windows, le son ne s’arrête pas.
Modification : pour les utilisateurs desktop, cette extension est en fait plutôt mauvaise. Le bruit blanc qui s’active et se coupe sans arrêt est encore bien plus agaçant.
J’ai donc créé mon propre programme qui ne fait pas passer de données sur la ligne, mais garde la sortie ouverte afin qu’elle ne passe pas en état inactif.
Cela dit, dans le contexte d’un ordinateur portable, ça n’a pas vraiment de sens, donc l’économie d’énergie y est justifiée.
Le pilote Windows dispose d’une option pour régler le flux sur Always On. J’aimerais vraiment que macOS ait la même chose.
play -qn &pour se lancer à la connexion.Un site d’actualité lisait de l’audio tout en rechargeant sans cesse de nouvelles publicités, et à cause de l’audio, l’onglet ne passait apparemment pas en veille. Les frais de données imprévus se répétaient, et j’ai fini par devoir passer à Chrome.
Autrement dit, il n’y avait pas de bruit blanc, mais il y avait une consommation d’énergie due à l’audio : https://bugzilla.mozilla.org/show_bug.cgi?id=1821102
Même maintenant, sur Mac, alors que rien n’est en cours de lecture,
coreaudiodutilise 20 % du CPU. Cela ruine vraiment l’autonomie, au point que j’envisage de passer à un autre navigateur jusqu’à ce que ce soit corrigé, même si je n’ai pas envie d’abandonner Firefox pour quelque chose qui semble aussi mineur.Mise à jour : cela semble lié, mais être un bug différent.
https://source.chromium.org/chromium/chromium/src/+/main:med...
En gros, après avoir détecté environ 30 secondes de silence, il passe du sink adossé au périphérique audio du système d’exploitation à un sink nul.
À noter que cette approche utilise une horloge différente de celle du périphérique audio, et il y a eu quelques signalements de distorsion sur certaines tonalités lorsque le contexte est réellement utilisé plus tard. Le contournement consiste pour le site à utiliser l’API suspend/resume mentionnée dans l’article.
audioContextest implémenté en interne, mais il semble y avoir beaucoup d’éléments assez malins et dynamiques. Lire un son de notification me fait un peu penser à dessiner du SVG avec D3 au lieu d’utiliserimg href *.svg.Je me demande s’il existe quelque chose comme un hook de Service Worker permettant d’enregistrer des éléments simples et répétables, comme un gestionnaire de notifications, auprès d’une API de plus bas niveau et plus efficace.
Sur Firefox 134.0.1 sous macOS, je n’entends rien.