Android 多媒體MediaPlayer使用詳解


現在的手機功能越來越豐富了,遙想10年前,MP3,MP4,MP5,還是很流行的,博主當時讀高中時很想擁有一台,可以聽音樂和看電影。可是條件有限,學校也禁止此東西,所以只能偷偷的玩。而現在我們的手機也很早以前就支持了這些功能,而且界面和功能也遠遠超過了MP4。好吧,說多了,今天本文介紹的是Andriod系統自帶的Mediaplayer,和VideoView實現簡單的音樂和視頻的播放,至於想做出如酷狗音樂這樣的APP的話,只要想做,應該也不難,都是基於此實現了功能的擴展。

 Android的MediaPlayer包含了Audio和Video的播放功能,在Android的界面上,Music和Video兩個應用程序都是調用MediaPlaer來實現的。

  一、播放音頻文件

         首先看看MediaPlaer的生命周期

下面是MediaPlayer提供的常用方法

 

方法 說明
MediaPlayer 構造方法
create 創建一個要播放的多媒體
getCurrentPosition 得到當前播放位置
getDuration 得到文件的時間
getVideoHeight 得到視頻的高度
getVideoWidth 得到視頻的寬度
isLooping 是否循環播放
isPlaying 是否正在播放
pause 暫停
prepare 准備(同步)
prepareAsync 准備(異步)
release 釋放MediaPlayer對象相關的資源
reset 重置MediaPlayer對象為剛剛創建的狀態
seekTo 指定播放的位置(以毫秒為單位的時間)
setAudioStreamType 設置流媒體的類型
setDataSource 設置多媒體數據來源(位置)
setDisplay 設置用SurfaceHolder來顯示多媒體
setLooping 設置是否循環播放
setOnButteringUpdateListener 網絡流媒體的緩沖監聽
setOnErrorListener 設置錯誤信息監聽
setOnVideoSizeChangedListener 視頻尺寸監聽
setScreenOnWhilePlaying 設置是否使用SurfaceHolder來保持屏幕顯示
setVolume 設置音量
start 開始播放
stop 停止播放


MediaPlayer的工作流程是這樣的:

 

1,首先創建MediaPlaer對象; *

2,然后調用setDataSource()方法來設置音頻文件的路徑;**

3,再調用prepare()方法使MediaPlayer進入到准備狀態;

4,調用start方法就可以播放音頻。

    *  創建MediaPlaer對象有兩種方式  

     a 直接new出來

 

[java]  view plain  copy
 
 print?
  1. MediaPlayer mp = new MediaPlayer();  

    b 使用create方式

 

 

[java]  view plain  copy
 
 print?
  1. MediaPlayer mp = MediaPlayer.create(this, R.raw.test);//這時就不用調用setDataSource了  

當然上面首先得在res文件夾下新建raw文件夾,並放置一個test文件

 

    ** 設置播放的文件

      MediaPlayer要播放的文件主要包括3個來源:
a. 用戶在應用中事先自帶的resource資源
例如:MediaPlayer.create(this, R.raw.test);
b. 存儲在SD卡或其他文件路徑下的媒體文件
例如:mp.setDataSource("/sdcard/test.mp3");
c. 網絡上的媒體文件
例如:mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
MediaPlayer的setDataSource一共四個方法:
setDataSource (String path) 
setDataSource (FileDescriptor fd) 
setDataSource (Context context, Uri uri) 
setDataSource (FileDescriptor fd, long offset, long length)
 
其中使用FileDescriptor時,需要將文件放到與res文件夾平級的assets文件夾里,然后使用:
AssetFileDescriptor fileDescriptor = getAssets().openFd("rain.mp3");
m_mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());
來設置datasource
先簡單看下效果圖吧


   上面的功能一看就知道了,就不用我說了吧

下面是實現代碼

activity_main.xml

 

[html]  view plain  copy
 
 print?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent"  
  4.     android:layout_margin="3dp"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <LinearLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:orientation="horizontal" >  
  11.   
  12.         <Button  
  13.             android:id="@+id/play"  
  14.             android:layout_width="0dp"  
  15.             android:layout_height="wrap_content"  
  16.             android:layout_weight="1"  
  17.             android:text="播放" />  
  18.   
  19.         <Button  
  20.             android:id="@+id/pause"  
  21.             android:layout_width="0dp"  
  22.             android:layout_height="wrap_content"  
  23.             android:layout_weight="1"  
  24.             android:text="暫停" />  
  25.   
  26.         <Button  
  27.             android:id="@+id/stop"  
  28.             android:layout_width="0dp"  
  29.             android:layout_height="wrap_content"  
  30.             android:layout_weight="1"  
  31.             android:text="停止" />  
  32.     </LinearLayout>  
  33.   
  34.     <SeekBar  
  35.         android:id="@+id/seekbar"  
  36.         android:layout_width="match_parent"  
  37.         android:layout_height="wrap_content"  
  38.         android:max="0"  
  39.         android:progress="0"  
  40.         android:secondaryProgress="0" />  
  41.   
  42.     <RelativeLayout  
  43.         android:layout_width="match_parent"  
  44.         android:layout_height="wrap_content" >  
  45.   
  46.         <TextView  
  47.             android:id="@+id/tv"  
  48.             android:layout_width="wrap_content"  
  49.             android:layout_height="wrap_content"  
  50.             android:layout_alignParentLeft="true"  
  51.             android:text="當前時間" />  
  52.   
  53.         <TextView  
  54.             android:id="@+id/tv2"  
  55.             android:layout_width="wrap_content"  
  56.             android:layout_height="wrap_content"  
  57.             android:layout_alignParentRight="true"  
  58.             android:text="總時間" />  
  59.     </RelativeLayout>  
  60.   
  61. </LinearLayout>  

MainActivity.java

 

 

[java]  view plain  copy
 
 print?
  1. package com.example.musicplayer;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5.   
  6. import android.R.integer;  
  7. import android.app.Activity;  
  8. import android.media.MediaPlayer;  
  9. import android.os.Bundle;  
  10. import android.os.Environment;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.util.Log;  
  14. import android.view.Menu;  
  15. import android.view.MenuItem;  
  16. import android.view.View;  
  17. import android.view.View.OnClickListener;  
  18. import android.widget.Button;  
  19. import android.widget.SeekBar;  
  20. import android.widget.SeekBar.OnSeekBarChangeListener;  
  21. import android.widget.TextView;  
  22.   
  23. public class MainActivity extends Activity implements OnClickListener,  
  24.         OnSeekBarChangeListener {  
  25.     private Button play, pause, stop;  
  26.     private MediaPlayer player;  
  27.     private SeekBar mSeekBar;  
  28.     private TextView tv, tv2;  
  29.     private boolean hadDestroy = false;  
  30.     private Handler mHandler = new Handler() {  
  31.         public void handleMessage(android.os.Message msg) {  
  32.   
  33.             switch (msg.what) {  
  34.             case 0x01:  
  35.   
  36.                 break;  
  37.   
  38.             default:  
  39.                 break;  
  40.             }  
  41.         };  
  42.     };  
  43.     Runnable runnable = new Runnable() {  
  44.   
  45.         @Override  
  46.         public void run() {  
  47.   
  48.             if (!hadDestroy) {  
  49.                 mHandler.postDelayed(this, 1000);  
  50.                 int currentTime = Math  
  51.                         .round(player.getCurrentPosition() / 1000);  
  52.                 String currentStr = String.format("%s%02d:%02d", "當前時間 ",  
  53.                         currentTime / 60, currentTime % 60);  
  54.                 tv.setText(currentStr);  
  55.                 mSeekBar.setProgress(player.getCurrentPosition());  
  56.             }  
  57.         }  
  58.     };  
  59.   
  60.     @Override  
  61.     protected void onCreate(Bundle savedInstanceState) {  
  62.         super.onCreate(savedInstanceState);  
  63.         setContentView(R.layout.activity_main);  
  64.         play = (Button) findViewById(R.id.play);  
  65.         pause = (Button) findViewById(R.id.pause);  
  66.         stop = (Button) findViewById(R.id.stop);  
  67.         mSeekBar = (SeekBar) findViewById(R.id.seekbar);  
  68.         tv = (TextView) findViewById(R.id.tv);  
  69.         tv2 = (TextView) findViewById(R.id.tv2);  
  70.         mSeekBar.setOnSeekBarChangeListener(this);  
  71.         play.setOnClickListener(this);  
  72.         pause.setOnClickListener(this);  
  73.         stop.setOnClickListener(this);  
  74.         player = new MediaPlayer();  
  75.         initMediaplayer();  
  76.   
  77.     }  
  78.   
  79.     /** 
  80.      * 初始化播放器 
  81.      */  
  82.     private void initMediaplayer() {  
  83.         try {  
  84.             File file = new File(Environment.getExternalStorageDirectory()  
  85.                     + "/Download/", "aiqiu.mp3");  
  86.             player.setDataSource(file.getPath());  
  87.             Log.e("播放器", file.toString());  
  88.             player.prepare();  
  89.         } catch (Exception e) {  
  90.             e.printStackTrace();  
  91.         }  
  92.     }  
  93.   
  94.     @Override  
  95.     public void onClick(View v) {  
  96.         switch (v.getId()) {  
  97.         case R.id.play:  
  98.             if (!player.isPlaying()) {  
  99.                 player.start();  
  100.                 int totalTime = Math.round(player.getDuration() / 1000);  
  101.                 String str = String.format("%02d:%02d", totalTime / 60,  
  102.                         totalTime % 60);  
  103.                 tv2.setText(str);  
  104.                 mSeekBar.setMax(player.getDuration());  
  105.                 mHandler.postDelayed(runnable, 1000);  
  106.             }  
  107.   
  108.             break;  
  109.         case R.id.pause:  
  110.             if (player.isPlaying()) {  
  111.                 player.pause();  
  112.             }  
  113.             break;  
  114.         case R.id.stop:  
  115.             if (player.isPlaying()) {  
  116.                 player.reset();  
  117.                 initMediaplayer();  
  118.             }  
  119.             break;  
  120.   
  121.         default:  
  122.             break;  
  123.         }  
  124.     }  
  125.   
  126.     @Override  
  127.     public void onProgressChanged(SeekBar seekBar, int progress,  
  128.             boolean fromUser) {  
  129.         if (player != null) {  
  130.             player.seekTo(seekBar.getProgress());  
  131.         }  
  132.   
  133.     }  
  134.   
  135.     @Override  
  136.     public void onStartTrackingTouch(SeekBar seekBar) {  
  137.         // TODO 自動生成的方法存根  
  138.   
  139.     }  
  140.   
  141.     @Override  
  142.     public void onStopTrackingTouch(SeekBar seekBar) {  
  143.         // TODO 自動生成的方法存根  
  144.     }  
  145.   
  146.     @Override  
  147.     protected void onDestroy() {  
  148.         // TODO 自動生成的方法存根  
  149.         super.onDestroy();  
  150.         if (player != null) {  
  151.             player.stop();  
  152.             hadDestroy = true;  
  153.             player.release();  
  154.         }  
  155.     }  
  156.   
  157. }  

