其实就是一个简单的视频和音频播放小程序! 先看截图:
本程序是根据网上一个示例更改的:blog.csdn.net/hellogv/article/details/5975864
上面链接文档中的程序是无法直接(在Android2.3上)执行的,会提示一个:getVideoHeight failed 错误!
如果通过注释的方法忽略该错误,将会导致音频和视频的进度条无法实时更新;于是本示例抛弃了原文档中的定时器(mTimerTask)控制方法,改用成多线程进行更新。
下面来看源代码吧,首先是布局文件main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SeekBar android:id="@+id/SeekBar01" android:layout_height="wrap_content"
android:layout_width="fill_parent"></SeekBar>
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:id="@+id/Button01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="播放音频"></Button>
<Button android:id="@+id/Button02" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="停止播放"></Button>
</LinearLayout>
<SeekBar android:id="@+id/SeekBar02" android:layout_height="wrap_content"
android:layout_width="fill_parent"></SeekBar>
<SurfaceView android:id="@+id/SurfaceView01"
android:layout_width="fill_parent" android:layout_height="360px"></SurfaceView>
<LinearLayout android:id="@+id/LinearLayout02"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/Button03"
android:text="播放视频"></Button>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="停止播放" android:id="@+id/Button04"></Button>
</LinearLayout>
</LinearLayout>
主要就是使用了线性布局(LinearLayout)的嵌套,其它也没什么特别的。
然后是AndroidManifest.xml文件,需要添加一个强制竖屏的设置,因为要是允许了重力感应,多媒体的进度条将会变得无法控制。只需在<activity>标签中添加:
android:launchMode="singleTask"
android:screenOrientation="portrait"
因为强制设置了竖屏显示,所以布局中<SurfaceView>的高度定义可以根据自己的视频实际尺寸计算一下,免得比例失真!
关于横屏、竖屏、全屏的设置可以参看:hi.baidu.com/wither/blog/item/7f35f1f2a8828d0ab17ec546.html
最后就是主程序文件Mplayer.java了:
package com.ucrobotics.mplayer;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;
public class Mplayer extends Activity {
/** Called when the activity is first created. */
private SeekBar skb_audio=null;
private Button btn_start_audio = null;
private Button btn_stop_audio = null;
private SeekBar skb_video=null;
private Button btn_start_video = null;
private Button btn_stop_video = null;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer m = null;
private String mp3Path = "/sdcard/Music/Young_For_You.mp3";
private String mp4Path = "/sdcard/Video/mv.mp4";
private boolean isVideo=false;
private boolean isAudio=false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//----------Media控件设置---------//
m=new MediaPlayer();
//播放结束后释放MediaPlayer
m.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer arg0) {
//Toast.makeText(Mplayer.this, "结束", Toast.LENGTH_LONG).show();
m.release();
}
});
btn_start_audio = (Button) this.findViewById(R.id.Button01);
btn_stop_audio = (Button) this.findViewById(R.id.Button02);
btn_start_audio.setOnClickListener(new ClickEvent());
btn_stop_audio.setOnClickListener(new ClickEvent());
skb_audio=(SeekBar)this.findViewById(R.id.SeekBar01);
skb_audio.setOnSeekBarChangeListener(new SeekBarChangeEvent());
btn_start_video = (Button) this.findViewById(R.id.Button03);
btn_stop_video = (Button) this.findViewById(R.id.Button04);
btn_start_video.setOnClickListener(new ClickEvent());
btn_stop_video.setOnClickListener(new ClickEvent());
skb_video=(SeekBar)this.findViewById(R.id.SeekBar02);
skb_video.setOnSeekBarChangeListener(new SeekBarChangeEvent());
surfaceView = (SurfaceView) findViewById(R.id.SurfaceView01);
surfaceHolder = surfaceView.getHolder();
//surfaceHolder.setFixedSize(100, 100);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/*
* 按键事件处理
*/
class ClickEvent implements View.OnClickListener{
public void onClick(View v) {
if(v==btn_start_audio)
{
//设置audio或video标记,以便控制各自的进度条变化
isAudio = true;
isVideo = false;
//恢复到未初始化的状态
m.reset();
//有两种方式获取资源文件:从工程的resource目录,或是指定路径;鉴于文件比较大,所以本示例均是从SD卡获取
//m=MediaPlayer.create(TestPlayer.this, R.raw.big);//读取音频
m=MediaPlayer.create(Mplayer.this, Uri.parse("file://" + mp3Path));
//设置SeekBar的长度
skb_audio.setMax(m.getDuration());
//每次播放都将进度条重置为0
skb_audio.setProgress(0);
try {
m.prepare(); //准备
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
m.start(); //播放
//启动一个新线程用于更新音频的进度条
aseekth as = new aseekth();
as.start();
}
else if(v==btn_stop_audio)
{
try{
m.stop();
isAudio = false;
} catch (Exception e) { }
}
else if(v==btn_stop_video)
{
try{
m.stop();
isVideo = false;
} catch (Exception e) { }
}
else if(v==btn_start_video)
{
isVideo = true;
isAudio = false;
m.reset();
//m=MediaPlayer.create(TestPlayer.this, R.raw.test);//读取视频
m=MediaPlayer.create(Mplayer.this, Uri.parse("file://" + mp4Path));
//设置SeekBar的长度
skb_video.setMax(m.getDuration());
//每次播放都将进度条重置为0
skb_video.setProgress(0);
m.setAudioStreamType(AudioManager.STREAM_MUSIC);
m.setDisplay(surfaceHolder);//设置屏幕
try {
m.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
m.start();
//启动一个新线程用于更新视频的进度条
vseekth vs = new vseekth();
vs.start();
}
}
}
/*
* SeekBar进度改变事件
*/
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
m.seekTo(seekBar.getProgress());
}
}
/*
* 音频进度条线程处理
*/
private class aseekth extends Thread {
public void run() {
try {
while(isAudio){
if(skb_audio.getProgress() < m.getCurrentPosition()){
skb_audio.setProgress(m.getCurrentPosition());
sleep(10);
}
}
} catch (Exception e) { }
}
}
/*
* 视频进度条线程处理
*/
private class vseekth extends Thread {
public void run() {
try {
while(isVideo){
if(skb_video.getProgress() < m.getDuration()){
skb_video.setProgress(m.getCurrentPosition());
sleep(10);
}
}
} catch (Exception e) { }
}
}
}
里面的注释应该很详细了。
运行本示例注意事项:
1. 更改源文件的定义:即mp3Path 和 mp4Path,都指向的是SD卡上的资源
2. 根据自己设备的分辨率适当调整布局中<SurfaceView>的高度
关于多媒体播放还个参阅另一篇帖子:vanlee820816.blog.163.com/blog/static/17981351200971993443205/