티스토리 뷰
C#에는 오디오 파일을 재생하기 위한 최고의 라이버르리가 존재한다.
사운드 Input부터 믹싱까지 다양한 기능이 있지만, 이 글에서는 단순 오디오 파일의 재생만 다룬다.
1. NuGet에서 NAudio를 검색하여 아래 스크린샷에 체크한 2개를 다운 받는다.
- NAudio.Vorbis는 NAudio를 Fork하여 파생된 프로젝트로, 기존 NAudio에서 지원하지 않는 형식인 .oga와 .ogg 파일의 재생을 위해 만들어진 프로젝트다.
2. Player의 재생은 개별 Thread로 해야하며, NAudio 공식 샘플은 async/await로 되어 있다. 이 글에서는 BackgroundWorker로 구현한 코드를 올린다.
- 구버전의 NAudio의 경우, 파일에 따라 그에 맞는 WaveStream을 써야 한다. 최신 버전의 NAdio는 AudioFileReader를 이용하면 각 파일에 맞는 WaveStream을 생성 해준다.
- .oga, .ogg 파일의 경우는 NAudio에서 지원하지 않는 형식으로, NAudio.Vorbis의 VorbisWaveReader를 이용하여 WaveStrea을 생성 해준다.
using NAudio.Vorbis;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace MusicPlayer
{
public class Player
{
public static readonly string[] GaneralExtensions = new string[] { ".mp3", ".mp4", ".wav", ".wma", ".flac", ".m4a" };
public static readonly string[] VorbisExtensions = new string[] { ".oga", ".ogg" };
public void Play(string filePath)
{
var bw = new BackgroundWorker();
bw.DoWork += delegate (object sender, DoWorkEventArgs e)
{
IWavePlayer player = null;
WaveStream reader = null;
try
{
reader = CreateReader(filePath);
player = new WaveOut(WaveCallbackInfo.FunctionCallback());
player.Init(reader);
player.Volume = 1.0F;
player.Play();
while (true)
{
int check = (int) Math.Ceiling(reader.CurrentTime.TotalSeconds);
if (check >= reader.TotalTime.TotalSeconds) break;
Thread.Sleep(10);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
if (player != null)
{
player.Stop();
}
if (reader != null)
{
reader.Dispose();
reader = null;
}
}
};
bw.RunWorkerAsync();
}
private WaveStream CreateReader(string filePath)
{
string extension = Path.GetExtension(filePath);
extension = extension.ToLower();
if (VorbisExtensions.Contains(extension))
{
return new VorbisWaveReader(filePath);
}
else
{
return new AudioFileReader(filePath);
}
}
}
}
'C#' 카테고리의 다른 글
C#: List Swap (by index) (0) | 2021.01.30 |
---|---|
C#: List Shuffle 구현 방법 (0) | 2021.01.30 |
C#: UI 프리징을 피하기 위한 Task 사용 방법 (0) | 2020.05.13 |
C#: WCF ServiceClient의 IDiaposable 구현 (0) | 2019.04.24 |
C#: GDI+와 Memento 패턴을 이용한 그림판 프로그램 (0) | 2019.01.13 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday