メインコンテンツへスキップ
見出し画像

DENON HOME SOUND BAR 550のQuick SelectをPCから自動切り替える方法

    この記事の内容

    DENON HOME SOUND BAR 550は、HEOS CLI経由でQuick SelectをPCから切り替えられます。
    今回はその仕組みを使って、特定のゲーム起動時だけゲーム用Quick Selectに切り替え、終了時に普段用へ戻す方法をまとめます。

    画像
    以前YouTubeで上げたサウンドバーの動画はこちらです

    https://youtu.be/-5JwKmGz_fc


    最近は鳴潮やエンドフィールドなど、Dolby Atmosに対応するゲームが増えてきました。
    私はDENON HOME SOUND BAR 550にDENON HOME 150を2台組み合わせて使っており、迫力のあるサウンドを楽しめています。
    ただ、そこで困ったのがサウンドモードの切り替えです。

    なぜ自動化したいか

    YouTubeなどの動画コンテンツではマルチステレオが好みなのですが、ゲームではキャラの声が少しエコーして聞こえるような違和感がありました。アプリから毎回手動で変更するのは手間がかかるため、ゲーム起動時だけゲーム用Quick Selectに切り替え、普段は通常用Quick Selectに戻す仕組みを作ることにしました。

    必要なもの

    ・Windows 11
    ・PowerShellコマンドを実行できる環境
    ・HEOSアプリ
    注意点としてこの記事のコードはAIを使用して作成していますのでご了承ください。また非公式の方法なので自己責任でお願いします。

    仕組み

    仕組みとしては、DENON HOME SOUND BAR 550 に対してPCからコマンドライン経由で Quick Select の切り替えコマンドを送ります。

    画像
    ゲームやYouTube用であらかじめ設定しておきます。長押しで現在の設定を保存できます。

    Home Assistant(以下HA)の環境があれば設定をそこに集約してコマンドをHAから送れるので管理が楽になります。私はHAを使っていますが今回は使わずにPCから直接サウンドバーにコマンドを送る方法を紹介します。

    サウンドバーのIPアドレスを調べる

    まずHEOSアプリやルーターなどでサウンドバーのIPアドレスを調べます。
    HEOSアプリであればマイデバイス→設定→詳細から見ることができます。
    サウンドバーのIPアドレスは固定にしておきましょう。

    pidを調べる

    DENON HOME SOUND BAR 550 は、HEOS CLIというネットワーク経由の制御機能を持っています。
    次にこのHEOS CLIを使って機器の pid を調べます。
    以下のPowerShellで、YOUR_DENON_IP を自分のサウンドバーのIPアドレスに置き換えてください。

    $ip = "YOUR_DENON_IP"
    $port = 1255
    
    $client = New-Object System.Net.Sockets.TcpClient
    $client.Connect($ip, $port)
    
    $stream = $client.GetStream()
    $writer = New-Object System.IO.StreamWriter($stream)
    $reader = New-Object System.IO.StreamReader($stream)
    
    $writer.NewLine = "`r`n"
    $writer.AutoFlush = $true
    
    $writer.WriteLine("heos://player/get_players")
    
    Start-Sleep -Milliseconds 500
    
    while ($stream.DataAvailable) {
        $reader.ReadLine()
    }
    
    $reader.Close()
    $writer.Close()
    $stream.Close()
    $client.Close()


    実行すると色々出てきますがpidと書いているところの数値を控えておきます。(画像はありません)

    ゲーム監視スクリプト

    pidを控えたら次は以下のスクリプトを実行します。これはゲームの起動を監視するスクリプトで以下のものは鳴潮(Client-Win64-Shipping)とエンドフィールド(endfield)が設定されています。ゲームのexeファイルはゲーム起動時にタスクマネージャで確認するとわかります。
    またQuick Selectの1がYouTubeなどの普段用でマルチステレオ、2がゲーム用でDolby Atmosに私はしています。

    "YOUR PID"の箇所に先ほど調べた数値を入れます。

    $DenonIp = "YOUR_DENON_IP"
    $DenonPort = 1255
    $HeosPlayerId = "YOUR PID"
    $NormalQuickSelect = 1
    $GameQuickSelect = 2
    
    # 監視したいゲームのプロセス名(拡張子 .exe は不要)
    $TargetProcesses = @(
        "Client-Win64-Shipping",
        "endfield"
    )
    
    $lastState = "normal"
    $lastMatchedProcess = ""
    
    function Send-DenonQuickSelect {
        param(
            [string]$Ip,
            [int]$Port,
            [string]$HeosPlayerIdValue,
            [int]$QuickSelectId
        )
    
        $client = $null
        $stream = $null
        $writer = $null
        $reader = $null
    
        try {
            $client = New-Object System.Net.Sockets.TcpClient
            $client.Connect($Ip, $Port)
    
            $stream = $client.GetStream()
            $writer = New-Object System.IO.StreamWriter($stream)
            $reader = New-Object System.IO.StreamReader($stream)
    
            $writer.NewLine = "`r`n"
            $writer.AutoFlush = $true
            $writer.WriteLine("heos://player/play_quickselect?pid=$HeosPlayerIdValue&id=$QuickSelectId")
    
            Start-Sleep -Milliseconds 500
    
            while ($stream.DataAvailable) {
                $null = $reader.ReadLine()
            }
        }
        catch {
        }
        finally {
            if ($reader) { $reader.Close() }
            if ($writer) { $writer.Close() }
            if ($stream) { $stream.Close() }
            if ($client) { $client.Close() }
        }
    }
    
    while ($true) {
        try {
            $matched = $null
    
            foreach ($proc in $TargetProcesses) {
                if ($null -ne (Get-Process -Name $proc -ErrorAction SilentlyContinue)) {
                    $matched = $proc
                    break
                }
            }
    
            $isGameRunning = $null -ne $matched
    
            if ($isGameRunning -and $lastState -ne "game") {
                Send-DenonQuickSelect -Ip $DenonIp -Port $DenonPort -HeosPlayerIdValue $HeosPlayerId -QuickSelectId $GameQuickSelect
                $lastState = "game"
                $lastMatchedProcess = $matched
            }
            elseif ($isGameRunning -and $lastState -eq "game" -and $matched -ne $lastMatchedProcess) {
                $lastMatchedProcess = $matched
            }
            elseif (-not $isGameRunning -and $lastState -ne "normal") {
                Send-DenonQuickSelect -Ip $DenonIp -Port $DenonPort -HeosPlayerIdValue $HeosPlayerId -QuickSelectId $NormalQuickSelect
                $lastState = "normal"
                $lastMatchedProcess = ""
            }
        }
        catch {
        }
    
        Start-Sleep -Seconds 5
    }


    このスクリプトは .ps1 ファイルとして保存し、PowerShellから実行します。常用する場合はタスクスケジューラに登録しておくと便利です。
    タスクスケジューラでは、トリガーを「ログオン時」に設定します。
    操作では、プログラム/スクリプトに powershell.exe を指定し、引数は以下のように設定します。プログラムのパスは置き換えてください。

    -WindowStyle Hidden -ExecutionPolicy Bypass -File "YOUR ps1 file path"


    これで設定したゲームはDolby Atmosになり、終了するとマルチステレオに自動でなります。

    追加機器なしで実現できたのはかなり良かった点です。
    最初はSwitchBot経由も考えましたが、最終的にはDENON本体のHEOS CLIを直接使うのがいちばん安定していました。
    Home Assistantに組み込む方法については、別の記事でまとめる予定です。


     
     
    自作PCやスマホに関連した記事を忘備録兼ねて投稿する予定です。 YouTubeもやっているのでそちらで伝えきれなかった内容を主に投稿しようかなと思います。 イラスト/ノーコピライトガール

    あなたへのおすすめ