第一篇:基于java的音樂(lè)播放器課程設(shè)計(jì)報(bào)告
Java課程設(shè)計(jì)報(bào)告
題目:java音樂(lè)播放器
姓
名 學(xué)
號(hào) 院
系 班
級(jí) 專
業(yè) 任課教師
1.設(shè)計(jì)內(nèi)容及要求
能夠?qū)崿F(xiàn)簡(jiǎn)單的音樂(lè)播放器功能,如:打開本地文件,播放,暫停,停止,背景播放,單曲循環(huán)等等,界面充實(shí),交互友好,可以添加多首歌曲目錄
一個(gè)簡(jiǎn)單的基于java語(yǔ)言的音樂(lè)播放器,菜單欄:文件,播放控制和播放列表,文件菜單包含打開、循環(huán)和退出三個(gè)菜單項(xiàng);播放控制菜單包含播放、暫停和停止三個(gè)菜單項(xiàng),播放列表菜單則是當(dāng)向里面添加歌曲之后才能夠查看到里面所包含的歌曲目錄。當(dāng)播放歌曲時(shí),可以調(diào)節(jié)音量大小或者設(shè)置是否靜音;可以查看當(dāng)前播放音樂(lè)的相關(guān)屬性,如:歌曲名,歌手,發(fā)布時(shí)間,所屬專輯等等。
2.需求分析
1、時(shí)間跟蹤條:根據(jù)歌曲播放的進(jìn)度,控制條自動(dòng)進(jìn)行追蹤,用戶可以
隨時(shí)了解歌曲的播放進(jìn)度
2、音量控制鍵:可以點(diǎn)擊該控鍵進(jìn)行音量大小的調(diào)節(jié)以及是否靜音的設(shè)
置
3、屬性查詢鍵:通過(guò)該控鍵,用戶可以查看當(dāng)前播放音樂(lè)的相屬性,獲
取關(guān)于該歌曲的用戶所需的相關(guān)信息。
4、菜單欄:
①文件:
打開:用戶通過(guò)該菜單項(xiàng)打開本地音樂(lè)文件,聽任何用戶想
聽的歌曲
循環(huán):通過(guò)循環(huán)設(shè)置,用戶可以重復(fù)的播放一首喜歡的歌曲
退出:退出音樂(lè)播放器,及退出該程序
②播放控制:
播放:選擇歌曲之后,通過(guò)點(diǎn)擊播放菜單項(xiàng)啟動(dòng)播放器播
放音樂(lè)
暫停:暫停當(dāng)前正在播放的音樂(lè)
停止:停止當(dāng)前正在播放的音樂(lè)
③播放列表:當(dāng)用戶通過(guò)文件打開本地音樂(lè)文件后,及相當(dāng)于在
播放列表里面添加了歌曲,及形成相應(yīng)的歌曲播放目錄
3.總體設(shè)計(jì)
結(jié)合需求分析來(lái)看,整個(gè)設(shè)計(jì)包含了簡(jiǎn)單的菜單欄,根據(jù)用戶需求設(shè)置了三個(gè)簡(jiǎn)單的實(shí)現(xiàn)基本操作的菜單,分別是:文件,播放控制,播放列表;根據(jù)具體的操作每個(gè)菜單還包含了相應(yīng)的菜單項(xiàng),文件:打開,循環(huán),退出;播放控制:播放,暫停,停止;播放列表則沒(méi)有菜單項(xiàng),該菜單就是用來(lái)顯示或者查看相應(yīng)的歌曲目錄的。
該音樂(lè)播放器設(shè)置了兩個(gè)窗口,運(yùn)行程序時(shí)打開的初始化歡迎界面,用戶可以根據(jù)自己的需求進(jìn)行菜單欄里面的基本操作和相應(yīng)的設(shè)置,當(dāng)用戶添加或者打開音樂(lè)播放文件的時(shí)候,程序?qū)?huì)顯示出第二個(gè)音樂(lè)文件播放窗口,與此同時(shí),第一個(gè)初始化窗口將會(huì)自動(dòng)隱藏,在音樂(lè)播放窗口里面用戶可以進(jìn)行相關(guān)的音樂(lè)播放的控制操作。
當(dāng)用戶進(jìn)入音樂(lè)播放窗口時(shí),該窗口有幾個(gè)快捷控制的控鍵:時(shí)間追蹤軸:可以實(shí)現(xiàn)播放的前進(jìn)、后退功能,根據(jù)用戶需求調(diào)節(jié)音樂(lè)的播放進(jìn)度等;音量控制:設(shè)置靜音,打開揚(yáng)聲器或者調(diào)節(jié)音量大??;播放列表:查看當(dāng)前播放音樂(lè)的相關(guān)屬性。4.主要功能設(shè)計(jì)流程
5.系統(tǒng)實(shí)現(xiàn)及測(cè)試:
(一)JMF(java媒體框架)簡(jiǎn)介
JMF 即Java媒體框架。其核心框架支持不同媒體,如音頻輸出和視頻輸出,包括時(shí)間的時(shí)鐘同步。它是一個(gè)標(biāo)準(zhǔn)的擴(kuò)展框架,允許用戶制作純音頻流和視頻流。
JMF實(shí)際上是Java的一個(gè)類包。它包括了一個(gè)開放的媒體架構(gòu),可使開發(fā)人員靈活采用各種媒體回放、捕獲組件,或采用他們自己的定制的內(nèi)插組件。
JMF軟件是Java Media系列軟件的一部分。采用各種Java Media API,軟件開發(fā)商人員就能容易、快速地為他們已有的各種應(yīng)用程序和客戶端,Java小程序增添豐富的媒體功能,如流式視頻、3D圖像和影像處理等。就是 說(shuō),各種Java Media API發(fā)揮了Java平臺(tái)的固有優(yōu)勢(shì),將“編寫一次,到處運(yùn)行”的能力擴(kuò)展到了圖像、影像和數(shù)字媒體等各種應(yīng)用領(lǐng)域,從而大大縮減了開發(fā)時(shí)間和降低了開發(fā) 成本。
在開發(fā)JMF 應(yīng)用程序之前要完全理解JMF 的體系架構(gòu)、接口和類。就拿我們的家用攝像機(jī)系統(tǒng)作個(gè)例子。首先用攝像機(jī)拍攝內(nèi)容,拍攝下來(lái)的內(nèi)容錄制在DV帶中。DV帶可以放在放像機(jī)里播放、放像機(jī)提供視頻信號(hào)給電視機(jī),提供音頻信號(hào)給音箱,這樣我們就可以在電視機(jī)上看到畫面,從音箱里聽到聲音。JMF API 提供的也是同樣的模型。
JMF 提供的模型可大致分為七類
* 數(shù)據(jù)源(Data source)
* 截取設(shè)備(Capture Device,包括視頻和音頻截取設(shè)備)
* 播放器(Player)
* 處理器(Processor)
* 數(shù)據(jù)池(DataSink)
* 數(shù)據(jù)格式(Format)
* 管理器(Manager)
如果只是想觀看捕獲的內(nèi)容,只需要使用捕獲數(shù)據(jù)源創(chuàng)建播放器Player即可。如果想把捕獲的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)或者保存起來(lái),就需要?jiǎng)?chuàng)建處理器Processor。
基本步驟是首先獲取視頻、音頻捕獲設(shè)備的信息,然后再根據(jù)取得的設(shè)備信息確定設(shè)備的位置。找到設(shè)備的位置以后,調(diào)用ManageCreatePlayer方法創(chuàng)建Player,當(dāng)Player開始播放的時(shí)候,就開始了捕獲的過(guò)程。
有多種方法獲得捕獲設(shè)備信息,可以通過(guò)查詢指定的格式,也可以查詢特定的設(shè)備名字。Player準(zhǔn)備好播放數(shù)據(jù),當(dāng)Player發(fā)出這個(gè)事件時(shí),就可以獲取播放器的可視面板和控制面板了。具體步驟如下:
1.先把所有的捕獲設(shè)備調(diào)出來(lái)
2.創(chuàng)建Player,當(dāng)Play開始的時(shí)候,就開始了音頻捕獲的過(guò)程
3.以MediaLocator為參數(shù),創(chuàng)建Player 4.為PLAYER添加監(jiān)聽器,以便監(jiān)聽RealizeComplete事件
(二)代碼實(shí)現(xiàn)
(1)添加庫(kù)、包等相關(guān)文件 import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.EndOfMediaEvent;import javax.media.PrefetchCompleteEvent;import javax.media.RealizeCompleteEvent;import javax.media.*;import javax.swing.*;import java.awt.*;
import java.awt.event.*;
(2)初始化窗口
1代碼實(shí)現(xiàn)
private void init(){
// TODO Auto-generated method stub
this.setLayout(new BorderLayout());
JPanel lrcPanel = new JPanel();
JPanel controP= new JPanel();
jta = new JTextArea(22,35);
jta.setBackground(Color.black);
jta.setLineWrap(true);
jta.setWrapStyleWord(true);
jta.setEditable(false);
lrcPanel.add(new JScrollPane(jta));
lrcPanel.setBackground(Color.black);
lrcPanel.setVisible(true);
JButton Jstart= new JButton(“");Jstart.setIcon(new ImageIcon(”start.png“));
Jstart.addActionListener(new ActionListener(){
@Override public void actionPerformed(ActionEvent arg0){
// TODO Auto-generated method stub
start();} });JButton Jpause=new JButton();Jpause.setIcon(new ImageIcon(”停止.png“));Jpause.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){
stop();
} });JButton Jnext =new JButton();Jnext.setIcon(new ImageIcon(”next.png“));Jnext.addActionListener(new ActionListener(){
@Override public void actionPerformed(ActionEvent e){
// TODO Auto-generated method stub
next();} });JButton Jprior =new JButton();Jprior.setIcon(new ImageIcon(”back.png“));Jprior.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){
back();} });controP.setLayout(new FlowLayout());controP.add(Jprior);controP.add(Jstart);controP.add(Jpause);
} controP.add(Jnext);
this.add(lrcPanel,BorderLayout.CENTER);this.add(controP,BorderLayout.SOUTH);
(3)音樂(lè)播放窗口機(jī)基本功能的實(shí)現(xiàn) ①界面
②代碼實(shí)現(xiàn)
// 播放方法
public void start(){
if(isplaying==false){
try {
player =
Manager.createPlayer(new File(mp3List.get
(mp3NO)).toURI().toURL());
jta.setText(null);
} catch(NoPlayerException e){
// TODO 自動(dòng)生成 catch BufferedReader(new FileReader(lcf));
String s;
塊
e.printStackTrace();
System.out.println(”不能播放此文件!“);
return;
} catch(IOException e){
// TODO 自動(dòng)生成 catch 塊
e.printStackTrace();
return;
}
if(player == null){
System.out.println(”播放文件為空!“);
return;
}
player.addControllerListener(this);
// 提取媒體內(nèi)容
player.prefetch();
isplaying=true;//正在播放一首歌
setLrc();
} }
private void setLrc(){
// TODO Auto-generated method stub
File lrcfile = new File(lrcpath);
if(!lrcfile.exists()){
lrcfile.mkdir();
}
String lrcFName = getlrcFName();
BufferedReader bReader;
File lcf= new File(lrcpath+lrcFName+”.lrc“);
System.out.println(lcf.getName());
try {
bReader = new while((s=bReader.readLine())!= null){
jta.append(” “+s);
jta.append(”n“);
}
} catch(Exception e){
// TODO Auto-generated catch block
jta.setText(”沒(méi)有歌詞“);
System.out.println(”沒(méi)有歌詞文件!“);
}
}
private String getlrcFName(){//解析歌曲名;
// TODO Auto-generated method stub
String musicPath = mp3List.get(mp3NO);
String s =musicPath.substring(11);
System.out.println(s);
String []str = s.split(”.“);
String lrcFName=str[0];
System.out.println(lrcFName);
return lrcFName;}
public void stop(){
player.stop();
isplaying=false;}
public void next(){
if(isplaying==true)
stop();
if(mp3NO mp3NO++; start(); } else{ jta.setText(”沒(méi)有下一首了 // 當(dāng)提取媒體的內(nèi)容結(jié)束 if(e instanceof PrefetchCompleteEvent){ System.out.println(“內(nèi)容結(jié)束”); player.start(); return; }(<_>“); } } public void back(){ if(isplaying) stop(); if(mp3NO>0){ mp3NO--; start(); } else jta.setText(”已經(jīng)是第一首歌了(<_>)“);} public void controllerUpdate(ControllerEvent e){ // 當(dāng)媒體播放結(jié)束時(shí),循環(huán)播放 if(e instanceof EndOfMediaEvent){ isplaying=false; mp3NO++; System.out.println(mp3NO); if(mp3NO < mp3List.size()){ this.start(); } return; } // 當(dāng)實(shí)例化后 if(e instanceof RealizeCompleteEvent){ System.out.println(”實(shí)例化“); // pack();//執(zhí)行pack()操作 return; } } public void setMp3List(){ File file = new File(musicpath); if(!file.exists()){ file.mkdir(); } File[] mcFiles; mcFiles = file.listFiles(); if(mcFiles!=null){ for(File f : mcFiles){ System.out.println(f.getPath()); mp3List.add(f.getPath()); } }else System.out.println(”MyMusic中沒(méi)有歌曲文件"); } 6.總結(jié)與說(shuō)明 在做寫程序?qū)崿F(xiàn)功能的過(guò)程中,界面和基本功能的設(shè)計(jì)需要較強(qiáng)的邏輯思維,一不小心就容易出錯(cuò),在具體的功能設(shè)計(jì)和實(shí)現(xiàn)的過(guò)程中要盡可能用最簡(jiǎn)單的語(yǔ)句實(shí)現(xiàn)基本的播放器功能。我覺(jué)得可以設(shè)計(jì)更多的菜單及菜單項(xiàng)目從而實(shí)現(xiàn)更多的功能,如:刪除,保存等,還可以實(shí)現(xiàn)更多的背景效果或者更多可選擇的皮膚,還可以對(duì)按鈕添加音效效果,這樣感覺(jué)整個(gè)音樂(lè)播放器更具有靈活性,媒體感更強(qiáng)烈一些,界面會(huì)更加豐富和生動(dòng)一些。 通過(guò)自己做課程設(shè)計(jì),自己設(shè)計(jì)界面,功能和設(shè)計(jì)功能的代碼實(shí)現(xiàn),將理論知識(shí)運(yùn)用到實(shí)際操作中,加深了對(duì)理論知識(shí)的理解和記憶,在做程序設(shè)計(jì)的過(guò)程中,對(duì)很多代碼的多次操作和重復(fù)使用,使得對(duì)很多基本的代碼和相關(guān)的操作能夠牢固的記憶。 Java課程設(shè)計(jì)報(bào)告 題目:java音樂(lè)播放器 姓 名 學(xué) 號(hào) 院 系 班 級(jí) 專 業(yè) 任課教師 1.設(shè)計(jì)內(nèi)容及要求 能夠?qū)崿F(xiàn)簡(jiǎn)單的音樂(lè)播放器功能,如:打開本地文件,播放,暫停,停止,背景播放,單曲循環(huán)等等,界面充實(shí),交互友好,可以添加多首歌曲目錄 一個(gè)簡(jiǎn)單的基于java語(yǔ)言的音樂(lè)播放器,菜單欄:文件,播放控制和播放列表,文件菜單包含打開、循環(huán)和退出三個(gè)菜單項(xiàng);播放控制菜單包含播放、暫停和停止三個(gè)菜單項(xiàng),播放列表菜單則是當(dāng)向里面添加歌曲之后才能夠查看到里面所包含的歌曲目錄。當(dāng)播放歌曲時(shí),可以調(diào)節(jié)音量大小或者設(shè)置是否靜音;可以查看當(dāng)前播放音樂(lè)的相關(guān)屬性,如:歌曲名,歌手,發(fā)布時(shí)間,所屬專輯等等。 2.需求分析 1、時(shí)間跟蹤條:根據(jù)歌曲播放的進(jìn)度,控制條自動(dòng)進(jìn)行追蹤,用戶可以 隨時(shí)了解歌曲的播放進(jìn)度 2、音量控制鍵:可以點(diǎn)擊該控鍵進(jìn)行音量大小的調(diào)節(jié)以及是否靜音的設(shè) 置 3、屬性查詢鍵:通過(guò)該控鍵,用戶可以查看當(dāng)前播放音樂(lè)的相屬性,獲 取關(guān)于該歌曲的用戶所需的相關(guān)信息。 4、菜單欄: ①文件: 打開:用戶通過(guò)該菜單項(xiàng)打開本地音樂(lè)文件,聽任何用戶想 聽的歌曲 循環(huán):通過(guò)循環(huán)設(shè)置,用戶可以重復(fù)的播放一首喜歡的歌曲 退出:退出音樂(lè)播放器,及退出該程序 ②播放控制: 播放:選擇歌曲之后,通過(guò)點(diǎn)擊播放菜單項(xiàng)啟動(dòng)播放器播 放音樂(lè) 暫停:暫停當(dāng)前正在播放的音樂(lè) 停止:停止當(dāng)前正在播放的音樂(lè) ③播放列表:當(dāng)用戶通過(guò)文件打開本地音樂(lè)文件后,及相當(dāng)于在 播放列表里面添加了歌曲,及形成相應(yīng)的歌曲播放目錄 3.總體設(shè)計(jì) 結(jié)合需求分析來(lái)看,整個(gè)設(shè)計(jì)包含了簡(jiǎn)單的菜單欄,根據(jù)用戶需求設(shè)置了三個(gè)簡(jiǎn)單的實(shí)現(xiàn)基本操作的菜單,分別是:文件,播放控制,播放列表;根據(jù)具體的操作每個(gè)菜單還包含了相應(yīng)的菜單項(xiàng),文件:打開,循環(huán),退出;播放控制:播放,暫停,停止;播放列表則沒(méi)有菜單項(xiàng),該菜單就是用來(lái)顯示或者查看相應(yīng)的歌曲目錄的。 該音樂(lè)播放器設(shè)置了兩個(gè)窗口,運(yùn)行程序時(shí)打開的初始化歡迎界面,用戶可以根據(jù)自己的需求進(jìn)行菜單欄里面的基本操作和相應(yīng)的設(shè)置,當(dāng)用戶添加或者打開音樂(lè)播放文件的時(shí)候,程序?qū)?huì)顯示出第二個(gè)音樂(lè)文件播放窗口,與此同時(shí),第一個(gè)初始化窗口將會(huì)自動(dòng)隱藏,在音樂(lè)播放窗口里面用戶可以進(jìn)行相關(guān)的音樂(lè)播放的控制操作。 當(dāng)用戶進(jìn)入音樂(lè)播放窗口時(shí),該窗口有幾個(gè)快捷控制的控鍵:時(shí)間追蹤軸:可以實(shí)現(xiàn)播放的前進(jìn)、后退功能,根據(jù)用戶需求調(diào)節(jié)音樂(lè)的播放進(jìn)度等;音量控制:設(shè)置靜音,打開揚(yáng)聲器或者調(diào)節(jié)音量大?。徊シ帕斜恚翰榭串?dāng)前播放音樂(lè)的相關(guān)屬性。4.主要功能設(shè)計(jì)流程 5.系統(tǒng)實(shí)現(xiàn)及測(cè)試: (一)JMF(java媒體框架)簡(jiǎn)介 JMF 即Java媒體框架。其核心框架支持不同媒體,如音頻輸出和視頻輸出,包括時(shí)間的時(shí)鐘同步。它是一個(gè)標(biāo)準(zhǔn)的擴(kuò)展框架,允許用戶制作純音頻流和視頻流。 JMF實(shí)際上是Java的一個(gè)類包。它包括了一個(gè)開放的媒體架構(gòu),可使開發(fā)人員靈活采用各種媒體回放、捕獲組件,或采用他們自己的定制的內(nèi)插組件。 JMF軟件是Java Media系列軟件的一部分。采用各種Java Media API,軟件開發(fā)商人員就能容易、快速地為他們已有的各種應(yīng)用程序和客戶端,Java小程序增添豐富的媒體功能,如流式視頻、3D圖像和影像處理等。就是 說(shuō),各種Java Media API發(fā)揮了Java平臺(tái)的固有優(yōu)勢(shì),將“編寫一次,到處運(yùn)行”的能力擴(kuò)展到了圖像、影像和數(shù)字媒體等各種應(yīng)用領(lǐng)域,從而大大縮減了開發(fā)時(shí)間和降低了開發(fā) 成本。 在開發(fā)JMF 應(yīng)用程序之前要完全理解JMF 的體系架構(gòu)、接口和類。就拿我們的家用攝像機(jī)系統(tǒng)作個(gè)例子。首先用攝像機(jī)拍攝內(nèi)容,拍攝下來(lái)的內(nèi)容錄制在DV帶中。DV帶可以放在放像機(jī)里播放、放像機(jī)提供視頻信號(hào)給電視機(jī),提供音頻信號(hào)給音箱,這樣我們就可以在電視機(jī)上看到畫面,從音箱里聽到聲音。JMF API 提供的也是同樣的模型。 JMF 提供的模型可大致分為七類 * 數(shù)據(jù)源(Data source) * 截取設(shè)備(Capture Device,包括視頻和音頻截取設(shè)備) * 播放器(Player) * 處理器(Processor) * 數(shù)據(jù)池(DataSink) * 數(shù)據(jù)格式(Format) * 管理器(Manager) 如果只是想觀看捕獲的內(nèi)容,只需要使用捕獲數(shù)據(jù)源創(chuàng)建播放器Player即可。如果想把捕獲的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)或者保存起來(lái),就需要?jiǎng)?chuàng)建處理器Processor。 基本步驟是首先獲取視頻、音頻捕獲設(shè)備的信息,然后再根據(jù)取得的設(shè)備信息確定設(shè)備的位置。找到設(shè)備的位置以后,調(diào)用ManageCreatePlayer方法創(chuàng)建Player,當(dāng)Player開始播放的時(shí)候,就開始了捕獲的過(guò)程。 有多種方法獲得捕獲設(shè)備信息,可以通過(guò)查詢指定的格式,也可以查詢特定的設(shè)備名字。Player準(zhǔn)備好播放數(shù)據(jù),當(dāng)Player發(fā)出這個(gè)事件時(shí),就可以獲取播放器的可視面板和控制面板了。具體步驟如下: 1.先把所有的捕獲設(shè)備調(diào)出來(lái) 2.創(chuàng)建Player,當(dāng)Play開始的時(shí)候,就開始了音頻捕獲的過(guò)程 3.以MediaLocator為參數(shù),創(chuàng)建Player 4.為PLAYER添加監(jiān)聽器,以便監(jiān)聽RealizeComplete事件 (二)代碼實(shí)現(xiàn) (1)添加庫(kù)、包等相關(guān)文件 import javax.media.ControllerEvent;import javax.media.ControllerListener;import javax.media.EndOfMediaEvent;import javax.media.PrefetchCompleteEvent;import javax.media.RealizeCompleteEvent;import javax.media.*;import javax.swing.*;import java.awt.*; import java.awt.event.*; (2)初始化窗口 ①界面 ②代碼實(shí)現(xiàn) public void setupMenu(){ Menu f = new Menu(“文件”); MenuItem mi = new MenuItem(“打開”); CheckboxMenuItem cbmi = new CheckboxMenuItem(“循環(huán)”, false);MenuItem ee = new MenuItem(“退出”);f.add(mi);f.add(cbmi);f.add(ee); mi.addActionListener(this);cbmi.addActionListener(this);ee.addActionListener(this);f.addSeparator();f.addSeparator();f.addSeparator(); Menu l = new Menu(“播放列表”);Menu c = new Menu(“播放控制”); MenuItem move = new MenuItem(“播放”);MenuItem pause = new MenuItem(“暫停”);MenuItem stop = new MenuItem(“停止”);move.addActionListener(this);pause.addActionListener(this);stop.addActionListener(this);c.add(move);c.add(pause);c.add(stop); c.addSeparator();c.addSeparator();c.addSeparator(); MenuBar mb = new MenuBar();mb.add(f);mb.add(c);mb.add(l); setMenuBar(mb);} (3)音樂(lè)播放窗口機(jī)基本功能的實(shí)現(xiàn) ①界面 ②代碼實(shí)現(xiàn) public void actionPerformed(ActionEvent e){ String cufile, selectfile, currentDirectory;if(e.getActionCommand().equals(“退出”)){ dispose(); return;} if(e.getActionCommand().equals(“播放”)){ if(player!= null) player.start();return; } if(e.getActionCommand().equals(“暫?!?) { if(player!= null) player.stop();return;} if(e.getActionCommand().equals(“停止”)){ if(player!= null){ player.stop(); player.setMediaTime(new Time(0));} return;} if(e.getActionCommand().equals(“打開”)){ FileDialog fd = new FileDialog(this, “打開媒體文件”, FileDialog.LOAD);fd.setVisible(true); if(fd.getFile()== null) return; selectfile = fd.getFile(); currentDirectory = fd.getDirectory(); cufile = currentDirectory + selectfile; MenuItem mi = new MenuItem(selectfile);mi.setActionCommand(cufile);MenuBar mb = getMenuBar();Menu m = mb.getMenu(2);mi.addActionListener(this);m.add(mi);} else { cufile = e.getActionCommand();selectfile = cufile;} if(player!= null) player.close();try { player = Manager.createPlayer(new MediaLocator(“file:” + cufile));}catch(Exception e2) { System.out.println(e2);return;} if(player == null){ System.out.println(“無(wú)法創(chuàng)建播放器”);return;} first = false; setTitle(selectfile); player.addControllerListener(this);player.prefetch();} public void itemStateChanged(ItemEvent arg0){ } public static void main(String[] args){ new MediaPlayer(“播放器”);} public void controllerUpdate(ControllerEvent e){ Container tainer = getContentPane();if(e instanceof ControllerClosedEvent){ if(vc!= null){ remove(vc);vc = null;} if(cc!= null){ remove(cc);cc = null;} } if(e instanceof EndOfMediaEvent){ player.setMediaTime(new Time(0));if(loop) player.start();return;} if(e instanceof PrefetchCompleteEvent){ player.start();return;} if(e instanceof RealizeCompleteEvent){ vc = player.getVisualComponent();if(vc!= null) tainer.add(vc, BorderLayout.CENTER); cc = player.getControlPanelComponent();cc.setBackground(Color.blue);if(cc!= null) { tainer.add(cc, BorderLayout.SOUTH);if(vc!= null){ pack();return;} Else { setSize(300, 75);setVisible(true);return;} } } } 6.總結(jié)與說(shuō)明 在做寫程序?qū)崿F(xiàn)功能的過(guò)程中,界面和基本功能的設(shè)計(jì)需要較強(qiáng)的邏輯思維,一不小心就容易出錯(cuò),在具體的功能設(shè)計(jì)和實(shí)現(xiàn)的過(guò)程中要盡可能用最簡(jiǎn)單的語(yǔ)句實(shí)現(xiàn)基本的播放器功能。我覺(jué)得可以設(shè)計(jì)更多的菜單及菜單項(xiàng)目從而實(shí)現(xiàn)更多的功能,如:刪除,保存等,還可以實(shí)現(xiàn)更多的背景效果或者更多可選擇的皮膚,還可以對(duì)按鈕添加音效效果,這樣感覺(jué)整個(gè)音樂(lè)播放器更具有靈活性,媒體感更強(qiáng)烈一些,界面會(huì)更加豐富和生動(dòng)一些。 通過(guò)自己做課程設(shè)計(jì),自己設(shè)計(jì)界面,功能和設(shè)計(jì)功能的代碼實(shí)現(xiàn),將理論知識(shí)運(yùn)用到實(shí)際操作中,加深了對(duì)理論知識(shí)的理解和記憶,在做程序設(shè)計(jì)的過(guò)程中,對(duì)很多代碼的多次操作和重復(fù)使用,使得對(duì)很多基本的代碼和相關(guān)的操作能夠牢固的記憶。 山西大學(xué) 課程設(shè)計(jì)報(bào)告 題 目:基于QT的音樂(lè)播放器 系 別: 軟件學(xué)院 班 級(jí): 1522班 姓 名:賈夢(mèng)潔 學(xué) 號(hào): 同組組員: 設(shè)計(jì)時(shí)間: 2017年12月22日----2017年12月30日 公司名稱: 上海杰普軟件科技有限公司 目 錄 第一章 引言.......................................1 第二章 軟件分析與設(shè)計(jì).............................2 2.1軟件需求分析........................................2 2.2開發(fā)環(huán)境............................................3 2.3軟件概要設(shè)計(jì)........................................3 第三章 軟件功能實(shí)現(xiàn)...............................4 3.1軟件總體架構(gòu)........................................5 3.2軟件功能流程........................................5 3.3具體功能實(shí)現(xiàn)........................................6 第四章 軟件測(cè)試..................................16 第五章 總結(jié)......................................17 第一章 引言 計(jì)算機(jī)技術(shù)的飛速發(fā)展大大提高了人們的工作效率,尤其是互聯(lián)網(wǎng)技術(shù)更是很大程度上豐富和方便了人們的生活。近些年來(lái),人們的生活水平也在不斷提升,在物質(zhì)豐富的條件下,人們開始在工作之余關(guān)注娛樂(lè),期望在其它方面釋放工作壓力,同時(shí)培養(yǎng)自己的興趣愛(ài)好,隨之而來(lái)的是人們對(duì)多媒體應(yīng)用的關(guān)注,許多電影播放平臺(tái)、音樂(lè)播放軟件等逐漸深入人們的生活,并慢慢地成為人們生活重要組成部分。 目前,互聯(lián)網(wǎng)上已經(jīng)擁有大量的音樂(lè)播放軟件,這些軟件是各個(gè)軟件供應(yīng)商的商品關(guān)鍵組成部分,當(dāng)前其實(shí)現(xiàn)技術(shù)較復(fù)雜,在功能方面相當(dāng)完備且強(qiáng)大,如何簡(jiǎn)單、高效、方便地設(shè)計(jì)實(shí)現(xiàn)一款小巧美觀的音樂(lè)播放器軟件成為人們關(guān)注的熱點(diǎn)。基于該問(wèn)題,本文設(shè)計(jì)并實(shí)現(xiàn)了基于Qt的音樂(lè)播放軟件,該軟件能夠便捷、高效地為用戶展示音樂(lè)播放界面,方便的進(jìn)行歌曲播放和控制功能。本文的工作分為軟件界面設(shè)計(jì)和軟件功能實(shí)現(xiàn)兩部分,其中,軟件界面設(shè)計(jì)工作主要包括用戶界面設(shè)計(jì)實(shí)現(xiàn);各個(gè)功能模塊實(shí)現(xiàn)工作主要包括后臺(tái)程序編碼設(shè)計(jì)模塊化完成設(shè)計(jì)等內(nèi)容。 該音樂(lè)播放軟件以Qt開發(fā)平臺(tái)中實(shí)現(xiàn)歌曲播放的相應(yīng)功能為基本框架設(shè)計(jì),通過(guò)C++語(yǔ)言編程實(shí)現(xiàn)各個(gè)功能函數(shù),軟件設(shè)計(jì)方面采用模塊化的軟件設(shè)計(jì)思想實(shí)現(xiàn),具有友好的用戶交互界面和高承載能力的運(yùn)行穩(wěn)定性。 第二章 軟件分析與設(shè)計(jì) 2.1 軟件需求分析 在設(shè)計(jì)實(shí)現(xiàn)音樂(lè)播放器軟件的同時(shí),可以對(duì)目前存在的不同類型的音樂(lè)播放器進(jìn)行廣泛深入的研究,查看軟件可能需要的需求內(nèi)容。因此,需要對(duì)具體問(wèn)題進(jìn)行具體分析,深入挖掘其需要實(shí)現(xiàn)的系統(tǒng)功能,以方便后面對(duì)軟件構(gòu)架的設(shè)計(jì)工作。需求分析的過(guò)程,是開發(fā)人員對(duì)音樂(lè)播放器工作過(guò)程的認(rèn)識(shí)與熟悉的過(guò)程,也是對(duì)軟件內(nèi)部工作流程進(jìn)行計(jì)算機(jī)建模的過(guò)程,最終目的是通過(guò)需求分析了解用戶需求實(shí)現(xiàn)的功能,根據(jù)用戶提出的需求設(shè)計(jì)好系統(tǒng)的概念模型,對(duì)用戶提出的需求進(jìn)行計(jì)算機(jī)方法的描述,并建立相應(yīng)配套的需求分析文檔,設(shè)計(jì)好系統(tǒng)的具體實(shí)現(xiàn)方案。 在設(shè)計(jì)實(shí)現(xiàn)基于Qt的音樂(lè)播放器的同時(shí),考慮到音樂(lè)播放器的實(shí)際工作環(huán)境,可以確定的是該軟件應(yīng)當(dāng)擁有以下幾個(gè)方面的特性: (1)基本功能 隨著電腦終端的擴(kuò)大化,PC機(jī)上各種軟件也不計(jì)其數(shù)。為了使用戶體驗(yàn)及軟件質(zhì)量都達(dá)到一定的完備性,我們需要保證一定的基礎(chǔ)功能。基于人性化角度,開發(fā)設(shè)計(jì)基礎(chǔ)功能,使用戶可以流暢使用軟件。在進(jìn)行功能劃分的過(guò)程當(dāng)中,可以采用模塊化的功能設(shè)計(jì)思想,對(duì)功能的劃分盡可能的細(xì)致,做到不遺漏。例如,應(yīng)當(dāng)有播放模式的選擇,音樂(lè)列表的選擇,音量高低的調(diào)試等。(2)穩(wěn)定性 基于QT的音樂(lè)播放器是一款?yuàn)蕵?lè)軟件,更需要保證軟件的穩(wěn)定性,以使用戶體驗(yàn)達(dá)到最高。若播放器不穩(wěn)定,則用戶體驗(yàn)這一指標(biāo)則會(huì)大幅下降。 (3)聯(lián)通性 移動(dòng)設(shè)備日益增長(zhǎng),微博、微信等交流平臺(tái)在市場(chǎng)中也占據(jù)重要地位。為迎合這一現(xiàn)象,QT音樂(lè)播放器必須進(jìn)行一定的互聯(lián)網(wǎng)聯(lián)通性。可以進(jìn)行音樂(lè)分享、轉(zhuǎn)發(fā)評(píng)論等。這樣可以實(shí)現(xiàn)軟件之間的交流結(jié)合,有利于軟件的推廣。同時(shí)也有利于通過(guò)大數(shù)據(jù)分析,得到聽眾最喜愛(ài)聽的歌曲,符合大眾口味。 2.2 開發(fā)環(huán)境 操作系統(tǒng):Windows 10 開發(fā)平臺(tái):Qt 使用語(yǔ)言:C++ 2.3 軟件概要設(shè)計(jì) 在軟件概要設(shè)計(jì)階段,是基于整個(gè)系統(tǒng)需要實(shí)現(xiàn)的功能,對(duì)物業(yè)管理信息系統(tǒng)的整體架構(gòu)進(jìn)行科學(xué)合理的設(shè)計(jì),使之有一定的規(guī)律可以遵循,不進(jìn)行盲目的設(shè)計(jì)工作,這對(duì)于后期的程序編碼和系統(tǒng)的來(lái)說(shuō)意義重大。在對(duì)音樂(lè)播放器軟件進(jìn)行軟件需求分析之后,針對(duì)需求 分析的結(jié)果,對(duì)系統(tǒng)進(jìn)行了整體的架構(gòu)設(shè)計(jì)。 設(shè)計(jì)實(shí)現(xiàn)的音樂(lè)播放器軟件,從軟件的架構(gòu)來(lái)看,主要包括兩個(gè)功能部分:軟件的歌曲播放部分和圖標(biāo)最小化功能實(shí)現(xiàn)部分。其中,歌曲播放部分主要實(shí)現(xiàn)該軟件的主要功能,即選擇歌曲和播放歌曲;另一部分則是最小化后軟件的實(shí)現(xiàn),主要包括顯示、登錄、設(shè)置、檢查更新、退出。以上是對(duì)該音樂(lè)播放器軟件的整體工作架構(gòu)進(jìn)行的設(shè)計(jì),該步驟是后續(xù)進(jìn)一步進(jìn)行系統(tǒng)功能實(shí)現(xiàn)的基礎(chǔ)。 第三章 軟件功能實(shí)現(xiàn) 在設(shè)計(jì)實(shí)現(xiàn)基于Qt的音樂(lè)播放器軟件的同時(shí),充分考慮了Qt的語(yǔ)言特性和開發(fā)環(huán)境,發(fā)揮了其在用戶界面應(yīng)用程序開發(fā)當(dāng)中的優(yōu)勢(shì),對(duì)音樂(lè)播放器軟件進(jìn)行了開發(fā)。根據(jù)前文對(duì)該音樂(lè)播放器軟件的 需求分析,以及對(duì)軟件的設(shè)計(jì)分析結(jié)果,結(jié)合實(shí)際使用當(dāng)中可能使用到的軟件功能,并采用了軟件工程中模塊化的開發(fā)思想,完成了該音樂(lè)播放器軟件的開發(fā),下面分別對(duì)軟件中重要的功能模塊的實(shí)現(xiàn)方法及實(shí)現(xiàn)效果進(jìn)行詳細(xì)的介紹和分析。 3.1 總體架構(gòu) 通過(guò)在需求階段對(duì)系統(tǒng)的總體功能的分析,我們得到了這個(gè)音樂(lè)播放器軟件的總體功能結(jié)構(gòu),它應(yīng)包括四大基本功能模塊。 (1)選擇歌曲文件模塊:用戶可以方便的查詢環(huán)境當(dāng)中存在的歌曲列表信息,并找到滿意歌曲的位置和具體的歌曲內(nèi)容。 (2)歌曲播放模塊:用戶根據(jù)所選擇的具體歌曲讓該軟件對(duì)歌曲進(jìn)行播放,并且可以實(shí)時(shí)查看歌曲的播放狀態(tài)。 (3)播放狀態(tài)控制模塊:用戶可以查看成自己在歌曲播放過(guò)程中進(jìn)度情況,并可以隨時(shí)更改歌曲的播放進(jìn)度信息。 (4)第二界面模塊:用戶可以進(jìn)入第二個(gè)更為簡(jiǎn)潔的界面進(jìn)行播放、暫停、切換等操作。 3.2 軟件功能流程 整個(gè)軟件所設(shè)計(jì)的工作流程如下: (1)開始。進(jìn)入Qt界面開始運(yùn)行軟件。 (2)播放歌曲。該部分是音樂(lè)播放器軟件最主要的功能部分,播放歌曲的功能實(shí)現(xiàn)需要相對(duì)復(fù)雜的函數(shù)調(diào)用來(lái)實(shí)現(xiàn),在軟件開發(fā)的過(guò)程 當(dāng)中有具體的實(shí)現(xiàn)代碼。 (3)播放設(shè)置。該部分的實(shí)現(xiàn)是進(jìn)一步提高用戶的使用體驗(yàn),方便用戶根據(jù)其自身的需求對(duì)所播放的歌曲進(jìn)行進(jìn)度控制,可以暫停歌曲的播放,也可以繼續(xù)歌曲的播放功能,同時(shí)也可以進(jìn)行音量的調(diào)控,以及對(duì)歌曲播放的順序進(jìn)行調(diào)整,比如順序播放、單曲循環(huán)等。(4)第二界面。點(diǎn)擊shrink按鈕可跳轉(zhuǎn)至第二界面,進(jìn)行播放切換歌曲等操作,也可以進(jìn)行最小化。 (5)結(jié)束。點(diǎn)擊關(guān)閉軟件,結(jié)束軟件運(yùn)行。 3.3 具體功能實(shí)現(xiàn) 本人完成了本次音樂(lè)播放器中的歌曲導(dǎo)入模塊以及播放歌曲的初步工作,具體的實(shí)現(xiàn)過(guò)程如下。 3.3.1歌曲導(dǎo)入(1).h文件 歌曲導(dǎo)入部分的代碼函數(shù)名稱以及相應(yīng)的函數(shù)聲明完成在settingwiget.h的頭文件下,先對(duì)命名空間進(jìn)行前向聲明,對(duì)類內(nèi)的對(duì)象和方法進(jìn)行聲明,具體代碼如下: #ifndef SETTINGWIGET_H #define SETTINGWIGET_H #include namespace Ui { class settingwiget;} class settingwiget : public QWidget { Q_OBJECT public: explicit settingwiget(QWidget *parent = 0);~settingwiget(); void initSystemSetting(void); bool writeInit(QString path, QString user_key, QString user_value);bool readInit(QString path, QString user_key, QString &user_value); private slots: void on_pb_save_clicked(); void on_pb_cancle_clicked(); void on_tb_lyricsPath_clicked(); void on_tb_songsPath_clicked(); void on_pb_save_destroyed(); private: Ui::settingwiget *ui;}; #endif // SETTINGWIGET_H (2).cpp文件 配置文件寫入和讀取的方法完成在settingwiget.cpp文件內(nèi),代碼如下: settingwiget::settingwiget(QWidget *parent): QWidget(parent), ui(new Ui::settingwiget){ ui->setupUi(this); SongsFile::m_songPath.clear();LyricsFile::m_lyricPath.clear();} settingwiget::~settingwiget(){ delete ui;} bool settingwiget::writeInit(QString path, QString user_key, QString user_value){ if(path.isEmpty()|| user_key.isEmpty()){ return false;} else { //創(chuàng)建配置文件操作對(duì)象 QSettings *config = new QSettings(path, QSettings::IniFormat); //將信息寫入配置文件 config->beginGroup(“config”);config->setValue(user_key, user_value);config->endGroup(); return true;} } bool settingwiget::readInit(QString path, QString user_key, QString &user_value){ user_value = QString(“");if(path.isEmpty()|| user_key.isEmpty()){ return false;} else { //創(chuàng)建配置文件操作對(duì)象 QSettings *config = new QSettings(path, QSettings::IniFormat); //讀取用戶配置信息 user_value = config->value(QString(”config/“)+ user_key).toString(); return true;} } 界面設(shè)計(jì)中按鈕的具體功能也對(duì)應(yīng)在settingwiget.cpp文件內(nèi),代碼如下: void settingwiget::on_tb_songsPath_clicked(){ SongsFile::m_songPath = QFileDialog::getExistingDirectory();ui->le_songsPath->setText(SongsFile::m_songPath);} void settingwiget::on_tb_lyricsPath_clicked(){ LyricsFile::m_lyricPath = QFileDialog::getExistingDirectory();ui->le_lyricsPath->setText(LyricsFile::m_lyricPath);} void settingwiget::on_pb_save_clicked(){ writeInit(QString(”../user.ini“), ”SONGPATH“, SongsFile::m_songPath);writeInit(QString(”../user.ini“), ”LYRICPATH“, LyricsFile::m_lyricPath); initSystemSetting();this->hide();} void settingwiget::on_pb_cancle_clicked(){ this->hide();} void settingwiget::initSystemSetting(void){ readInit(QString(”../user.ini“), ”SONGPATH“, SongsFile::m_songPath);readInit(QString(”../user.ini“), ”LYRICPATH“, LyricsFile::m_lyricPath); ui->le_songsPath->setText(SongsFile::m_songPath);ui->le_lyricsPath->setText(LyricsFile::m_lyricPath);} void settingwiget::on_pb_save_destroyed(){} 其中,cpp文件內(nèi)的頭文件為: #include ”settingwiget.h“ #include ”ui_settingwiget.h“ #include 3.3.2歌曲播放的部分功能(1).h文件 musicplayer.h的頭文件下,采用枚舉類型對(duì)播放模式進(jìn)行聲明,寫入信號(hào)和槽方便傳值,對(duì)歌曲播放邏輯、歌曲列表獲取邏輯、歌曲歌詞獲取邏輯的對(duì)象、方法進(jìn)行聲明,具體代碼如下: #ifndef MUSICPLAYER_H #define MUSICPLAYER_H #include #include #include ”songsfile.h“ #include ”lyricsfile.h“ #define TIME_MS_DURATION 1000 #define INIT_SYSTEM_VOLUME 50 enum PlaybackMode //播放模式 { CURRENT_ITEM_ONCE = 0, //單曲播放 CURRENT_ITEM_IN_LOOP = 1, //單曲循環(huán) SEQUENTIAL = 2, //順序播放 LOOP = 3, //列表循環(huán) RANDOM = 4 //隨機(jī)播放 }; class MusicPlayer : public QObject { Q_OBJECT signals: void signalPositionChanged(QString updateTime);void signalDurationChanged(qint64 duration); public slots: void slotPositionChanged(qint64 position);void slotDurationChanged(qint64 duration); public: explicit MusicPlayer(QObject *parent = 0); const qint64 getTotalPlayerTime(void)const;void setTotalPlayerTime(const qint64 time); const qint64 getCurrentPlayerTime(void)const;void setCurrentPlayerTime(const qint64 time); /// 歌曲播放邏輯 QMediaPlayer ¤tMediaPlayer(void); /// 歌曲列表獲取邏輯 QMediaPlaylist &musicPlayList(void);QStringList &songsNameList(void); /// 歌曲歌詞獲取邏輯 void getCurrentSongLyric(void);QList private: /// 歌曲播放邏輯 qint64 m_totalPlayerTime;qint64 m_currentPlayerTime;QMediaPlayer m_player; /// 歌曲列表獲取邏輯 SongsFile *m_songsFile;QMediaPlaylist m_musicPlayList;QStringList m_songsNameList; /// 歌曲歌詞獲取邏輯 QList #endif // MUSICPLAYER_H (2).cpp文件 musicplayer.cpp的頭文件如下: #include ”musicplayer.h“ #include 同時(shí)在cpp文件內(nèi)寫入了信號(hào)與槽傳值連接的方法,代碼如下: MusicPlayer::MusicPlayer(QObject *parent): QObject(parent){ m_songsFile = new SongsFile(this); m_songsFile->initSongsListAndSongsNameList(m_musicPlayList, m_songsNameList); m_player.setPlaylist(&m_musicPlayList);m_player.setVolume(INIT_SYSTEM_VOLUME);connect(&m_player, SIGNAL(durationChanged(qint64)), this, SLOT(slotDurationChanged(qint64)));connect(&m_player, SIGNAL(positionChanged(qint64)), this, SLOT(slotPositionChanged(qint64)));} 得到siganl后相應(yīng)執(zhí)行的槽函數(shù)(position),具體代碼如下: void MusicPlayer::slotPositionChanged(qint64 position){ m_currentPlayerTime = position / TIME_MS_DURATION;//歌曲進(jìn)度條顯示 QTime currentTime((m_currentPlayerTime/3600)%60,(m_currentPlayerTime/60)%60, m_currentPlayerTime%60,(m_currentPlayerTime*1000)%1000);QTime totalTime((m_totalPlayerTime/3600)%60,(m_totalPlayerTime/60)%60, m_totalPlayerTime%60,(m_totalPlayerTime*1000)%1000); QString updateTime = currentTime.toString(”mm:ss“)+ ”/“+ totalTime.toString(”mm:ss"); emit signalPositionChanged(updateTime);} void MusicPlayer::slotDurationChanged(qint64 duration){ m_totalPlayerTime = duration / TIME_MS_DURATION;//TIME_MS_DURATION 1000 emit signalDurationChanged(m_totalPlayerTime);} 以及對(duì)播放時(shí)間、播放列表等的聲明,代碼如下: const qint64 MusicPlayer::getTotalPlayerTime(void)const { return m_totalPlayerTime / TIME_MS_DURATION;//INIT_SYSTEM_VOLUME 50 } void MusicPlayer::setTotalPlayerTime(const qint64 time){ m_totalPlayerTime = time;} const qint64 MusicPlayer::getCurrentPlayerTime(void)const { return m_currentPlayerTime;} void MusicPlayer::setCurrentPlayerTime(const qint64 time){ m_currentPlayerTime = time;} QMediaPlayer &MusicPlayer::currentMediaPlayer(void){ return m_player;} QMediaPlaylist &MusicPlayer::musicPlayList(void){ return m_musicPlayList;} QStringList &MusicPlayer::songsNameList(void){ return m_songsNameList;} void MusicPlayer::getCurrentSongLyric(void){ LyricsFile lyricsFile;m_lyricIndexList.clear();m_lyricContentList.clear();lyricsFile.getCurrentSongLyric(m_lyricIndexList, m_lyricContentList);} QList QStringList &MusicPlayer::lyricContentList(void)//歌詞內(nèi)容列表 { return m_lyricContentList;} 第四章 軟件測(cè)試 軟件實(shí)現(xiàn)截圖如下:(1)主界面 (2)第二界面(3)最小化 第五章 總結(jié) 本次所設(shè)計(jì)的基于Qt的音樂(lè)播放器軟件,在Windows系統(tǒng)環(huán)境下可以成功的運(yùn)行,對(duì)于預(yù)期的功能目標(biāo)已經(jīng)基本實(shí)現(xiàn),其中包括歌曲的選擇,歌曲打開,歌曲播放,歌曲暫停,顯示歌曲播放的進(jìn)度條等功能。該軟件的開發(fā)是在Qt Creator的開發(fā)環(huán)境下完成的程序編寫工作,該開發(fā)平臺(tái)簡(jiǎn)單方便,操作快捷,可以直接在Windows系統(tǒng)平臺(tái)下安裝運(yùn)行,完成代碼的編寫后,只需要直接點(diǎn)擊編譯和運(yùn)行即可使音樂(lè)播放器開始工作,按用戶的選擇進(jìn)行歌曲播放等功能,具有一定的實(shí)用性。 通過(guò)本次畢業(yè)設(shè)計(jì),我終于明白了“看一萬(wàn)行代碼,不如動(dòng)手寫一行代碼”這一句真理,對(duì)于工科類的學(xué)生來(lái)說(shuō),除了加強(qiáng)對(duì)對(duì)書本里的理論知識(shí)的學(xué)習(xí)之外,更重要的是培養(yǎng)自己實(shí)踐動(dòng)手的能力。這次畢業(yè)設(shè)計(jì),讓我以后面對(duì)困難時(shí)變得更有耐心,對(duì)我來(lái)說(shuō),這一精力都是在以后的生活和學(xué)習(xí)中的很寶貴的財(cái)富,極大的影響我以后的成長(zhǎng)和發(fā)展道路。 開發(fā)時(shí)間限制,我們小組實(shí)現(xiàn)了系統(tǒng)的基本功能,軟件可以實(shí)現(xiàn)基本功能,但是界面尚不夠美觀,系統(tǒng)也不夠完善,下一步,我們會(huì) 繼續(xù)改進(jìn)系統(tǒng)。本次設(shè)計(jì)以及系統(tǒng)的實(shí)現(xiàn)讓我們認(rèn)識(shí)到了以前很多沒(méi)有注意到的細(xì)節(jié)問(wèn)題,讓我學(xué)到了不少的新知識(shí)。 package ChatClient; import java.awt.*;import java.net.*;import java.awt.event.*;import java.io.*;import java.applet.*;class AudioClipWindow extends Frame implements Runnable,ItemListener,ActionListener { Thread thread; Choice choice; URL url; AudioClip clip; Button buttonPlay,buttonLoop,buttonStop; String str; AudioClipWindow(ActionListener chatClient) { thread=new Thread(this); choice=new Choice(); choice.add(“陳綺貞-我在那一角落患過(guò)傷風(fēng).wav”); choice.add(“no one wants forever.wma.wav”); choice.add(“中島美嘉-雪之華(韓雪-飄雪)日文版.wav”); choice.addItemListener(this); buttonPlay=new Button(“播放”); buttonLoop=new Button(“循環(huán)”); buttonStop=new Button(“停止”); buttonPlay.addActionListener(this); buttonStop.addActionListener(this); buttonLoop.addActionListener(this); setLayout(new FlowLayout()); add(choice); add(buttonPlay); add(buttonLoop); add(buttonStop); setSize(350,120); setVisible(true); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); validate(); } public void itemStateChanged(ItemEvent e) { str=choice.getSelectedItem(); if(!(thread.isAlive())) { thread=new Thread(this); } try{ thread.start(); } catch(Exception ee){} } public void run() { try{ File file=new File(str); url=file.toURL(); clip=Applet.newAudioClip(url); } catch(Exception e) { System.out.println(e); } } public void actionPerformed(ActionEvent e) { if(e.getSource()==buttonPlay) { clip.play(); } else if(e.getSource()==buttonLoop) { clip.loop(); } if(e.getSource()==buttonStop) { clip.stop(); } } } 一. 課程設(shè)計(jì)目的 1.通過(guò)D/A裝換器產(chǎn)生模擬信號(hào),使PC機(jī)作為簡(jiǎn)易音樂(lè)播放器。2.了解利用數(shù)模轉(zhuǎn)換器產(chǎn)生音樂(lè)的基本方法。 二.課程設(shè)計(jì)任務(wù) 設(shè)計(jì)并實(shí)現(xiàn)一個(gè)鍵控音樂(lè)播放器。要求: (1)自己選用合適的芯片,不少于兩種。 (2)自行設(shè)計(jì)電路并使用匯編語(yǔ)言編寫程序完成鍵控音樂(lè)播放器功能。 (3)該播放器有若干首歌曲可以選擇,開始時(shí)輸出說(shuō)明,要用戶選擇要播放的歌曲,然后根據(jù)用戶按鍵進(jìn)行播放、退出或出錯(cuò)提示。 三、總體設(shè)計(jì)方案 1、總體設(shè)計(jì)方案一 所有音樂(lè)都是由各個(gè)不同頻率的音階和其延續(xù)時(shí)間的長(zhǎng)短來(lái)實(shí)現(xiàn)的。不同的音樂(lè)是由各個(gè)音階按某種排列各自播放一定時(shí)間形成的,將各音樂(lè)音階和其延續(xù)時(shí)間存在數(shù)據(jù)段中,然后根據(jù)不同按鍵值選擇不同的音階和時(shí)間表,再使用計(jì)數(shù)器產(chǎn)生該音階頻率。而我們學(xué)過(guò)的有計(jì)數(shù)器可以產(chǎn)生各種頻率,所以我們主要采用計(jì)數(shù)器8253產(chǎn)生各音符,用8255并行接口來(lái)控制揚(yáng)聲器的開關(guān),達(dá)到播放音樂(lè)的功能。 2、總體設(shè)計(jì)方案二 可以使用0832(數(shù)模轉(zhuǎn)換器)來(lái)產(chǎn)生頻率,原理圖: 更連續(xù),效果更好點(diǎn)。 提出這個(gè)方案是因?yàn)槲蚁氘a(chǎn)生模擬信號(hào),來(lái)驅(qū)動(dòng)揚(yáng)聲器,這樣產(chǎn)生的聲音更加圓潤(rùn)感覺(jué)我們想把一個(gè)周期的波形分成32份,然后每份給8253一個(gè)值讓他轉(zhuǎn)換成模擬信號(hào),不同的頻率可以用8253計(jì)數(shù)器控制,比如要產(chǎn)生261Hz的頻率,使用1MHz的話,周期就為1/261=3.83ms,分成32份,每份間隔時(shí)間就是3.83ms/32=0.12ms,換句話說(shuō)就是送計(jì)數(shù)器0的初值為1M/261/32=120次。 3、各個(gè)音符的對(duì)應(yīng)頻率表: 音符 頻率/HZ 半周期/us 音符 頻率/HZ 半周期/us 低1DO 262 1908 #4FA# 740 0676 #1DO# 277 1805 中5SO 784 0638 低2RE 294 1700 #5SO# 831 0602 #2RE# 311 1608 中6LA 880 0568 低3M 330 1516 #6LA# 932 0536 低4FA 349 1433 中7SI 988 0506 #4FA# 370 1350 高1DO 1046 0478 低5SO 392 1276 #DO# 1109 0451 #5SO# 415 1205 高2RE 1175 0426 低6LA 440 1136 #2RE# 1245 0402 #6LA# 466 1072 高3M 1318 0372 低7SI 494 1012 高4FA 1397 0358 中1DO 523 0956 #4FA# 1480 0338 #1DO# 554 0903 高5SO 1568 0319 中2RE 578 0842 #5S0# 1661 0292 #2RE# 622 0804 高6LA 1760 0284 中3M 659 0759 #6LA# 1865 0268 中4FA 698 0716 高7SI 1976 0253 四.部分電路設(shè)計(jì)及功能解說(shuō) 1、頻率發(fā)生電路 使用8253產(chǎn)生音符頻率。8253采用方式3,產(chǎn)生方波信號(hào),根據(jù)輸入計(jì)數(shù)初值的不同產(chǎn)生不同頻率的方波信號(hào)來(lái)驅(qū)動(dòng)揚(yáng)聲器。 2、揚(yáng)聲器開關(guān)控制電路 使用8255并行接口芯片來(lái)控制揚(yáng)聲器的開和關(guān),PC0始終接低電平,PA0和8253的OUT0接在與門上,這樣只有PA0=1時(shí)揚(yáng)聲器才有可能開通,否則不發(fā)聲。關(guān)閉的方法是,從PC口讀入數(shù)據(jù)再?gòu)腜A口輸出;而開揚(yáng)聲器時(shí)只要在輸出PA口數(shù)據(jù)前對(duì)數(shù)據(jù)進(jìn)行一個(gè)取反操作就可以了。 設(shè)某音符頻率為fHz,而CLK脈沖是1MHz,則計(jì)數(shù)初值N=1M/f。8253的控制端口為28BH,控制字為36H。五.硬件接線圖 六.軟件設(shè)計(jì)流程圖 1、總流程圖 開始輸出說(shuō)明讀取按鍵是‘1’?N是‘2’?Y播放曲1Y播放曲2N是‘3’?Y播放曲3N是‘0’?Y結(jié)束Y選擇無(wú)效程序總流程圖 2、音樂(lè)播放子程序流程圖 開始保護(hù)現(xiàn)場(chǎng)曲N各音符頻率設(shè)置曲N各音符時(shí)間設(shè)置讀取頻率F頻率是-1 ?Y恢復(fù)現(xiàn)場(chǎng)N讀取時(shí)間T結(jié)束返回計(jì)算機(jī)計(jì)數(shù)次數(shù)送計(jì)數(shù)器,產(chǎn)生該頻率F信號(hào)啟動(dòng)喇叭延時(shí)T關(guān)閉喇叭音符間延時(shí)播音流程圖 七.程序段功能匯總 1、MAIN程序 MAIN程序是總程序,輸出說(shuō)明,等待用戶按鍵并讀取鍵值。根據(jù)不同的按鍵選擇調(diào)用播音子程序播放不同的歌曲。 2、PLAY子程序 PLAY子程序是播音子程序,SI指向音節(jié)表中的頻率,BP指向音節(jié)表中的時(shí)間。從SI的指向的音節(jié)表中取一個(gè)頻率,只要不是-1,即有效就再讀取時(shí)間,然后計(jì)算計(jì)數(shù)初值送入計(jì)數(shù)器,產(chǎn)生各種頻率。開啟揚(yáng)聲器,根據(jù)所取的時(shí)間調(diào)用若干次延時(shí)子程序。這段時(shí)間揚(yáng)聲器就發(fā)出該頻率的聲音,延時(shí)結(jié)束,就關(guān)閉揚(yáng)聲器,調(diào)用音節(jié)之間的小延時(shí)程序。最后修改SI和BP,指向下一個(gè)頻率,重復(fù)上面的工作。 3、DELAY子程序和DELAY_OFF子程序 兩個(gè)都是子程序,采用空操作循環(huán)多次的方法,只是第二個(gè)延時(shí)時(shí)間較短,大概為5ms。八.程序清單 SSEG SEGMENT PARA STACK 'stack' dw 100h dup(0);Resize the stack by changing the number '100' SSEG ENDS DSEG SEGMENT ;TO DO: Add your program's data here INFO1 DB 0DH,0AH,'--------------------------',0DH,0AH,'THERE ARE 3 SONGS:',0DH,0AH,0DH,0AH,'$' INFO2 DB '1.HAPPY BIRTHDAY',0DH,0AH,'$' INFO3 DB '2.SHEEP',0DH,0AH,'$' INFO4 DB '3.RIVER',0DH,0AH,'$' INFO5 DB '0.EXIT',0DH,0AH,'$' INFO6 DB 'YOU HAVE CHOSEN :$' INFO7 DB 'THANK YOU FOR YOUR USE',0DH,0AH,'$' INFO8 DB '---------------------------',0DH,0AH,'PRESS THE KEY TO SELECT SONG!',0DH,0AH,'$' INFO9 DB 0DH,0AH,'-------------------',0DH,0AH,'|INVALID SELECTION|',0DH,0AH,'-------------------',0DH,0AH,'$' FREG1 DW 2 dup(262),294,262,349,262,262,294,262,392,249,262,262,523,440,349 ;曲1的頻率 DW 330,294,466,266,440,349,392,349,-1 TIME1 DW 1,1,2,2,2,4,1,1,2,2,2,4,1,1,2,2,2,2,4,1,1,2,2,2,4 ;曲1的時(shí)間 FREG2 DW 330,294,262,294,3 DUP(330) ;曲2的頻率 DW 3 DUP(294),330,392,392 DW 330,294,262,294,4 DUP(330)DW 294,294,330,294,262,-1 TIME2 DW 6 DUP(1),2 ;曲2的時(shí)間 DW 2 DUP(1,1,2)DW 12 DUP(1),4 FREG3 DW 330,392,330,294,330,392,330,294,330,330,392,330,294,262,294,330,392,294 ;曲3的頻率 DW 262,262,220,196,220,262,294,332,262,-1 TIME3 DW 3 DUP(2),1,1,2,1,1,4 ;曲3的時(shí)間 DW 2 DUP(2,2,1,1),4 DW 3 DUP(2,1,1,1),4 DSEG ENDS CSEG SEGMENT assume cs:CSEG, ds:DSEG, es:DSEG, ss:SSEG INIT PROC;Initialize procedure mov ax, dseg mov ds, ax mov es, ax;TO DO: Add your initialize code here(as your requirement)ret ;return to the MAIN procedure INIT ENDP MAIN PROC ;Here is your program entry point call INIT;call the INIT procedure to initialize the program ;**TO DO: Add your main code here** RE: MOV DX,28BH ;關(guān)閉揚(yáng)聲器 MOV AL,89H OUT DX,AL MOV DX,28AH IN AL,DX MOV DX,288H OUT DX,AL LEA DX,INFO1 MOV AH,09H INT 21H LEA DX,INFO2 INT 21H LEA DX,INFO3 INT 21H LEA DX,INFO4 INT 21H LEA DX,INFO5 INT 21H LEA DX,INFO8 INT 21H MOV AH,01H INT 21H CMP AL,'1' JE MUSIC1 CMP AL,'2' JE MUSIC2 CMP AL,'3' JE MUSIC3 CMP AL,'0' JE EXIT LEA DX,INFO9 MOV AH,09H INT 21H JMP RE ;輸出說(shuō)明信息 ;讀取按鍵 ;根據(jù)不同的按鍵播放不同的曲子 ;無(wú)效選擇,輸出錯(cuò)誤提示 MUSIC1: MOV SI,OFFSET FREG1 ;指向曲1的表 MOV BP,OFFSET TIME1 CALL PLAY JMP RE MUSIC2: MOV SI,OFFSET FREG2 ;指向曲2的表 MOV BP,OFFSET TIME2 CALL PLAY JMP RE MUSIC3: MOV SI,OFFSET FREG3 ;指向曲3的表 MOV BP,OFFSET TIME3 CALL PLAY JMP RE EXIT: MOV DX,28BH ;關(guān)閉揚(yáng)聲器 MOV DX,28AH IN AL,DX MOV DX,288H OUT DX,AL LEA DX,INFO7 ;輸出歡迎使用信息,增加界面友好度 MOV AH,09H INT 21H mov ax, 4c00h;The end of the program, return to the system MOV AL,89H OUT DX,AL int 21h MAIN ENDP ;TO DO: Add other procedures(PROC)here(as your requirement) ;THE PROGRAMME OF PLAYING THE MUSIC PLAY PROC ;PLAY子程序,功能上面介紹過(guò) L1: MOV BX,DS:[SI] ;取頻率 CMP BX,-1 ;看是否有效 JE L0 ;無(wú)效就退出 MOV CX,DS:[BP] ;讀取時(shí)間 MOV DL,CL ;保存時(shí)間 ADD DL,30H MOV AH,02H INT 21H MOV DX,0FH ;計(jì)算計(jì)數(shù)初值,1M的十六進(jìn)制為0F4240H MOV AX,4240H DIV BX MOV BX,AX MOV DX,283H ;設(shè)置計(jì)數(shù)器工作方式 MOV AL,36H OUT DX,AL MOV DX,280H ;輸入計(jì)數(shù)初值 MOV AX,BX OUT DX,AL MOV AL,AH OUT DX,AL MOV DX,28BH MOV AL,89H OUT DX,AL MOV DX,28AH IN AL,DX NOT AL MOV DX,288H OUT DX,AL ROD:CALL DELAY LOOP ROD MOV DX,28BH MOV AL,89H OUT DX,AL MOV DX,28AH IN AL,DX MOV DX,288H OUT DX,AL CALL DELAY_OFF ADD SI,2 ADD BP,2 JMP L1 L0: RET PLAY ENDP DELAY PROC PUSH AX PUSH BX PUSH CX PUSH DX MOV BX,09FH LL1:MOV CX,0FFFFH ;開揚(yáng)聲器 ;延時(shí) ;關(guān)揚(yáng)聲器 ;延時(shí)子程序 ;循環(huán)這么多次 ;音節(jié)間延時(shí) LOP: LOOP LOP DEC BX JNZ LL1 POP DX POP CX POP BX POP AX RET DELAY ENDP DELAY_OFF PROC PUSH AX PUSH BX PUSH CX PUSH DX MOV BX,0FH LL2:MOV CX,0CFFFH LOP2: LOOP LOP2 DEC BX JNZ LL2 POP DX POP CX POP BX POP AX RET DELAY_OFF ENDP CSEG ENDS;TO DO: Add other segments here(as your requirement) END MAIN 九.試驗(yàn)結(jié)果和分析 1、試驗(yàn)結(jié)果: 程序初始運(yùn)行界面 如果按錯(cuò)了鍵,會(huì)出現(xiàn)如下界面 如果選擇正確,將出現(xiàn)如下界面: 2、分析 這是按照方案一做的結(jié)果,按1~3分別播放“生日快樂(lè)”等歌,但由于本組人對(duì)音樂(lè)都是外行,各音階頻率的排序和延時(shí)時(shí)間搭配不好,導(dǎo)致音樂(lè)嚴(yán)重走調(diào),但基本能聽出不是噪音。 按照方案二做的電路和程序,無(wú)論怎么樣都不出聲,后來(lái)我們直接送數(shù)據(jù)到0832產(chǎn)生三角波信號(hào)(程序在我們的一次作業(yè)中寫的)。還是無(wú)法讓揚(yáng)聲器發(fā)出聲音,因此按這個(gè)方案失敗了。 十.課程設(shè)計(jì)總結(jié)和體會(huì) 1.實(shí)驗(yàn)過(guò)程中碰到了很多的難題和障礙,我認(rèn)識(shí)到平時(shí)基礎(chǔ)知識(shí)的重要性,只有能夠熟練的掌握才能在實(shí)驗(yàn)過(guò)程中得心應(yīng)手,否則一步錯(cuò)則整個(gè)試驗(yàn)都會(huì)陷入困境,因而,嚴(yán)謹(jǐn)?shù)膽B(tài)度是試驗(yàn)成功的重要保障! 2.通過(guò)這次課程設(shè)計(jì),我們對(duì)各個(gè)芯片有了進(jìn)一步的了解,對(duì)各個(gè)芯片的功能有了更深刻的認(rèn)識(shí)和體會(huì),平時(shí)上課的理論知識(shí)只是停留在理論的層面,只有通過(guò)了這樣的試驗(yàn)才能更好的體會(huì)到,做到了理論和實(shí)際的相結(jié)合,使理論知識(shí)真正運(yùn)用到了實(shí)踐中去。在課程設(shè)計(jì)過(guò)程中,同組人員之間相互合作,共同研究使我更加堅(jiān)信了團(tuán)體的力量。在團(tuán)體的共同協(xié)作和努力下,任何的難題都可以被解決! 3.我們大家在實(shí)驗(yàn)的時(shí)候都團(tuán)結(jié)合作,遇到問(wèn)題時(shí)候一起探討,增強(qiáng)了我們的合作精神。 十一.參考文獻(xiàn) 1、《〈微機(jī)原理與接口技術(shù)〉學(xué)生實(shí)驗(yàn)指導(dǎo)書》 揚(yáng)州大學(xué) 羅加奇 2、《微機(jī)原理及應(yīng)用》 機(jī)械工業(yè)出版社 胡鋼 主編第二篇:基于java的音樂(lè)播放器課程設(shè)計(jì)報(bào)告
第三篇:基于Qt的音樂(lè)播放器課程設(shè)計(jì)報(bào)告
第四篇:java音樂(lè)播放器源代碼(ChatClient)
第五篇:微機(jī)原理課程設(shè)計(jì)——音樂(lè)播放器