PCsoleil Informatique

Entreprise Individuelle
Services informatiques Brignoles et Centre-VAR | Professionnels et particuliers

Quand la musique s’arrête dans une salle de sport, en l’occurence une salle dédiée à la musculation et au renforcement musculaire en général, un ange passe… Ça s’est pour l’aspect positif et poétique, mais dans les affres des désagréments s’étirent la perte de motivation, le sentiment d’être contraint de communiquer avec son voisinage de l’effort, l’impératif de ne pas trop gueuler en poussant la fonte, enfin, une situation intenable pour une salle moderne digne de ce nom.

L’ordinateur qui délivre le divin son est de bonne facture, sous Windows 11. Le débit de notre vocaliste numérique passe par la fibre optique d’une BOX Orange Pro.

Une prise Jack audio couple l’unité avec des puissants ampli eux-mêmes reliés aux blocs haut-parleurs suspendus aux 4 coins de la salle. Sauf l’ampleur considérable du dispositif audio, rien n’éloigne le fonctionnement du PC d’une utilisation domestique.

J’ai essayé toutes les méthodes officielles visibles ici, notamment le vidage du cache Spotify, la mise à jour de Windows ainsi que sa réparation, (checkdisk, SFC, réparation DISM), celle des pilotes, la vérification des démarrages auto via MSconfig et FRST, le lancement fonctionnel de la version page Web de Spotify… J’ai sans doute oublié de citer quelques autres diagnostics.

Je désespérais de découvrir la solution lorsque, étant devant le PC, j’ai remarqué que l’icône représentant le son dans la barre des tâches, en bas à droite, était affublée d’une croix rouge ; C’est ce qui arrive naturellement lorsqu’on débranche physiquement le câble audio derrière le PC ; Évidemment, cela constitue un signal clair à Spotify pour mettre en pause la lecture audio.

Heureusement cette déconnexion est très brève, et l’icône audio revient en moins de deux secondes à son état « Connecté » si je puis dire. Cependant « reconnexion » ne relance pas Spotify qui fait la sourde oreille. 

La vérification de la connexion physique du-dit câble faite, les arrêts aléatoires de lecture perduraient et cela même en changeant ce fil. De plus le délai entre les arrêts se trouvaient être extrêmement aléatoires, allant de 5 minutes à une heure et demie.

Je n’avais alors pas assez d’indices pour incriminer le PC ou le système haut-parleur coûteux de la salle, et hors de question de couper la musique pour diagnostiquer le PC ou grimper au niveau des baffles pour les changer… Avec quoi d’ailleurs.

Le contournement

Je me trouvais dans l’impasse formée par les murs suivants : Pas de solution officielle, ni d’ailleurs officieuse sur les forums anglais spécialisés que j’ai consulté, pas de possibilité de diagnostiquer la tour, ni les hauts parleurs.

J’ai donc réfléchi à ce que je pouvais faire, soit : 

  • Un script de détection de la mise en pause de Spotify, qui relance la lecture indéfiniment jusqu’à ce que le câble audio soit considéré comme « connecté ».
  • Un autre script qui fait croire à Spotify que le cable audio n’est pas débranché… (Hé hé malin…)
 

La deuxième solution pourrait potentiellement souffrir d’effets de bord, laquelle agissant directement sur l’O.S., je privilégie la première possibilité mais sans avoir les compétences de la mettre en oeuvre à part apprendre sur le tas les API et languages de Spotify et de Windows.

Il fallait donc que ça arrive… Que l’I.A. m’aidâ un jour ou l’autre de manière conséquente. J’ai privilégié ChatGPT pour mener cette intervention car l’expérience qu’elle a acquise n’est pas substituable à mon sens (rappelez-vous il y a quelques années de ChatGPT 3, ça commence à faire quelques années n’est-ce pas ? Sachant que nous sommes en Août 2026).

L’occurence payante du cerveau virtuel s’imposait car la discussion menaçait d’être longue. Je ne vais pas commenter longuement le script PowerShell que je placerais pour info plus bas, mais il y eu de longs interludes avec mon assistant mytho mais surdoué pour identifier le nom technique de la sortie audio vue par Windows, ainsi que pour ouvrir les portes de la sécurité sur un O.S. aussi considérablement attaqué (droits sur le dossier contenant le Script, autorisations d’actions particulières non interactives sur le système de gestion Audio de Windows).

				
					# ============================================================
# AudioMonitor.ps1
# Surveillance audio + reprise Spotify
# ============================================================

$EndpointName  = 'Casque (High Definition Audio Device)'
$CheckInterval = 5
$StableTime    = 3

$LogDirectory = "$env:LOCALAPPDATA\AudioMonitor"
$LogFile      = Join-Path $LogDirectory 'audio-monitor.log'

if (-not (Test-Path $LogDirectory)) {
    New-Item -ItemType Directory -Path $LogDirectory -Force | Out-Null
}

function Write-Log {
    param([string]$Message)

    "{0}  {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message |
        Add-Content -Path $LogFile
}

function Get-EndpointState {

    $Endpoint = Get-PnpDevice -Class AudioEndpoint -ErrorAction SilentlyContinue |
        Where-Object { $_.FriendlyName -eq $EndpointName } |
        Select-Object -First 1

    if ($null -eq $Endpoint) {
        return 'ABSENT'
    }

    return $Endpoint.Status
}

function Test-SpotifyRunning {
    return $null -ne (
        Get-Process Spotify -ErrorAction SilentlyContinue |
        Select-Object -First 1
    )
}

