programing

PowerShell에서 소리를 음소거/ 음소거하려면 어떻게 해야 합니까?

lovejava 2023. 10. 6. 20:46

PowerShell에서 소리를 음소거/ 음소거하려면 어떻게 해야 합니까?

시작할 때 소리를 음소거하고, 처음부터 음소거하지 않은 경우에만 소리를 음소거하고 끝에서 음소거를 해제하는 PowerShell cmdlet을 작성하려고 합니다.사용할 수 있는 PowerShell 또는 WMI 개체를 찾을 수 없습니다.auxGetVolume 또는 auxSetVolume과 같은 Win32 기능을 사용하는 것을 가지고 놀고 있었지만 제대로 작동할 수 없었습니다(IntPtr에서 값을 읽는 방법?).

V2 CTP2를 사용하고 있습니다.무슨 생각 있어요?

감사합니다!

Vista부터는 Core Audio API를 사용하여 시스템 볼륨을 제어해야 합니다.자동화를 지원하지 않는 COM API이므로 에서 사용하기 위해 많은 보일러 플레이트가 필요합니다.NET 및 PowerShell.

할 수 .[Audio]::Volume그리고.[Audio]::MutePowerShell 의 속성.이것은 유용할 수 있는 원격 컴퓨터에서도 작동합니다.PowerShell 창에 코드를 복사하여 붙여넣기만 하면 됩니다.

Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;

[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume {
  // f(), g(), ... are unused COM method slots. Define these if you care
  int f(); int g(); int h(); int i();
  int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
  int j();
  int GetMasterVolumeLevelScalar(out float pfLevel);
  int k(); int l(); int m(); int n();
  int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
  int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice {
  int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator {
  int f(); // Unused
  int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }

public class Audio {
  static IAudioEndpointVolume Vol() {
    var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
    IMMDevice dev = null;
    Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
    IAudioEndpointVolume epv = null;
    var epvid = typeof(IAudioEndpointVolume).GUID;
    Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
    return epv;
  }
  public static float Volume {
    get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;}
    set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));}
  }
  public static bool Mute {
    get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
    set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
  }
}
'@

사용 샘플:

PS C:\> [Audio]::Volume         # Check current volume (now about 10%)
0,09999999
PS C:\> [Audio]::Mute           # See if speaker is muted
False
PS C:\> [Audio]::Mute = $true   # Mute speaker
PS C:\> [Audio]::Volume = 0.75  # Set volume to 75%
PS C:\> [Audio]::Volume         # Check that the changes are applied
0,75
PS C:\> [Audio]::Mute
True
PS C:\>

좀 더 포괄적인 것들이 있습니다.코어 오디오 API에 대한 NET 래퍼가 필요한 경우 해당 패키지를 제공하지만 파워셸 친화적인 cmdlet 세트를 알지 못합니다.

추신: 디오고의 답변은 현명한 것 같지만 저에게는 통하지 않습니다.

ps1 powershell 스크립트에서 다음 명령을 사용합니다.

$obj = new-object -com wscript.shell 
$obj.SendKeys([char]173)

Alexandre의 답변은 제 상황에 맞지만, 'var'의 네임스페이스에 대한 컴파일 오류로 인해 예제가 작동하지 않습니다..net의 새로운/다른 버전이 예제를 작동하지 않을 수 있습니다.컴파일 오류가 발생한 경우 다음과 같은 경우 시도해 볼 수 있는 대체 버전입니다.

Add-Type -Language CsharpVersion3 -TypeDefinition @'
using System.Runtime.InteropServices;

[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume {
  // f(), g(), ... are unused COM method slots. Define these if you care
  int f(); int g(); int h(); int i();
  int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
  int j();
  int GetMasterVolumeLevelScalar(out float pfLevel);
  int k(); int l(); int m(); int n();
  int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
  int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice {
  int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator {
  int f(); // Unused
  int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }

public class Audio {
  static IAudioEndpointVolume Vol() {
    var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
    IMMDevice dev = null;
    Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
    IAudioEndpointVolume epv = null;
    var epvid = typeof(IAudioEndpointVolume).GUID;
    Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
    return epv;
  }
  public static float Volume {
    get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;}
    set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));}
  }
  public static bool Mute {
    get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
    set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
  }
}
'@

사용 방법은 동일합니다.

PS C:\> [Audio]::Volume         # Check current volume (now about 10%)
0,09999999
PS C:\> [Audio]::Mute           # See if speaker is muted
False
PS C:\> [Audio]::Mute = $true   # Mute speaker
PS C:\> [Audio]::Volume = 0.75  # Set volume to 75%
PS C:\> [Audio]::Volume         # Check that the changes are applied
0,75
PS C:\> [Audio]::Mute
True
PS C:\>

음량을 조절하는 빠르고 쉬운 방법은 없는 것 같습니다.만약 당신이 c++ 경험이 있다면, 당신은 이 블로그 게시물로 무언가를 할 수 있을 것입니다. 여기서 Larry Osterman은 플랫폼 api에서 IAudioEndpointVolume 인터페이스를 호출하는 방법을 설명합니다(Vista의 경우 XP가 몇 번의 검색에서 발견한 것보다 더 어려울 수 있습니다).

V2에서는 Add-Type을 통해 인라인 코드를 컴파일할 수 있으므로 이를 선택할 수 있습니다.

