Android 4.0.3(Api Level 15)支持的多媒体格式。
注意:有些设备可能支持其他的文件格式。
1.Audio
AAC LC/LTP、HE-AACv1(AAC+)、AMR-NB、AMR-WB、MP3、MIDI、Ogg Vorbis、PCM/WAVE、FLAC(3.1或3.1以上)
2.Image
JPEG、PNG、WEBP、GIF、BMP
3.Video
H.263、H.264 AVC、MPEG-4 SP、VP8(2.3.3或2.3.3以上)
播放音频、视频主要由MediaPlayer类来控制。
大致步骤:
1.初始化MediaPlayer,附上要播放的媒体。
2.准备播放 prepare
3.开始播放 start
4.在播放结束前:停止或者暂停播放 pause or stop
5.播放完成 complete
android只支持有限数量的可同步的MediaPlayer,不释放它们会导致运行时错误,所以当你完成播放的时候,记得:
mediaPlayer.release(); 来释放所涉及的资源。
Prepare音频
MediaPlayer可以播放本地文件、Content Providers、远程URL流。
加载:
02 |
MediaPlayer resourcePlayer = |
03 |
MediaPlayer.create( this , R.raw.my_audio); |
06 |
MediaPlayer filePlayer = MediaPlayer.create( this , |
10 |
MediaPlayer urlPlayer = MediaPlayer.create( this , |
14 |
MediaPlayer contentPlayer = MediaPlayer.create( this , |
15 |
Settings.System.DEFAULT_RINGTONE_URI); |
注意:上述这种create后返回mediaPlayer的方式,其实已经调用了prepare方法,所以不能再调用了。
涉及网络的,记得加网络权限。
方法2:
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(“/sdcard/mydopetunes.mp3”);
mediaPlayer.prepare();
与上面类似。
Prepare视频
想要播放视频,比播放音频复杂许多。播放视频你必须有一个surface来支持。
2种方式来播放视频:
方法一:使用VideoView,内置了surface,通过MediaPlayer加载。
方法二:自己指定surface,直接操作底层的MediaPlayer。
播放视频通过VideoView:
1 |
final VideoView videoView = (VideoView)findViewById(R.id.videoView); |
4 |
videoView.setVideoPath(“/sdcard/mycatvideo.3gp”); |
7 |
videoView.setVideoUri(myAwesomeStreamingSource); |
当Video被初始化后,你可以控制它的播放通过使用start、stopPlayback、pause、seekTo方法。
VideoView还包含setKeepScreenOn方法,在播放中屏幕不锁屏。
方法一:使用VideoView:
02 |
final VideoView videoView = (VideoView)findViewById(R.id.videoView); |
05 |
videoView.setKeepScreenOn( true ); |
06 |
videoView.setVideoPath(“/sdcard/mycatvideo.3gp”); |
09 |
MediaController mediaController = new MediaController( this ); |
10 |
videoView.setMediaController(mediaController); |
方法二:利用surface
SurfaceHolder是异步创建的,所以你必须等surfaceCreated触发后,你才能将Holder给mediaPlayer。
直接看框架代码:
01 |
public class SurfaceViewVideoViewActivity extends Activity |
02 |
implements SurfaceHolder.Callback { |
04 |
static final String TAG = “SurfaceViewVideoViewActivity”; |
06 |
private MediaPlayer mediaPlayer; |
08 |
public void surfaceCreated(SurfaceHolder holder) { |
13 |
mediaPlayer.setDisplay(holder); |
14 |
mediaPlayer.setDataSource(“/sdcard/test2.3gp”); |
15 |
mediaPlayer.prepare(); |
16 |
} catch (IllegalArgumentException e) { |
17 |
Log.e(TAG, “Illegal Argument Exception”, e); |
18 |
} catch (IllegalStateException e) { |
19 |
Log.e(TAG, “Illegal State Exception“, e); |
20 |
} catch (SecurityException e) { |
21 |
Log.e(TAG, “Security Exception“, e); |
22 |
} catch (IOException e) { |
23 |
Log.e(TAG, “IO Exception“, e); |
27 |
public void surfaceDestroyed(SurfaceHolder holder) { |
28 |
mediaPlayer.release(); |
31 |
public void surfaceChanged(SurfaceHolder holder, |
32 |
int format, int width, int height) { } |
35 |
public void onCreate(Bundle savedInstanceState) { |
36 |
super .onCreate(savedInstanceState); |
38 |
setContentView(R.layout.surfaceviewvideoviewer); |
41 |
mediaPlayer = new MediaPlayer(); |
44 |
final SurfaceView surfaceView = |
45 |
(SurfaceView)findViewById(R.id.surfaceView); |
48 |
surfaceView.setKeepScreenOn( true ); |
51 |
SurfaceHolder holder = surfaceView.getHolder(); |
52 |
holder.addCallback( this ); |
53 |
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); |
54 |
holder.setFixedSize( 400 , 300 ); |
57 |
Button playButton = (Button)findViewById(R.id.buttonPlay); |
58 |
playButton.setOnClickListener( new OnClickListener() { |
59 |
public void onClick(View v) { |
66 |
Button pauseButton = (Button)findViewById(R.id.buttonPause); |
67 |
pauseButton.setOnClickListener( new OnClickListener() { |
68 |
public void onClick(View v) { |
74 |
Button skipButton = (Button)findViewById(R.id.buttonSkip); |
75 |
skipButton.setOnClickListener( new OnClickListener() { |
76 |
public void onClick(View v) { |
77 |
mediaPlayer.seekTo(mediaPlayer.getDuration()/ 2 ); |
控制MediaPlayer的播放
mediaPlayer.start()后就开始播放。 getDuration方法获得播放的长度,getCurrentPosition找到当前播放到的位置。使用seekTo方法跳到指定的位置。
去确保一致的体验,Android提供了MediaController-一个标准的提供常用的Media控制按钮,就像:
你若想使用MediaController去控制播放,最好在代码中实例化它。当你这么做了,MediaController只会在你设置它为visible之后或者触摸它的Video View,或者与其交互。
如果你使用VideoView去显示你的视频内容,你可以简单得通过VideoView的setMediaController方法:
2 |
MediaController mediaController = new MediaController( this ); |
3 |
videoView.setMediaController(mediaController); |
去控制一个MediaPlayer,你需要去实现一个新的MediaController.MediaPlayerControl:
01 |
MediaController mediaController = new MediaController( this ); |
02 |
mediaController.setMediaPlayer( new MediaPlayerControl() { |
04 |
public boolean canPause() { |
08 |
public boolean canSeekBackward() { |
12 |
public boolean canSeekForward() { |
16 |
public int getBufferPercentage() { |
20 |
public int getCurrentPosition() { |
21 |
return mediaPlayer.getCurrentPosition(); |
24 |
public int getDuration() { |
25 |
return mediaPlayer.getDuration(); |
28 |
public boolean isPlaying() { |
29 |
return mediaPlayer.isPlaying(); |
36 |
public void seekTo( int pos) { |
37 |
mediaPlayer.seekTo(pos); |
使用setAnchorView方法去决定MediaController依附在哪个View上,这个View可以是任意View。
调用show或者hide来显示或者隐藏。
1 |
mediaController.setAnchorView(myView); |
2 |
mediaController.show(); |
管理MediaPlayer的输出
MediaPlayer提供方法去控制音量、锁屏亮度、设置循环模式。
控制音量通过setVolume方法。
mediaPlayer.setVolume(0.5f, 0.5f); 值在0-1之间浮点数,0表示静音,1表示最大音量。 2个参数分别代表左声道和右声道。
1 |
mediaPlayer.setScreenOnWhilePlaying( true ); |
3 |
if (!mediaPlayer.isLooping()) |
4 |
mediaPlayer.setLooping( true ); |
有些设备,附上了耳机,或者蓝牙耳机,会提供播放、暂停、skip、上一个播放的 按键。
你可以监听Action为:android.intent.action.MEDIA_BUTTON。
01 |
public class MediaControlReceiver extends BroadcastReceiver { |
03 |
public static final String ACTION_MEDIA_BUTTON = |
04 |
“com.paad.ACTION_MEDIA_BUTTON”; |
07 |
public void onReceive(Context context, Intent intent) { |
08 |
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { |
09 |
Intent internalIntent = new Intent(ACTION_MEDIA_BUTTON); |
10 |
internalIntent.putExtras(intent.getExtras()); |
11 |
context.sendBroadcast(internalIntent); |
16 |
public class ActivityMediaControlReceiver extends BroadcastReceiver { |
18 |
public void onReceive(Context context, Intent intent) { |
19 |
if (MediaControlReceiver.ACTION_MEDIA_BUTTON.equals( |
20 |
intent.getAction())) { |
22 |
(KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); |
24 |
switch (event.getKeyCode()) { |
25 |
case (KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) : |
26 |
if (mediaPlayer.isPlaying()) |
31 |
case (KeyEvent.KEYCODE_MEDIA_PLAY) : |
33 |
case (KeyEvent.KEYCODE_MEDIA_PAUSE) : |
35 |
case (KeyEvent.KEYCODE_MEDIA_NEXT) : |
37 |
case (KeyEvent.KEYCODE_MEDIA_PREVIOUS) : |
40 |
case (KeyEvent.KEYCODE_MEDIA_STOP) : |
AudioManager的registMediaButtonEventReceiver方法去注册接受者,可以防止其他APP也在监听ACTION。
04 |
(AudioManager)getSystemService(Context.AUDIO_SERVICE); |
05 |
ComponentName component = |
06 |
new ComponentName( this , MediaControlReceiver. class ); |
08 |
am.registerMediaButtonEventReceiver(component); |
12 |
activityMediaControlReceiver = new ActivityMediaControlReceiver(); |
14 |
new IntentFilter(MediaControlReceiver.ACTION_MEDIA_BUTTON); |
16 |
registerReceiver(activityMediaControlReceiver, filter); |