二、播放視頻文件
     播放視頻文件相比播放音頻文件並不比它復雜,這里使用VideoView類來實現。這個類將視頻的顯示和控制集於一身。

 

     VideoView和MediaPlaer也比較類似,主要有以下常用方法

   

方法名

功能描述

setVideoPath()

設置要播放的視頻文件的位置。

start()

開始或繼續播放視頻。

pause()

暫停播放視頻。

resume()

將視頻重頭開始播放。

seekTo()

從指定的位置開始播放視頻。

isPlaying()

判斷當前是否正在播放視頻。

getDuration()

獲取載入的視頻文件的時長。

 

因為VideoView是包裝過的MediaPlayer,所以使用起來很相似。

 

比如:

 

[java]  view plain  copy
 
 print?
  1. private void initVideoPlayer() {  
  2.         File file = new File(Environment.getExternalStorageDirectory()  
  3.                 + "/Download/", "Sample.3gp");  
  4.         videoPlayer.setVideoPath(file.getPath());// 指定視頻文件的路徑  
  5.   
  6.     }  

事件處理

 

 

[java]  view plain  copy
 
 print?
  1. @Override  
  2.     public void onClick(View v) {  
  3.         switch (v.getId()) {  
  4.         case R.id.play:  
  5.             if (!videoPlayer.isPlaying()) {  
  6.                 videoPlayer.start();  
  7.             }  
  8.             break;  
  9.         case R.id.pause:  
  10.             if (videoPlayer.isPlaying()) {  
  11.                 videoPlayer.pause();  
  12.             }  
  13.             break;  
  14.         case R.id.stop:  
  15.             if (videoPlayer.isPlaying()) {  
  16.                 videoPlayer.resume();  
  17.             }  
  18.             break;  
  19.   
  20.         default:  
  21.             break;  
  22.         }  
  23.     }  

 

三、常見的MediaPlayer錯誤

        也就是它的錯誤狀態。比如這樣的錯誤 start called in state 0,0表示他的錯誤狀態,下面是MediaPlayer的狀態,源碼中找到的:

 

[java]  view plain  copy
 
 print?
  1. enum media_player_states {  
  2.        MEDIA_PLAYER_STATE_ERROR        = 0,           // 0狀態  
  3.        MEDIA_PLAYER_IDLE                = 1 << 0,     // 1狀態  
  4.        MEDIA_PLAYER_INITIALIZED        = 1 << 1,      // 2 狀態  
  5.        MEDIA_PLAYER_PREPARING            = 1 << 2,    // 4 狀態  
  6.        MEDIA_PLAYER_PREPARED            = 1 << 3,     // 8狀態  
  7.        MEDIA_PLAYER_STARTED            = 1 << 4,      // 16狀態  
  8.        MEDIA_PLAYER_PAUSED                = 1 << 5,   // 32狀態  
  9.        MEDIA_PLAYER_STOPPED            = 1 << 6,      // 64 狀態  
  10.        MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7,      // 128 狀態  
  11.    }  

    可以參照報錯的狀態和MediaPlayer的生命周期(上圖)進行錯誤分析。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM