现在的手机功能越来越丰富了,遥想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出来

  1. MediaPlayer mp = new MediaPlayer();

b 使用create方式

  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

  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. <LinearLayout
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:orientation="horizontal" >
  10. <Button
  11. android:id="@+id/play"
  12. android:layout_width="0dp"
  13. android:layout_height="wrap_content"
  14. android:layout_weight="1"
  15. android:text="播放" />
  16. <Button
  17. android:id="@+id/pause"
  18. android:layout_width="0dp"
  19. android:layout_height="wrap_content"
  20. android:layout_weight="1"
  21. android:text="暂停" />
  22. <Button
  23. android:id="@+id/stop"
  24. android:layout_width="0dp"
  25. android:layout_height="wrap_content"
  26. android:layout_weight="1"
  27. android:text="停止" />
  28. </LinearLayout>
  29. <SeekBar
  30. android:id="@+id/seekbar"
  31. android:layout_width="match_parent"
  32. android:layout_height="wrap_content"
  33. android:max="0"
  34. android:progress="0"
  35. android:secondaryProgress="0" />
  36. <RelativeLayout
  37. android:layout_width="match_parent"
  38. android:layout_height="wrap_content" >
  39. <TextView
  40. android:id="@+id/tv"
  41. android:layout_width="wrap_content"
  42. android:layout_height="wrap_content"
  43. android:layout_alignParentLeft="true"
  44. android:text="当前时间" />
  45. <TextView
  46. android:id="@+id/tv2"
  47. android:layout_width="wrap_content"
  48. android:layout_height="wrap_content"
  49. android:layout_alignParentRight="true"
  50. android:text="总时间" />
  51. </RelativeLayout>
  52. </LinearLayout>

MainActivity.java

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

二、播放视频文件
     播放视频文件相比播放音频文件并不比它复杂,这里使用VideoView类来实现。这个类将视频的显示和控制集于一身。

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

方法名

功能描述

setVideoPath()

设置要播放的视频文件的位置。

start()

开始或继续播放视频。

pause()

暂停播放视频。

resume()

将视频重头开始播放。

seekTo()

从指定的位置开始播放视频。

isPlaying()

判断当前是否正在播放视频。

getDuration()

获取载入的视频文件的时长。

 

因为VideoView是包装过的MediaPlayer,所以使用起来很相似。

比如:

  1. private void initVideoPlayer() {
  2. File file = new File(Environment.getExternalStorageDirectory()
  3. + "/Download/", "Sample.3gp");
  4. videoPlayer.setVideoPath(file.getPath());// 指定视频文件的路径
  5. }

事件处理

  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. default:
  20. break;
  21. }
  22. }

三、常见的MediaPlayer错误

也就是它的错误状态。比如这样的错误 start called in state 0,0表示他的错误状态,下面是MediaPlayer的状态,源码中找到的:

  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的生命周期(上图)进行错误分析。

Android 多媒体MediaPlayer使用详解的更多相关文章

  1. Android JNI作用及其详解

    Android JNI作用及其详解 Java Native Interface (JNI)标准是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 J ...

  2. Android开发之MdiaPlayer详解

    Android开发之MdiaPlayer详解 MediaPlayer类可用于控制音频/视频文件或流的播放,我曾在<Android开发之基于Service的音乐播放器>一文中介绍过它的使用. ...

  3. 《Android NFC 开发实战详解 》简介+源码+样章+勘误ING

    <Android NFC 开发实战详解>简介+源码+样章+勘误ING SkySeraph Mar. 14th  2014 Email:skyseraph00@163.com 更多精彩请直接 ...

  4. Android开发之InstanceState详解

    Android开发之InstanceState详解   本文介绍Android中关于Activity的两个神秘方法:onSaveInstanceState() 和 onRestoreInstanceS ...

  5. ANDROID L——Material Design详解(UI控件)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...

  6. android bundle存放数据详解

    转载自:android bundle存放数据详解 正如大家所知道,Activity之间传递数据,是将数据存放在Intent或者Bundle中 例如: 将数据存放倒Intent中传递: 将数据放到Bun ...

  7. Cordova 打包 Android release app 过程详解

    Cordova 打包 Android release app 过程详解 时间 -- :: SegmentFault 原文 https://segmentfault.com/a/119000000517 ...

  8. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

  9. 给 Android 开发者的 RxJava 详解

    我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 .而最近这几个 ...

随机推荐

  1. lua知识点整理

    1. lua全局环境和局部环境 local cf = loadstring(" local i=0 i=i+1 print(i) ") --从后面两个输出我们可以看出,生成的函数的 ...

  2. js方法区分IE浏览器和非IE浏览器

    可以从IE特有的方法和非IE特有的方法来区分不同的浏览器 1.为元素添加事件监听: 非IE:.addEventListener("click",show,false)//第三个参数 ...

  3. 17,UC(06)

    /*  达内学习 UC day06 2013-10-10 */ 回忆过去:  系统调用 - UNIX操作系统提供的一些列函数皆苦,用于访问内核空间,遵循posix规范  文件操作:open()\rea ...

  4. css - 三种方法解决LI和内部Img的上下间距问题

    在火狐浏览器和谷歌浏览器(qq浏览器,谷歌内核)bug类似这张图: img的高度是190*127 但是放到li中,li并没有设置高度,却和内部的图片之间上下错位. 若强行给li设置高度127,他和im ...

  5. Excel 2010 最熟悉的陌生功能:筛选器(将当前所选内容添加到筛选器)

    使用excel2010版的同学,在进行筛选时,肯定都对这句话很熟悉:将当前所选内容添加到筛选器.但很多同学天天看到,却不知道什么是筛选器?它有什么作用. 其实,这里所指的筛选器就是储存筛选结果的一个虚 ...

  6. weblogic jprofile配置

    前提: 1.安装好weblogic 2.安装好jprofile 非等待模式: export JAVA_OPTIONS="${JAVA_OPTIONS} -Dweblogic.threadpo ...

  7. Cisco IOS和IOS XE 新漏洞检测与修复

    Cisco IOS/IOS XE 新漏洞检测与修复 CVE-2018-0150 Cisco IOS XE 存在默认弱口令 漏洞影响: 默认弱口令可以导致攻击者直远程登录控制Cisco设备.受影响版本, ...

  8. 【黑金ZYNQ7000系列原创视频教程】02.视频接口——hdmi编码输出实验

    黑金论坛地址: http://www.heijin.org/forum.php?mod=viewthread&tid=36636&extra=page%3D1 爱奇艺地址: http: ...

  9. 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树

    [BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...

  10. oracle和mysql如何快速查看每个表的数据量?

    oracle: select t.table_name,t.num_rows from user_tables t ORDER BY NUM_ROWS DESC; mysql: use informa ...