# ------------------------------------------------------------
# API Windows : touche multimédia + niveau sonore
# ------------------------------------------------------------

Add-Type @"
using System;
using System.Runtime.InteropServices;

public static class AudioTools
{
    [DllImport("user32.dll")]
    static extern void keybd_event(
        byte bVk,
        byte bScan,
        uint dwFlags,
        UIntPtr dwExtraInfo
    );

    public static void PlayPause()
    {
        keybd_event(0xB3, 0, 0, UIntPtr.Zero);
        keybd_event(0xB3, 0, 2, UIntPtr.Zero);
    }

    [ComImport]
    [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
    class MMDeviceEnumerator {}

    enum EDataFlow {
        eRender,
        eCapture,
        eAll
    }

    enum ERole {
        eConsole,
        eMultimedia,
        eCommunications
    }

    [ComImport]
    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IMMDeviceEnumerator
    {
        int NotImpl1();

        int GetDefaultAudioEndpoint(
            EDataFlow dataFlow,
            ERole role,
            out IMMDevice device
        );
    }

    [ComImport]
    [Guid("D666063F-1587-4E43-81F1-B948E807363F")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IMMDevice
    {
        int Activate(
            ref Guid iid,
            int clsctx,
            IntPtr activationParams,
            [MarshalAs(UnmanagedType.IUnknown)] out object interfaceObject
        );
    }

    [ComImport]
    [Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IAudioMeterInformation
    {
        int GetPeakValue(out float peak);
    }

    public static float GetPeak()
    {
        IMMDeviceEnumerator enumerator =
            (IMMDeviceEnumerator)new MMDeviceEnumerator();

        IMMDevice device;

        enumerator.GetDefaultAudioEndpoint(
            EDataFlow.eRender,
            ERole.eMultimedia,
            out device
        );

        Guid iid = typeof(IAudioMeterInformation).GUID;

        object obj;

        device.Activate(
            ref iid,
            23,
            IntPtr.Zero,
            out obj
        );

        float peak;

        ((IAudioMeterInformation)obj).GetPeakValue(out peak);

        return peak;
    }
}
"@

function Test-AudioPlaying {

    # Observe le niveau audio pendant 2 secondes
    for ($i = 0; $i -lt 20; $i++) {

        try {
            if ([AudioTools]::GetPeak() -gt 0.005) {
                return $true
            }
        }
        catch {
        }

        Start-Sleep -Milliseconds 100
    }

    return $false
}

# ============================================================
# Démarrage
# ============================================================

Write-Log '=============================================='
Write-Log 'AudioMonitor démarré'

$LastState = Get-EndpointState
$AudioLost = $false

Write-Log "Etat initial : ENDPOINT=$LastState"

while ($true) {

    try {

        $State = Get-EndpointState

        # Perte de la sortie audio
        if ($LastState -eq 'OK' -and $State -ne 'OK') {

            Write-Log "PERTE AUDIO : $LastState -> $State"
            $AudioLost = $true
        }

        # Retour de la sortie audio
        if ($AudioLost -and $State -eq 'OK') {

            Write-Log 'AUDIO RETABLI'

            Start-Sleep -Seconds $StableTime

            if ((Get-EndpointState) -eq 'OK') {

                if (Test-SpotifyRunning) {

                    if (Test-AudioPlaying) {

                        Write-Log 'Audio déjà actif : aucune action'
                    }
                    else {

                        Write-Log 'Silence détecté : reprise Spotify'

                        [AudioTools]::PlayPause()

                        Write-Log 'Commande Play/Pause envoyée'
                    }
                }
                else {

                    Write-Log "Spotify n'est pas lancé"
                }
            }

            $AudioLost = $false
        }

        if ($State -ne $LastState) {
            Write-Log "ENDPOINT : $LastState -> $State"
        }

        $LastState = $State
    }
    catch {

        Write-Log "ERREUR : $($_.Exception.Message)"
    }

    Start-Sleep -Seconds $CheckInterval
}
				
			

Croire que n’importe qui peux assister l’I.A. et la régir pour créer un script viable est une erreur ; De nombreuses connaissances informatiques sont requises pour imaginer tel ou tel sous-scénario et interpréter telle ou telle alerte ou notification, sans questionner le maitre virtuel à tout bout de champ…

… En tout cas pour l’heure, cette semi-automatisation est salvatrice, car à l’avenir il est certain que la main sera donnée à l’I.A. pour contrôler directement nos ordinateurs et tablettes, même si l’expérience -déjà tentée en interne par les développeurs du girond- fut malheureuse car révélatrice du potentiel néfaste pour l’interface Chaise – Écran que nous sommes.

Les menaces révélées sont bien identifiées, et un piratage du compte I.A. de l’utilisateur peut vite mener à un vidage des comptes bancaires sans aucune interaction visible :

On lance des API bancaires directement sur la session utilisateur, dont l’empreinte numérique est déjà connue par la banque suite à une visite identifiée antérieure de l’utilisateur, on visite des sites webs interdits avec un outil python invisible comme Pupeeter pour lancer par la suite un chantage monétisé plus crédible que ceux dans nos Spams, etc..

Besoin d'un devis informatique ?
Parlons-en !

Formulaire devis 2
Téléphone Demande complexe ou difficile à décrire ? Appelez au 06.28.07.77.83

Diagnostic de 35€ offert si devis accepté

Demande de devis