Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

main

[C#/Winform] 마이크 온/오프 기능 윈폼앱 본문

ETC

[C#/Winform] 마이크 온/오프 기능 윈폼앱

1984 2023. 4. 26. 22:25

* C#

* Visual Studio 2022 Community

 

1. 프로젝트 생성

Window Form 앱을 생성한다.

 

2. 보기 > 도구 상자 클릭

 

3. label, button 등 필요한거 추가함.

 

4. 패키지 설치를 위해 솔루션 탐색기 > 프로젝트 우클릭 > 솔루션용 NuGet 패키지 관리.. 클릭

NuGet : 패키지 관리 프로그램

5. 찾아 보기 탭 > NAudio 검색 > 프로젝트 선택 > 설치 

6. 코드 작성

* 마이크 On/Off 토글 버튼

* 마이크 장치 이름

* 마이크 장치 On/Off 상태 확인

* 마이크 On / Off 시 메세지 창

* 마이크 장치 없을 때 종료

* 다른 스레드에서 On/Off 하는 것 체크

* Scroll Lock 키에 단축키 할당 / 프로그램 종료 시 단축키 삭제

using Microsoft.VisualBasic;
using NAudio.CoreAudioApi;
using System.Resources;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ToggleMicApp
{
    public partial class Form1 : Form
    {
        // MMDeviceEnumerator 객체 생성
        MMDeviceEnumerator enumerator = new MMDeviceEnumerator();

        // RegisterHotKey 함수
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        // UnregisterHotKey 함수
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        // 단축키 ID (Toggle Key)
        private const int HOTKEY_ID = 0;

        public void CheckMicStatus()
        {
            // 기본 입력 장치 (마이크) 가져오기
            MMDevice device = (MMDevice)enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications);
            //생성된 스레드가 아닌 다른 스레드에서 호출될 경우 true
            var deviceName = device.DeviceFriendlyName;
            if (label2.InvokeRequired)
            {
                Console.WriteLine("out thread");
                label2.Invoke(new MethodInvoker(delegate ()
                {
                    label2.Text = deviceName;

                }));
                if (device.AudioEndpointVolume.Mute)
                {
                    label4.Invoke((MethodInvoker)(() => label4.Text = "Off"));
                    button1.Invoke((MethodInvoker)(() => button1.Text = "마이크 켜기(&X)"));
                    button1.Invoke((MethodInvoker)(() => notifyIcon1.BalloonTipText = "마이크 꺼짐"));

                }
                else
                {
                    label4.Invoke((MethodInvoker)(() => label4.Text = "On"));
                    button1.Invoke((MethodInvoker)(() => button1.Text = "마이크 끄기(&X)"));
                    button1.Invoke((MethodInvoker)(() => notifyIcon1.BalloonTipText = "마이크 켜짐"));
                }
            }
            else
            {
                Console.WriteLine("in thread");
                label2.Text = device.DeviceFriendlyName;
                if (device.AudioEndpointVolume.Mute)
                {
                    label4.Text = "Off";
                    button1.Text = "마이크 켜기(&X)";
                    notifyIcon1.BalloonTipText = "마이크 꺼짐";
                }
                else
                {
                    label4.Text = "On";
                    button1.Text = "마이크 끄기(&X)";
                    notifyIcon1.BalloonTipText = "마이크 켜짐";
                }
            }

            notifyIcon1.ShowBalloonTip(0);

        }

        public void ToggleMicOnOff()
        {
            var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications);
            // 마이크 On/Off
            device.AudioEndpointVolume.Mute = !device.AudioEndpointVolume.Mute;

            // 마이크 상태 Label 값 변경
            //CheckMicStatus();
        }

        public Form1()
        {
            InitializeComponent();
            try
            {
                var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications);
                device.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
                CheckMicStatus();
            }
            catch (Exception ex)
            {
                // 예외 처리
                if (ex is COMException)
                {
                    MessageBox.Show("연결된 기본 마이크가 없습니다.", "장치 없음", MessageBoxButtons.OK, MessageBoxIcon.Error);

                }
                else
                {
                    MessageBox.Show(ex.Message, "알 수 없는 에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                // 예외 발생 시 강제 종료
                Environment.Exit(1);
            }
        }

        private void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
        {
            Console.WriteLine("VolumeNotification: {0}", data.MasterVolume);
            // 마이크 상태 변경 시 실행할 로직 구현
            CheckMicStatus();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine("button click");
            ToggleMicOnOff();
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 0x0312 && m.WParam.ToInt32() == HOTKEY_ID)
            {
                // 단축키 처리 코드 작성
                ToggleMicOnOff();
                Console.WriteLine("토글 실행");
            }

        }


        private void Form1_Load(object sender, EventArgs e)
        {
            // Ctrl + Alt + Shift + M 단축키 등록
            Console.WriteLine(" 단축키 등록");
            RegisterHotKey(this.Handle, HOTKEY_ID, 0x0, (int)Keys.Scroll);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            // 등록한 단축키 해제
            Console.WriteLine(" 단축키 해제");
            UnregisterHotKey(this.Handle, HOTKEY_ID);
        }
    }
}

7. github 에 저장

https://github.com/kimsunbal/MicMuteSwitch

 

GitHub - kimsunbal/MicMuteSwitch: Mic on/off toggle switch with hotkey(Scroll lock)

Mic on/off toggle switch with hotkey(Scroll lock). Contribute to kimsunbal/MicMuteSwitch development by creating an account on GitHub.

github.com

 

참고자료

https://www.youtube.com/watch?v=xfOM1sIMlGw&ab_channel=ProgrammingKnowledge 

https://iamadeveloper.tistory.com/183

https://11cc.tistory.com/10

 

728x90
Comments