見出し画像

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に組み込む方法については、別の記事でまとめる予定です。


いいなと思ったら応援しよう!