与音频的不同点是在视频录制中需要定义一个额外的SurfaceView组件,以捕获摄像头采集的数据。
(1)主程序
publicclass MyMediaRecorderDemo extends Activity {
private ImageButton record = null;
private ImageButton stop = null;
private ImageButton browser = null;
private TextView info = null;
private MediaRecorder mediaRecorder = null;
private boolean sdcardExists = false; // SD卡存在的标记
private File recordVideoSaveFileDir = null;
private File recordVideoSaveFile = null;
private String recordVideoSaveFileName =null;
private String recDir ="mldnvideo";
private boolean isRecord = false;
private SurfaceView surface = null;
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
super.requestWindowFeature(Window.FEATURE_NO_TITLE);// 不显示标题
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 高亮的风格显示
super.setContentView(R.layout.main);
this.record = (ImageButton)super.findViewById(R.id.record);
this.stop = (ImageButton) super.findViewById(R.id.stop);
this.browser = (ImageButton)super.findViewById(R.id.browser);
this.info = (TextView)super.findViewById(R.id.info);
this.surface = (SurfaceView)super.findViewById(R.id.surface);
this.surface.getHolder().setType(
SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.surface.getHolder().setFixedSize(480,800);
if ((this.sdcardExists =Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))) {
this.recordVideoSaveFileDir = newFile(Environment
.getExternalStorageDirectory().toString()
+ File.separator
+MyMediaRecorderDemo.this.recDir + File.separator); // 保存文件夹
if(!this.recordVideoSaveFileDir.exists()) {
this.recordVideoSaveFileDir.mkdirs();// 创建文件夹
}
}
this.record.setOnClickListener(newRecordOnClickListenerImpl()) ;
this.stop.setOnClickListener(newStopOnClickListenerImpl()) ;
this.browser.setOnClickListener(newBrowserOnClickListenerImpl()) ;
this.stop.setEnabled(false) ; // 停止录象的按钮暂时不可用
}
private class RecordOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
if(MyMediaRecorderDemo.this.sdcardExists){ // sd卡存在
MyMediaRecorderDemo.this.recordVideoSaveFileName= MyMediaRecorderDemo.this.recordVideoSaveFileDir
.toString()
+ File.separator
+ "MLDNVideo_"
+System.currentTimeMillis() + ".3gp";// 文件的路径名称
MyMediaRecorderDemo.this.recordVideoSaveFile= new File(
MyMediaRecorderDemo.this.recordVideoSaveFileName);//文件路径
MyMediaRecorderDemo.this.mediaRecorder= new MediaRecorder() ;
MyMediaRecorderDemo.this.mediaRecorder.reset();// 重置
MyMediaRecorderDemo.this.mediaRecorder
.setAudioSource(MediaRecorder.AudioSource.MIC);
MyMediaRecorderDemo.this.mediaRecorder
.setVideoSource(MediaRecorder.VideoSource.CAMERA);
MyMediaRecorderDemo.this.mediaRecorder
.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
MyMediaRecorderDemo.this.mediaRecorder
.setVideoEncoder(MediaRecorder.VideoEncoder.H263);//定义视频编码
MyMediaRecorderDemo.this.mediaRecorder
.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//定义音频编码
MyMediaRecorderDemo.this.mediaRecorder
.setOutputFile(MyMediaRecorderDemo.this.recordVideoSaveFileName);//定义输出文件
MyMediaRecorderDemo.this.mediaRecorder.setVideoSize(320,240) ;
MyMediaRecorderDemo.this.mediaRecorder.setVideoFrameRate(10);//每秒10帧
MyMediaRecorderDemo.this.mediaRecorder
.setPreviewDisplay(MyMediaRecorderDemo.this.surface
.getHolder().getSurface());//定义视频显示
try {
MyMediaRecorderDemo.this.mediaRecorder.prepare();
} catch (Exception e) {
Log.i("MyMediaRecorderDemo",e.toString()) ;
}
MyMediaRecorderDemo.this.mediaRecorder.start();
MyMediaRecorderDemo.this.info.setText("正在录象中...") ;
MyMediaRecorderDemo.this.stop.setEnabled(true);
MyMediaRecorderDemo.this.record.setEnabled(false);
MyMediaRecorderDemo.this.isRecord= true ;
}
}
}
private class StopOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
if(MyMediaRecorderDemo.this.isRecord){
MyMediaRecorderDemo.this.mediaRecorder.stop();
MyMediaRecorderDemo.this.mediaRecorder.release();
MyMediaRecorderDemo.this.stop.setEnabled(false);
MyMediaRecorderDemo.this.record.setEnabled(true);
MyMediaRecorderDemo.this.info.setText("录象结束,文件路径为:"
+MyMediaRecorderDemo.this.recordVideoSaveFile);
}
}
}
private class BrowserOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
Intent it = newIntent(MyMediaRecorderDemo.this,BroswerActivity.class) ;
MyMediaRecorderDemo.this.startActivity(it);
}
}
@Override
public boolean onKeyDown(int keyCode,KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {//如果是手机上的返回键
super.finish() ;//程序结束
}
return false ;
}
}
(2)定义BrowserActivity程序完成ListView列表显示
public class BroswerActivity extends Activity {
private ImageButton back = null ;
private ListView videolist = null ;
private SimpleAdapter recordSimpleAdapter =null ;
private List<Map<String,Object>>recordFiles = null ;
private String recDir ="mldnvideo";
private File recordVideoSaveFileDir = null;
private boolean sdcardExists = false;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
super.requestWindowFeature(Window.FEATURE_NO_TITLE);// 不显示标题
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 高亮的风格显示
super.setContentView(R.layout.broswer);
if ((this.sdcardExists =Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))) {
this.recordVideoSaveFileDir = newFile(Environment
.getExternalStorageDirectory().toString()
+ File.separator
+BroswerActivity.this.recDir + File.separator); // 保存文件夹
if(!this.recordVideoSaveFileDir.exists()) {
this.recordVideoSaveFileDir.mkdirs();// 创建文件夹
}
}
this.back = (ImageButton)super.findViewById(R.id.back) ;
this.videolist = (ListView)super.findViewById(R.id.videolist) ;
this.back.setOnClickListener(newBackOnClickListenerImpl()) ;
this.getRecordFiles() ;
this.videolist.setOnItemClickListener(newOnItemClickListenerImpl()) ;
}
private void getRecordFiles() {
this.recordFiles = newArrayList<Map<String, Object>>();
if(this.sdcardExists){
File files [] =this.recordVideoSaveFileDir.listFiles() ;
for (int x = 0; x < files.length;x++) {
Map<String, Object>fileInfo = new HashMap<String, Object>();
fileInfo.put("filename",files[x].getName()) ;
this.recordFiles.add(fileInfo) ;
}
this.recordSimpleAdapter = newSimpleAdapter(this,
this.recordFiles,R.layout.recordfiles,
new String[] {"filename" }, new int[] { R.id.filename });
this.videolist.setAdapter(this.recordSimpleAdapter);
}
}
private class BackOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
Intent it = newIntent(BroswerActivity.this,MyMediaRecorderDemo.class) ;
BroswerActivity.this.startActivity(it);
}
}
private class OnItemClickListenerImplimplements OnItemClickListener {
@Override
public voidonItemClick(AdapterView<?> adapter, View view, int position,
long id) {
if(BroswerActivity.this.recordSimpleAdapter.getItem(position) instanceof Map) {
Map<?, ?> map = (Map<?,?>) BroswerActivity.this.recordSimpleAdapter
.getItem(position);
Intent intent = new Intent(BroswerActivity.this,PlayVideoActivity.class);
intent.putExtra("filepath",
BroswerActivity.this.recordVideoSaveFileDir.toString()
+ File.separator
+map.get("filename").toString());
BroswerActivity.this.startActivity(intent);
}
}
}
}
(3)视频播放程序
publicclass PlayVideoActivity extends Activity {
private ImageButton play = null;
private ImageButton stop = null;
private ImageButton back = null;
private MediaPlayer media = null;
private SurfaceView sufaceView = null;
private SurfaceHolder surfaceHolder = null;
private String filepath = null;
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
super.requestWindowFeature(Window.FEATURE_NO_TITLE);// 不显示标题
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 高亮的风格显示
super.setContentView(R.layout.play);
this.filepath =super.getIntent().getStringExtra("filepath") ;
this.play = (ImageButton)super.findViewById(R.id.play);
this.stop = (ImageButton)super.findViewById(R.id.stop);
this.back = (ImageButton)super.findViewById(R.id.back);
this.sufaceView = (SurfaceView)super.findViewById(R.id.surfaceView) ;
this.surfaceHolder =this.sufaceView.getHolder() ;
this.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.media = new MediaPlayer() ;
this.media.reset() ;
try {
this.media.setDataSource(this.filepath);
} catch (Exception e) {
}
this.play.setOnClickListener(newPlayOnClickListenerImpl());
this.stop.setOnClickListener(newStopOnClickListenerImpl());
this.back.setOnClickListener(newBackOnClickListenerImpl());
}
private class PlayOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
PlayVideoActivity.this.media.setAudioStreamType(AudioManager.STREAM_MUSIC);
PlayVideoActivity.this.media.setDisplay(PlayVideoActivity.this.surfaceHolder);
try {
PlayVideoActivity.this.media.prepare();
PlayVideoActivity.this.media.start();
} catch (Exception e) {
}
}
}
private class StopOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
PlayVideoActivity.this.media.stop();
}
}
private class BackOnClickListenerImplimplements OnClickListener {
@Override
public void onClick(View v) {
Intent it = newIntent(PlayVideoActivity.this, BroswerActivity.class);
PlayVideoActivity.this.startActivity(it);
}
}
@Override
public boolean onKeyDown(int keyCode,KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
this.media.stop() ;
this.media.release() ;
super.finish() ;
}
return false ;
}
}
(4)定义BrowserActivity程序进行ListView显示时的布局管理器---recordfiles.xml
<?xmlversion="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableRow>
<ImageView
android:id="@+id/icon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/file_icon"/>
<TextView
android:id="@+id/filename"
android:textSize="25px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</TableRow>
</TableLayout>
(5)定义BrowserActivity程序的布局管理器---browser.xml
<?xmlversion="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">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:id="@+id/info"
android:textSize="25px"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="视频文件列表" />
<ImageButton
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/back"/>
</LinearLayout>
<ListView
android:id="@+id/videolist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
(6)定义视频播放程序PlayVideoActivity的布局管理器---play.xml
<?xmlversion="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">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/play"/>
<ImageButton
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/stop"/>
<ImageButton
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="@drawable/back"/>
</LinearLayout>
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
(7)配置权限文件
<uses-permissionandroid:name="android.permission.RECORD_AUDIO" />
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permissionandroid:name="android.permission.CAMERA" />