2013年7月10日 星期三

[Note] 使用NAudio Libary 建立一個簡單的音樂播放器 (C#)

在一般C/C++ , C#等.NET 平台下,對於音訊處理方面的功能是相當鮮少的,所以我們今天要來使用一個Open Source 函式庫來做一個簡單的音樂播放器。




NAidio 是一個開源的函式庫應用於.NET 平台,擁有很多有關於音訊處理的Classes 給開發者使用。

關於NAudio 的專案(Click me)

話不多說,馬上開始。


1.首先先建立一個專案 C#


2.加入參考,下載NAudio 之後。



















3. 在介面上加入兩個按鈕 。 一個為 讀檔、一個為 播放/暫停。(亦為程式的圖)













4.  首先必須先宣告 使用NAudio 的兩個變數。

一個為wave , 一個為 output.

wave : 讀取來源的音訊檔

output : 播放由NAudio做用完的音訊檔。

        private NAudio.Wave.WaveFileReader wave = null;
        private NAudio.Wave.DirectSoundOut output = null;


5. 在播放按鈕的程式區塊加入

            // read audio file (.wav)
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "Wave file (*.wav)|*.wav";
            if (open.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            DisposwWave();
            // open file into wave variable
            wave = new NAudio.Wave.WaveFileReader(open.FileName);
            output = new NAudio.Wave.DirectSoundOut();
            // because the wave file is not a IWave file , so need to make a covertion
            output.Init(new NAudio.Wave.WaveChannel32(wave));
            output.Play();
            // when music is playing ,the button can be clicked .
            pause_button.Enabled = true;


以上為開檔並且播放。

OpenFileDialog 為 C# 讀取檔案的方法。

Disposewave ()為垃圾回收技術。

因為一開始讀入的檔案為wave format 的 stream ,但是要給 NAudio做處理,

就必須轉換成 IWave 格式的stream ,所以須經過 output.Init(); 做轉換處理。

然後開始播放為 output.Play();

並且將 暫停按鈕設為可以按 。


6.  接下來加入暫停按鈕的程式區塊

            if(output != null)
            {
                //when music is plauing , then pause it.
                if(output.PlaybackState == NAudio.Wave.PlaybackState.Playing)
                {
                    output.Pause();
                }
                // when music is paused , then play it .
                else if(output.PlaybackState == NAudio.Wave.PlaybackState.Paused)
                {
                    output.Play();
                }
            }

如以上,很清楚地可以從程式碼得知,如果狀態是在播放中,則暫停。

如果狀態為暫停,則播放。

7. DisposeWave()

            if (output != null)
            {
                if (output.PlaybackState == NAudio.Wave.PlaybackState.Paused)
                {
                    output.Stop();
                }
                output.Dispose();
                output = null;
            }
            if(wave != null)
            {
                wave.Dispose();
                wave = null;
            }

此為如果要關閉串流,或是停止,有新的狀態下都必須設定為初始化null

8.  Enjoy it

完整程式碼(請點我)-wav

9. 附註

此外可以調整使用NAudio去播放MP3 檔案,

在宣告時變數如下(因為MP3為壓縮過後檔案需要用stream 去讀取)

private NAudio.Wave.BlockAlignReductionStream stream = null;//cause mp3 file 

在讀取按鈕程式區塊改變為

            // read audio file (.mp3)
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "MP3 file (*.mp3)|*.mp3";
            if (open.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            DisposeWave();
            // use pcm data to restore mp3 file (because NAudio has no mp3 format code)
            NAudio.Wave.WaveStream pcm = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(open.FileName));
            stream = new NAudio.Wave.BlockAlignReductionStream(pcm);
            output = new NAudio.Wave.DirectSoundOut();
            // because the stream file is not a IWave file , so need to make a covertion
            output.Init(stream);
            output.Play();
            // when music is playing ,the button can be clicked .
            pause_button.Enabled = true;


在上面程式碼裡面,原本讀取wav 檔案的方式改變了。

因為mp3是受過壓縮編碼過後的檔案,原本的NAudio 並沒有辦法可以去直接讀取一個mp3檔

案,所以必須去還原成pcm data。(說明請點我)

在將讀入的pcm data  轉換成stream 讓NAudio 可以去讀取。

我們依然還是要轉換成IWave 格式才可以往下繼續運作。

其餘後面部分原本的 wave更改成為 stream變數即可。

完整程式碼請點我 - MP3




參考來源 :

NAudio (CodePlex)

C# Audio Tutorial



沒有留言:

張貼留言