카테고리 없음

[Windows] 특정 프로세스 오디오 출력 디바이스 변경 스크립트, 트러블슈팅

시남 2026. 3. 30. 23:57

[Windows] 특정 프로세스 오디오 출력 디바이스 변경 스크립트, 트러블슈팅

Firefox 사운드를 블루투스 스피커로 보내기 위해 PowerShell 스크립트를 만들면서
겪은 삽질들을 정리해두었습니다.

 

완성한 PowerShell 스크립트는 아래에서 확인 가능합니다. Star 한 번씩 부탁드립니다 :)

https://gist.github.com/sinam7/703412ff6ab17e653141670c4054567f


들어가며

하고 싶은 건 단순했다. Firefox 에서 틀어놓은 유튜브 소리를 블루투스 스피커로 보내고,
필요하면 다시 기본 출력으로 돌리는 것. 이런 일은 Claude에게 맡기기에 딱이다.

 

Windows는 프로세스별 오디오 라우팅 API를 공식으로 제공하지 않아서,
NirSoft의 SoundVolumeView / svcl을 써야 한다.
그 과정에서 여러 가지 문제를 겪었는데, 그 기록을 남겨본다.


0. 준비물

두 파일을 같은 폴더에 넣어두면 된다.


1. & 연산자로 exe 실행이 안 됨

증상

& : 'C:\...\soundvolumeview-x64' 용어가 cmdlet, 함수, 스크립트 파일 또는
실행할 수 있는 프로그램 이름으로 인식되지 않습니다.

원인

경로에 .exe가 없거나, 경로에 공백이 포함된 경우 따옴표 처리가 안 된 것.

해결

# 실행 파일 확장자 포함, 경로 전체를 따옴표로 감쌀 것 (아래 경로는 예시)
$svcl = "C:\Users\User\Desktop\Tools\soundvolumeview-x64\svcl.exe"

2. param 블록 위치 오류

증상

대입 식이 잘못되었습니다. 대입 연산자의 입력은 변수 또는 속성과 같이
대입을 허용할 수 있는 개체여야 합니다.

원인

param 블록 앞에 관리자 권한 상승 코드를 먼저 배치하면 파싱 오류가 발생한다.
PowerShell에서 param은 반드시 스크립트 최상단에 있어야 한다.

해결

# 맨 위에 param 먼저. 디바이스 이름과 프로세스명은 필요에 맞게 수정할 것
param(
    [string]$Device  = "Philips S2108 Stereo",
    [string]$Default = "Realtek High Definition Audio",
    [string]$Process = "firefox"
)

# 그 다음 관리자 권한 상승. svcl 사용을 위해선 관리자 권한이 필요
if (-not ([Security.Principal.WindowsPrincipal]...)) {
    Start-Process powershell -ArgumentList "... -Device `"$Device`" ..." -Verb RunAs
    exit
}

관리자 권한으로 재실행 시 파라미터도 명시적으로 넘겨줘야 기본값이 유지된다.


3. 한글 깨짐

증상

콘솔 출력에서 한글이 ?? 또는 알 수 없는 문자로 표시됨.

해결

스크립트 상단에 아래 두 줄 추가.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
chcp 65001 | Out-Null

그래도 깨진다면 스크립트 파일 자체의 인코딩을 확인하자.
VS Code 기준으로 우측 하단에서 UTF-8 with BOM으로 저장하면 된다.


4. /RemoveAppDefault가 동작하지 않음

증상

시스템 기본 출력으로 복원하기 위해 /RemoveAppDefault 명령어를 썼더니
SoundVolumeView GUI가 그냥 열리거나, 아무 반응이 없었다.

원인

/RemoveAppDefault는 SoundVolumeView 공식 문서에 없는 명령어다.
환각 문제는 역시 완벽하게 해결될 수 없는 것 같다.

해결

복원할 때도 /SetAppDefault를 쓰되, 시스템 기본 디바이스 이름을 직접 지정한다.

현재 Firefox 오디오 라우팅 상태 확인:

& $svcl /scomma "$env:TEMP\app_check.csv" | Out-Null
Get-Content "$env:TEMP\app_check.csv" -Encoding UTF8 | Select-String "firefox"

출력 결과에서 Active 항목의 Device Name이 현재 라우팅된 디바이스,
Inactive 항목이 시스템 기본 디바이스다.

Firefox,Application,Render,Philips S2108 Stereo,,,,Active,...
Firefox,Application,Render,Realtek High Definition Audio,,,,Inactive,...

이 경우 복원 명령은 다음과 같다.

& $svcl /SetAppDefault "Realtek High Definition Audio" all "firefox.exe"

5. 명령어 실행 시 GUI가 열림

증상

svcl 명령어 실행 시 터미널 출력 없이 GUI 창으로 열림.

원인

PowerShell에서 슬래시(/)가 나누기 연산자로 파싱되는 경우가 있다.

해결

Start-Process로 교체하면 안정적으로 동작한다.

Start-Process -FilePath $svcl `
    -ArgumentList "/SetAppDefault `"$Device`" all `"$Process.exe`"" `
    -Wait -WindowStyle Hidden

-WindowStyle Hidden으로 창이 뜨는 것도 막을 수 있다.


맺으며

Windows에서 프로세스별 오디오 라우팅은 공식 API가 없다 보니,
제3자 툴에 의존할 수밖에 없고 그 과정에서 문서화가 덜 된 부분들이 꽤 있다.
Windows 11에서는 좀 나아졌으려나 모르겠다.

/RemoveAppDefault처럼 없는 명령어를 추측으로 쓰다가 삽질한 게 가장 아팠다. (Claude가.)
결국 실제 디바이스 목록을 csv로 뽑아서 확인하고 나서야 해결됐다.

뭔가 안 된다 싶으면 추측보다 먼저 상태를 확인하는 게 맞다.

# 현재 오디오 라우팅 상태 확인 (항상 여기서 시작)
& $svcl /scomma "$env:TEMP\check.csv" | Out-Null
Get-Content "$env:TEMP\check.csv" -Encoding UTF8 | Select-String "firefox"
 

이 글은 Claude를 통해 스크립트를 작성한 뒤, Troubleshooting을 이전 글 문체로 작성시킨 뒤 최소한의 퇴고만 거쳐 게시되었습니다.