如何用C/C++動手編程一款windows平台下的屬於自己的音樂播放器軟體?

小弟作為一個萌新,剛初學C++,萌生想用C++編寫一個帶界面的音樂播放器管理軟體:可以有播放列表,播放記憶,播放暫停等相關功能,目的是通過實際的動手操作,熟悉基本的windows軟體編寫流程,同時利用C++寫程序加深對C++的理解,希望知乎大神給予指導,需要哪些步驟,每個步驟需要學習哪些知識,小弟不勝感謝!!


這個我拿手啊……至少曾經拿手過。曾在相近領域(攝像頭)幹了五年,然後到今天放下五年了。

你若就想用C/C++,並且就想在Windows上練習,那麼DirectShow / Windows Media Foundation是你的最佳選擇!至於界面什麼的我懶得提了,肯定會有別的回答教你用Qt什麼的。那無所謂。

再說一遍:DirectShow 或 Windows Media Foundation。二選一即可。

後者我只聽說過,因為到它隨著Vista推出時我剛好辭職干別的去了。但是知道它是DirectShow的接替者。

要想玩DirectShow,你必須具備兩個基礎知識:

1,Windows多線程編程。

可以去讀侯捷先生翻譯的《Win32多線程程序設計》。

2,COM編程。

可以去讀潘愛民先生著作的《COM原理與應用》 —— 這本書要吸收裡面的基礎知識。

然後讀潘愛民先生的《深入解析ATL》或者其英文原版《ATL Internals》。這本書實踐性強一些,但是是基於古老的ATL的。但你要用C++,那好像也只有這個了。

至於DirectShow,怎麼說呢,可以讀一讀陸琪明這個人寫的《DirectShow開發指南》,或者讀其英文原版《MSDN》。

-----------------------

最後給你一個強烈建議:千萬不要去網上隨便找一個mp3播放控制項然後一門心思做界面!!不要重複我十來年前干過的傻事。

而且即使你最後DirectShow通關了,你也不等於會解析mp3了!只等於會在Win32上「操作」流媒體文件了。


必須來答一記,大一的時候成天都在做音樂播放器……還做了好幾版。起因其實是要幫助高中同學做C語言的實驗,好像最後一個大實驗就是做一個能放音樂的程序。下面的流程和用到的庫/Win32 API可以給你作參考:

第一版當然就是普通的控制台程序,讀入用戶輸入的字元,比如p是播放/暫停,f是輸入文件路徑之類的。這一版播放功能用的是Windows Media Control Interface(Windows Multimedia),界面就是普通的控制台界面。

截圖和代碼什麼的都沒有了……

第二版的播放功能還是用的MCI,加了能讀ID3 tag的功能。這一版主要是主要是界面上做了一點改進,提供了兩種界面,Console和Graphical。

Console版本的界面的輸出用SetConsoleCursorPosition(SetConsoleCursorPosition function)設定游標位置,響應輸入用ReadConsoleInput(ReadConsoleInput function)。

Graphical版本沒用UI庫,只用VS拖了一個Dialog,所有的事件處理等工作全都手擼Win32 API。這兩個界面還能隨時切換。

代碼當時整理硬碟的時候被偶然發現,所以傳到GitHub了,題主可以參考:dontpanic92/AudioPlayer

第三版把播放的解碼功能替換成了libmpg123,輸出好像用的是sdl,還做了一下FFT。界面上主要是在Console界面上下了點功夫。做成了這個樣子:

支持滑鼠點擊,做了按鈕,做了能拖動的進度條,做了顯示lyric歌詞的功能。感謝人人網還保留著我的截圖……代碼應該還在硬碟里,但不知道被我丟到哪裡去了……

UPDATE:找到了一份代碼,dontpanic92/AudioPlayer3 但是Win10的Cmd打開界面好像會亂掉

第四版的播放功能添加了其他文件格式的支持,比如ogg/flac/ape之類的,添加了能檢測音樂BPM的功能(用的SoundTouch)。界面上完全重做,使用了WTL做了兩套界面。一套是做了一個簡單的皮膚引擎,能支持千千靜聽那個藍不拉幾很有vista風格的皮膚,當時正巧當C語言助教課,還給下一屆的師弟師妹們在課上show過。另一套主要是為了嘗試用DwmExtendFrameIntoClientArea (DwmExtendFrameIntoClientArea function)。

