2022. 5. 25. 15:30

.NET으로 사운드 파일을 재생하려면 보통 'SoundPlayer'를 사용합니다.

근데 이놈은 한 번에 하나의 파일만 재생이 가능합니다.

 

여러 파일을 재생하려면 

'DirectX SDK', 'Windows Media Player SDK', 'NAudio' 같은 외부 라이브러리를 이용하거나

'WinAPI'를 이용해야 합니다.

 

이 포스팅에서는 'WinAPI'의 'mciSendString'를 이용하여 재생하겠습니다.

 

 

1. 'SoundPlayer'를 사용해 보자

'SoundPlayer'를 사용하여 파일을 재생해봅시다.

아래와 같이 개체를 초기화하고

private SoundPlayer _soundPlayer1;
 
 
this._soundPlayer1 = new SoundPlayer();
this._soundPlayer1.SoundLocation = @"SoundFiles\IsUse.wav";

아래 코드로 재생을 해봅시다.

this._soundPlayer1.Play();

 

재생이 끝나기 전에 다시 재생을 시도하면

기존 재생이 끊기고 다시 재생하는것을 확인할 수 있습니다.

 

 

2. 'mciSendString'를 이용하자

WinAPI기 때문에 'DllImport'를 통해 "winmm.dll"파일을 불러와야 합니다.

'mciSendString'의 진입점은 아래와 같이 선언하면 됩니다.

/// <summary>
/// https://docs.microsoft.com/ko-kr/previous-versions//dd757161(v=vs.85)
/// </summary>
/// <param name="command"></param>
/// <param name="buffer"></param>
/// <param name="bufferSize"></param>
/// <param name="hwndCallback"></param>
/// <returns></returns>
[DllImport("winmm.dll")]
static extern Int32 mciSendString(
    string command
    , StringBuilder buffer
    , int bufferSize
    , IntPtr hwndCallback);

 

 

2-1. 파일 열기

'mciSendString'로 파일을 열려면 아래와 같이 명령어를 만들어야 합니다.

//open [파일 경로] type [파일 타입] alias [구분용 고유이름]
open SoundFiles\IsUse.wav type waveaudio alias SoundMci1

 

이걸 위에서 만든 진입점의 'command' 파라메타에 넣어주면 됩니다.

mciSendString(@"open SoundFiles\IsUse.wav type waveaudio alias SoundMci1"
                , null, 0, IntPtr.Zero);

 

 

2-2. 파일 재생하기

파일 재생 명령어는 아래와 같습니다.

//play [구분용 고유이름]
play SoundMci1

'play SoundMci1'을 여러 번 전달해도 재생은 한 번만 되는 것을 알 수 있습니다.

이런 현상이 일어나는 이유는 재생되던 위치를 그대로 가지고 있기 때문입니다.

 

2-3. 재생 위치 초기화

재생 위치를 초기화하면 처음부터 파일이 재생되게 됩니다.

//seek [구분용 고유이름] to start
seek SoundMci1 to start

이 명령어를 사용하면 재생 중이던 개체(구분용 고유이름 기준)는 재생을 정지합니다.

 

 

2-4. 파일 재생 정지

재생 중인 개체도 정지시킬 수 있습니다.

//stop [구분용 고유이름]
stop SoundMci1

 

하지만 다시 재생하면 멈췄던 부분부터 재생됩니다.

'pause'와 차이점을 모르겠습니다.

 

처음부터 재생하려면 '2-3. 재생 위치 초기화'를 해야 합니다.

 

 

3. 테스트 프로그램

github - dang-gun/DotNetSamples/SoundPlayerTest

 

윈폼으로 간단하게 만들었습니다.

 

 

마무리

이 이슈가 오래된 거로 아는데 왜 .NET에서 공식적으로 지원을 하지 않는지 모르겠습니다.

구현 방법이 없는 것도 아닐 텐데 말이죠....

다른 플랫폼들 때문에 그러나?? 아니면 외부 라이브러리로 커버가 가능해서 그런가?