上篇文章講服務的例子中,有個演示服務的後台播放音樂,今天就來講一講多媒體之一的音樂播放。
說到多媒體不得不向上追溯,空間多媒體是如何實現的,如何可以讓我們輕松的播放音樂、視頻?本章講述點大致如下:
- 1、什麼是Open Core?
- 2、Open Core 的具體功能。
- 3、Mediaplayer 介紹
- 4、完整音樂播放例子演示
- 5、Android 模擬器使用SD卡
1、什麼是Open Core?
Open Core 是 Android 多媒體框架的核心,所有 Android 平台的音頻、視頻的采用以及播放等操作,都是通過它來實現。
2、Open Core 的具體功能
- 1、多媒體文件的播放、下載,包括:3GPP,MPEG-4,AAC 和 MP3 containers。
- 2、流媒體文件的下載、實時播放,包括:3GPP,HTTP 和 RTSP/RTP。
- 3、動態視頻和靜態圖像的編碼、解碼,例如:MPEG-4,H.263 和 AVC (H.264),JPEG。
- 4、語音編碼格式:MP3,AAC,AAC 。
- 5、視頻和圖像格式:3GPP,MPEG-4 和 JPEG。
- 6、視頻會議:基於 H324-M 標准。
Open Core 是一個多媒體的框架,從宏觀上來看,它主要包含了兩大方面的內容:
- 1、PVPPlayer:提供媒體播放器的功能,完成各種音頻(Audio)、視頻(Video)流的回放(Playback)功能。
- 2、PVAuthor:提供媒體流記錄的功能,完成各種音頻、視頻流以及靜態圖像的捕獲功能。
3、Mediaplayer 介紹
MediaPlayer 類可以用來播放音頻、視頻和流媒體,MediaPlayer 包含了 Audio 和 Video 的播放功能,在 Android 的界面上, Music 和 Video 兩個應用程序都是調用 MediaPlayer 實現的。下面兩張圖是 MediaPlayer 在 Android 和 Open Core 的示例圖:
下面是圖例顯示 MediaPlayer 的生命周期
3.1、MediaPlayer 常用方法介紹
- 方法:create(Context context, Uri uri)
解釋:靜態方法,通過Uri創建一個多媒體播放器。
- 方法:create(Context context, int resid)
解釋:靜態方法,通過資源ID創建一個多媒體播放器
- 方法:create(Context context, Uri uri, SurfaceHolder holder)
解釋:靜態方法,通過Uri和指定 SurfaceHolder 【抽象類】 創建一個多媒體播放器
- 方法: getCurrentPosition()
解釋:返回 Int, 得到當前播放位置
- 方法: getDuration()
解釋:返回 Int,得到文件的時間
- 方法:getVideoHeight()
解釋:返回 Int ,得到視頻的高度
- 方法:getVideoWidth()
解釋:返回 Int,得到視頻的寬度
- 方法:isLooping()
解釋:返回 boolean ,是否循環播放
- 方法:isPlaying()
解釋:返回 boolean,是否正在播放
- 方法:pause()
解釋:無返回值 ,暫停
- 方法:prepare()
解釋:無返回值,准備同步
- 方法:prepareAsync()
解釋:無返回值,准備異步
- 方法:release()
解釋:無返回值,釋放 MediaPlayer 對象
- 方法:reset()
解釋:無返回值,重置 MediaPlayer 對象
- 方法:seekTo(int msec)
解釋:無返回值,指定播放的位置(以毫秒為單位的時間)
- 方法:setAudioStreamType(int streamtype)
解釋:無返回值,指定流媒體的類型
- 方法:setDataSource(String path)
解釋:無返回值,設置多媒體數據來源【根據 路徑】
- 方法:setDataSource(FileDescriptor fd, long offset, long length)
解釋:無返回值,設置多媒體數據來源【根據 FileDescriptor】
- 方法:setDataSource(FileDescriptor fd)
解釋:無返回值,設置多媒體數據來源【根據 FileDescriptor】
- 方法:setDataSource(Context context, Uri uri)
解釋:無返回值,設置多媒體數據來源【根據 Uri】
- 方法:setDisplay(SurfaceHolder sh)
解釋:無返回值,設置用 SurfaceHolder 來顯示多媒體
- 方法:setLooping(boolean looping)
解釋:無返回值,設置是否循環播放
- 事件:setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)
解釋:監聽事件,網絡流媒體的緩沖監聽
- 事件:setOnCompletionListener(MediaPlayer.OnCompletionListener listener)
解釋:監聽事件,網絡流媒體播放結束監聽
- 事件:setOnErrorListener(MediaPlayer.OnErrorListener listener)
解釋:監聽事件,設置錯誤信息監聽
- 事件:setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)
解釋:監聽事件,視頻尺寸監聽
- 方法:setScreenOnWhilePlaying(boolean screenOn)
解釋:無返回值,設置是否使用 SurfaceHolder 顯示
- 方法:setVolume(float leftVolume, float rightVolume)
解釋:無返回值,設置音量
- 方法:start()
解釋:無返回值,開始播放
- 方法:stop()
解釋:無返回值,停止播放
4、完整音樂播放例子演示
通過上面的講解大致知道了 MediaPlayer 的播放原理,下面我們來完成一個小項目,即實現一個 Mini 版音樂播放器。這個播放器中我們需要有暫停、停止、上一首、下一首等基本按鈕,有了上面的講解要實現這個小項目就輕松多了,下面將貼出代碼
import java.io.File;
import java.io.FilenameFilter;
public class MusicFilter implements FilenameFilter{
@Override
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
return (filename.endsWith(".mp3"));
}
}
Tip:播放器不可能只是希望播放一種音樂格式,並且還需要自動識別指定的路徑中哪些是可以播放的音頻文件,哪些是不支持的格式,以上代碼可以作為參考。好了,下面貼出完整代碼
音樂播放器示例代碼
package com.terry;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class musicActivity extends ListActivity {
//播放對象
private MediaPlayer myMediaPlayer;
//播放列表
private List<String> myMusicList=new ArrayList<String>();
//當前播放歌曲的索引
private int currentListItem=0;
//音樂的路徑
private static final String MUSIC_PATH=new String("/sdcard/");
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myMediaPlayer=new MediaPlayer();
findView();
musicList();
listener();
}
//綁定音樂
void musicList(){
File home=new File(MUSIC_PATH);
if(home.listFiles(new MusicFilter()).length>0){
for(File file:home.listFiles(new MusicFilter())){
myMusicList.add(file.getName());
}
ArrayAdapter<String> musicList=new ArrayAdapter<String>
(musicActivity.this,R.layout.musicitme, myMusicList);
setListAdapter(musicList);
}
}
//獲取按鈕
void findView(){
viewHolder.start=(Button)findViewById(R.id.start);
viewHolder.stop=(Button)findViewById(R.id.stop);
viewHolder.next=(Button)findViewById(R.id.next);
viewHolder.pause=(Button)findViewById(R.id.pause);
viewHolder.last=(Button)findViewById(R.id.last);
}
//監聽事件
void listener(){
//停止
viewHolder.stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(myMediaPlayer.isPlaying()){
myMediaPlayer.reset();
}
}
});
//開始
viewHolder.start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
playMusic(MUSIC_PATH myMusicList.get(currentListItem));
}
});
//下一首
viewHolder.next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
nextMusic();
}
});
//暫停
viewHolder.pause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(myMediaPlayer.isPlaying()){
myMediaPlayer.pause();
}else{
myMediaPlayer.start();
}
}
});
//上一首
viewHolder.last.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
lastMusic();
}
});
}
//播放音樂
void playMusic(String path){
try {
myMediaPlayer.reset();
myMediaPlayer.setDataSource(path);
myMediaPlayer.prepare();
myMediaPlayer.start();
myMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
nextMusic();
}
});
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//下一首
void nextMusic(){
if( currentListItem>=myMusicList.size()){
currentListItem=0;
}
else{
playMusic(MUSIC_PATH myMusicList.get(currentListItem));
}
}
//上一首
void lastMusic(){
if(currentListItem!=0)
{
if(--currentListItem>=0){
currentListItem=myMusicList.size();
} else{
playMusic(MUSIC_PATH myMusicList.get(currentListItem));
}
} else{
playMusic(MUSIC_PATH myMusicList.get(currentListItem));
}
}
//當用戶返回時結束音樂並釋放音樂對象
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK){
myMediaPlayer.stop();
myMediaPlayer.release();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
//當選擇列表項時播放音樂
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
currentListItem=position;
playMusic(MUSIC_PATH myMusicList.get(currentListItem));
}
}
運行效果圖:
5、Android 模擬器使用SD卡
例子中直接指定SD卡裡面的音樂文件進行操作,那麼我們的Android模擬器如何使用SD卡呢?
- 1、你可以來 CSDN 這裡看一下他的文章http://blog.csdn.net/ligaoyang/archive/2009/08/25/4484046.aspx
- 2、不用操作 DOS 直接使用 Android SDK and AVD Manager 在創建 AVD 時創建一個SD 卡,這樣就可以實現,不妨親手試試。
創建好SD 卡那如何把文件導入SD 卡裡面供模擬器使用呢?
- 1、啟動程序,運行模擬器。
- 2、在 Eclipse 上先把 DDMS 窗口,選擇 File Explorer 標簽。
- 3、如果你當時創建AVD 時有順帶創建 SD 卡或者你通過DOS命令創建的SD 卡,那麼File Explorer 裡面就會顯示一個 "sdcard" 的文件夾,這時選中它,右上角的兩個箭頭就變成可用,右邊箭頭是導入,左邊箭頭是導出。
不多寫了,源碼下載 :musicPlayer.rar