這一版的代碼應該也在硬碟里,說不定我晚上回去還能搶救一下

UPDATE:這份代碼也找到啦 dontpanic92/AudioPlayer4


怎麼都在回答Qt還是WPF。

自己做音樂播放器,UI就是個皮毛問題。真正的問題是你對各種音樂格式是否真正了解,以及對系統API的熟悉,要不然你到csdn還是哪直接下個原碼然後改改不就行了。

在這推薦兩個庫,PortAudio,NAudio(注意這是C#的,但我覺得設計的不錯)作代碼參考。


反對上面都在討論怎麼構造UI的答案,

下面是我的建議:

設計一個音樂播放器可以包括以下幾個步驟:

  1. 聲音文件讀取模塊。從磁碟中讀取指定格式的文件,比如wav,mp3等。讀取一些音頻信息,比如採樣率,解析率,幀數量,時長,確定文件完整性的校驗碼,以及特定格式的一些參數。這時需要上網查找一下對應格式的定義,例如:MP3 File Format Specification Microsoft WAVE soundfile format
  2. 音頻解碼器。讀取文件中的音頻數據塊。如果時wav文件直接就可以得到pcm數據。如果是有編碼的,需要找對應格式的codec,例如這個,LAME MP3 Encoder。
  3. 音頻輸出到設備。可以直接找windows api,不過我建議使用一下跨平台的庫,例如 an Open-Source Cross-Platform Audio API
  4. 這時可以開始設計你的軟體結構,繼承體系,比如所有格式的解碼器都繼承自一個基類,基類中定義抽象的decode方法。程序整體結構為解碼器輸入為一個istream ,根據istream動態選擇派生類來完成解碼。然後把音頻輸出模塊抽象為一個ostream,這樣總的結構就成了 istream - &> decoder -&> ostream
  5. 可以考慮播放網路音樂。這時只需要擴展一下前面的istream,比如基類就叫做AudioInputStream,原先從文件讀取的那個類繼承AudioInputStream。然後可以基於socket做一個簡單的ftp或http客戶端,也繼承AudioInputStream。而AudioInputStream可以定義一個這樣構造方法,其參數為一個url。文件在這裡視為一種特殊的協議,比如url可能是這樣的file:///C:/hello.wav,或者ftp://example.com/hello.mp3,或者是http://example.com/hello.aac 。增加了網路播放,可能會遇到一下額外的問題,比如網路不佳怎麼辦?這是就需要按需設計輸入緩衝區。
  6. 也可以考慮輸出做一些擴展,如果輸出不是喇叭,而是一個文件呢?我們在ostream前面增加一個encoder模塊,如果是喇叭就什麼都不做,如果是文件就按文件格式選擇encoder.這是軟體結構就是這樣了,istream -&> decoder -&> decoder -&>ostream 。做到了這一步的話,那麼恭喜你做播放器的同時還順手做出來一個轉碼工具了。。

做完了這些大概就差不多了,今後無論想擴展音頻輸入源支持其他協議還是支持其他的格式就都很容易了。


解碼用ffmpeg,音頻io用wasapi,xaudio,portaudio都可以,界面xaml或者qt。

如果windows獨佔可以做成uwp的。現在uwp正缺好的音樂播放器。

做的時候注意優先順序和緩衝問題,還要考慮實時精確計算播放時間。


瀉藥,大家說的方案都挺對的。

如果我是我的話第一選擇是Qt,因為平時C++寫的最多,C++的所有GUI庫里Qt最熟悉(當然Qt不單單是GUI庫),音頻播放的功能也都有相關的API提供。不需要了解什麼額外的解編碼知識就可以寫出來。界面、音頻文件處理都可以很簡單,也很直觀。

auto player = new QMediaPlayer();
player-&>setMedia(QUrl::fromLocalFile("filename.mp3"));
player-&>play();

這三行代碼就可以了,其實也是調用了DirectShow。不過我們用起來簡單就好了。配合上Qt其他的功能,一個功能豐富,界面好看,還跨平台的音樂播放器分分鐘就出來了。下面這個就是剛剛花了三分鐘左右做的一個簡易播放器。

第二選擇,如果只在Windows上用,應該就是C++/CX,結合XAML做界面,Windows也提供了很多很方便的API,你不需要了解什麼解碼知識就可以直接播放音頻。不過這個C++/CX只用過一次,寫了一個計算器demo就沒再用過了。

第三個選擇就是了解一下相關的解碼庫,然後選擇一個GUI框架寫,不太推薦,不過如果是為了學習,還是用這個方法比較好。

第四個選擇是OpenFrameWorks這一些創意編程的庫,C++有好多這種很神奇的框架,完全封裝底層代碼,所以可讀性超級好,播放音頻真的很簡單,也可以很容易製作出很漂亮的界面,只要你有想像力,什麼都可以做到,這個OpenFrameWorks貌似是一堆微軟的工程師搞出來的。PS:如果只是音頻的話你的系統上一般都有相應的解碼功能,所以不需要你自己再配置。

ofSoundPlayer mySound;
mySound.load("fileName.mp3");
mySound.play();

PS:話說C#也挺好用。。。


既然是初學者,如果想快速實現有界面的程序,可以嘗試Qt、MFC之類的庫。

C++不太適合做圖形界面,比較繁瑣,Windows下最快的圖形界面開發工具是VB或易語言。可以C++做庫,其它語言調用。

如果想用C++做圖形界面可以學習Qt,具體網上有資料,MFC比較老舊不過也可以學習。

學習完簡單的語法,做個界面,直接調用別人的音頻解碼庫就可以了(也可以用ActiveX插件),調用完就是做界面交互,不會很困難。對於初學者,如果打算自己學習音頻解碼技術可能會比較困難,難度和圖像編程有一拼。

對於音頻庫,可以參考這個:簡單的C++ MP3播放器類 - VC開發指南 - 程序員博客

列表實現可以用數組、容器等等的方案,播放暫停是調用庫的功能,記憶則是操作讀寫文件。這些不全是C++基礎的內容,甚至不需要學習完C++的基礎內容就可以實現的。

如果想幾天就做個帶精美圖形界面的小程序而不是黑窗口,甚至可以嘗試一星期學習一個易語言,這個具備快速開發能力的東西很容易提升自己的信心。

C++是艱苦奮鬥的路程,前期付出與回報是不成正比的。耐心學下去,祝有所成。


涉及二塊 一個是gui一個是底層播放庫

前者可以使用qt後者可以使用gaudio我寫的播放器sdk. http://github.com/ccsdu2004/gaudio


我理解啊,你只是想找個實際的練手的項目。1. 用mfc有點坑,有可能你要先熟悉mfc的手冊,不一定能快速見到效果。

2. 如果說只是練手,wxWidgets和QT都行,兩者都有建立解碼器的快速方法,後者可能要好一點,編碼,解碼這塊不用費心,精力就就在前端UI的結構上就好,用滑鼠拖拖點點就好,兩者都有書籍教程介紹。我建議你用它們工具設計好了之後自己,把生成的類參照手冊好好改改,能學到不少。

3. 想鑽研一下,這就比較難了。前端依然QT或者wxWidgets或者其它你熟悉UI庫。但是後面的事兒,至少要做到了解碼器的API調用,我推薦FFMPEG或DIRECTSHOW,可能要用到緩存,具體看情況。也可以關注一下編碼格式,存儲格式,這兩個還好。涉及到信號處理就算了吧,咱們不是數學家沒必要學那些定理和證明。

4. 其實你要是能搞到緩存這兒,你也可再寫個視頻播放器。


用Qt的QML語言寫界面,QML可以快速開發界面,加上設計,C++寫邏輯層,一個漂亮的播放器就生成了。

或者用WPF


一般做軟體先規劃一下,之前看知乎上也有前輩總結說,實現的時候先考慮當前這個階段,這一層次的事情,比如在宏觀上做前台的時候我只考慮前台該具備哪些東西,搭好界面,對應的播放啊、暫停啊、下一首啊留個介面在那不具體寫就行了,在做後台的時候專心想著怎麼解析,怎麼控制讀取進度之類的就可以。

前台這邊,因為感覺qt對新手比較友好,上手快所以推薦qt,你可以先放幾個簡單的按鈕上邊實現功能,詳細界面樣式等做完之後用qss設置,qss和css很像,可以做參考。

後台方面像前面前輩說的,既有現成的庫函數可以直接拿來用,也可以自己鑽研一下怎麼去解析,以及解析各種不同的音頻格式。其實去了解一種文件類型並讀出來感覺也挺有意思的。

還有就是做的時候盡量培養一下面向對象的思路,我的第一個軟體就是想一步做一步寫一步硬生生把代碼變成了這個流程翻譯...


初學的挫折感是很可怕的。當年畢業前捧著本visual c++ 6.0啃了1年,愣沒拿下來。後來工作用了1年別的語言後才轉的C++。有了點編程基礎和實際需求,學起來確實快一些。

針對題主目前的狀況,個人建議你在動手做播放器之前,先把C/C++語言基礎、最基本的數據結構熟悉一下。IDE建議就用Visual Studio 2017 社區版。有了以上基礎,用VS+MFC組合去實現你的小目標,學習曲線就會相對平滑。當然,MFC也不要刻意去深入鑽研,用些簡單組件攢出播放器就行。相信網上也有足夠多的資源來支撐你渡過這一階段。


用Qt ,百度下一大堆例子,研究透了還可以去讀Qt源碼。學到一些工程性的代碼如何編寫。

至於播放器的解碼之類的,用ffmpeg吧。


用gtk吧,實現起來很簡單


初學?那還是先拖個播放器控制項吧,別搞什麼DShow,MF。話說DShow淘汰十幾年了,Win98時代的產物。

另外一定要用C++做界面的話,還有個新選擇,Windows10 UWP的XAML C++/CX(CX是微軟的擴展,也可以用標準C++,就是做界面麻煩點),Windows通用平台(電腦,平板,手機,xbox,VR等)。學習下還是可以的。說不定哪天微軟讓XAML C++也支持Win32傳統桌面了呢。感興趣可以看看。


你的問題要點不明確。

其他答案,有說界面的,有說音頻解碼的。說界面的,又涉及多種庫。

你要說清楚,界面方面,你是想了解基本的 Win32 應用開發,還是說了解其他更簡單的庫?

解碼方面,你是想能播放就好,還是想了解具體的解碼流程?


你可以參考一下VLC,解碼器啊,或者ffmpeg,了解一下com編程啊這些,然後參考一些資料(比方說msdn上關於dx的部分),自己動手寫一個出來。不需要你解碼太多格式,搞一個wav/pcm就好了。界面什麼的對於播放器而言不是非常重要的問題。


github上搜索vlc或者google搜索mediaplayerclassic+A。


其他人並沒有說中這個問題的要害,對於你的需求來說大體來說分為UI,播放和解碼三塊。UI就是大家說到的,用qt還是mfc還是duilib,這個真的沒那麼重要。重要的是播放和解碼。播放的話,windows下可以用directsound和openal,解碼就是一個非常複雜的問題了。你可以把整個文件靜態讀入內存並播放(如wav),更多時候,需要按照流的形式,一邊解碼一邊寫入緩存,這需要你對音頻格式有一定的了解,熟悉一些解碼庫(如libmad),也要對windows線程同步有一定了解


用QT吧,如果要著手去做一定要先把數據結構先架好,別就在腦子裡有個印象就著手開始做,上來就打代碼,對於新手來說打到一半思路就被打亂了


萌新別用C++做界面 死的快

做界面去用C#


推薦閱讀:

c++中cin和scanf的區別是什麼?
客戶端產品一般是用什麼編程語言寫的?
應該把C語言學習到什麼程度?
學習 C 語言需要數學基礎嗎?
怎樣提高自己代碼可讀性?

TAG:編程語言 | 應用程序Application | C編程語言 | C |