Windows 오디오 서비스를 관리하기만 하면 다른 방법으로 고양이를 가죽을 벗길 수 있습니다.음소거하지 말고, 음소거하지 않게 시작합니다.

PowerShell이 아닌 것은 알지만 Michael과 Diogo의 답변을 종합하면 한 줄짜리 VB스크립트 솔루션이 제공됩니다.

CreateObject("WScript.Shell").SendKeys(chr(173))

이거 집어넣어요.mute.vbs 두 번 , 를 할 수 .

  • Windows 10(10586.104)에서도 작동합니다.
  • 그럴 필요 없어요.Set-ExecutionPolicy PowerShell을

vbscript의 솔루션:

Set WshShell = CreateObject("WScript.Shell")
For i = 0 To 50
  WshShell.SendKeys(chr(174))
  WScript.Sleep 100
Next

키를 사용하면 볼륨이 매번 2씩 줄어듭니다.

PowerShell에서 이 작업을 수행하는 방법을 찾지 못했지만, NirCmd라는 명령행 유틸리티가 있습니다.

C:\utils\nircmd.exe mutesysvolume 0  # 1 to to unmute, 2 to toggle

NirCmd는 여기 http://www.nirsoft.net/utils/nircmd.html 에서 무료로 이용할 수 있습니다.

파워셸에서 오디오 레벨 변경에 대한 제 답변을 확인해보시겠습니까?

Set-DefaultAudioDeviceMute

답변에 대한 피드백을 받은 후 다시 시도해 보겠습니다.

이것은 여기 https://github.com/frgnca/AudioDeviceCmdlets 에서 찾을 수 있는 @frgnca의 AudioDeviceCmdlets를 기반으로 합니다.

여기 모든 기록 장치를 음소거하는 코드가 있습니다.

Import-Module .\AudioDeviceCmdlets
$audio_device_list = Get-AudioDevice -list
$recording_devices = $audio_device_list | ? {$_.Type -eq "Recording"}
$recording_devices 
$recording_device_index = $recording_devices.Index | Out-String -stream
foreach ($i in $recording_device_index) {
    $inti = [int]$i
    Set-AudioDevice $inti | out-null -erroraction SilentlyContinue
    Set-AudioDevice -RecordingMute 1 -erroraction SilentlyContinue
}

AudioDeviceCmdlets dll을 가져온 다음 녹음 장치로 필터링된 모든 오디오 장치 목록을 저장합니다.모든 녹음 장치의 인덱스를 잡은 다음 각각의 장치를 반복하여 장치를 기본 오디오 장치로 설정한 다음 해당 장치를 음소거로 설정합니다(이 2단계 프로세스는 dll에 의해 제한됩니다).

모든 것을 음소거하지 않으려면 -Recording Mute 1을 Recording Mute 0으로 바꿉니다.

마찬가지로 음소거 재생 장치에서도 다음 코드를 사용할 수 있습니다.

Import-Module .\AudioDeviceCmdlets
$audio_device_list = Get-AudioDevice -list
$playback_devices = $audio_device_list | ? {$_.Type -eq "Playback"}
$playback_devices 
$playback_device_index = $playback_devices.Index | Out-String -stream
foreach ($i in $playback_device_index) {
$inti = [int]$i
    Set-AudioDevice $inti | out-null -erroraction SilentlyContinue
    Set-AudioDevice -PlaybackMute 1 -erroraction SilentlyContinue
}

모든 것을 음소거하지 않으려면 -PlaybackMute 1PlaybackMute 0으로 변경합니다.

이 코드는 아두이노를 통해 물리적 버튼/LED 음소거 상태 디스플레이에 연결하여 모든 시스템 마이크를 음소거/음소거 해제(줌, 미팅, 팀, 디스코드 등을 지원)하고 사람들이 당혹스러운 핫마이크 사고를 피할 수 있도록 지원하는 더 큰 프로젝트의 일부에서 비롯되었습니다.

https://github.com/dakota-mewt/mewt

1

추신. 파워셸에서 오디오 레벨을 변경하는 것과 같은 한 줄 솔루션을 정말 좋아합니다.

그러나 한 줄 음소거는 일반적으로 현재 Windows 기본값으로 설정된 단일 장치에만 적용됩니다.따라서 Zoom(줌) 및 Meet(밋)과 같은 다양한 오디오 장치를 처리할 수 있는 소프트웨어가 있는데 이 소프트웨어가 기본이 아닌 장치를 사용하는 경우 원하는 대로 작동하지 않을 수 있습니다.

위의 두 번째 스크립트에서 첫 번째 줄의 PowerShell 7 또는 PowerShell Core에서 작동하려면 다음과 같이 변경합니다.

-Language CsharpVersion3

...에게

-Language Csharp

10원 작업 중

오토핫키(autohotkey dotcom)를 사용하는 간단한 시간 음소거 스크립트가 있습니다.

mbutton::; 마우스 휠을 클릭하여 이 스크립트를 트리거합니다.

SoundSet, +1, Mute; PC 사운드 음소거

sleep, 27000 ; 성가신 광고가 실행될 때까지 27초를 기다립니다.

SoundSet, +1, Mute; PC 사운드 음소거 해제

언급URL : https://stackoverflow.com/questions/255419/how-can-i-mute-unmute-my-sound-from-powershell