第十一章:Android中的多媒体应用

播放音频及视频我们会用到MediaPlayer和JetPlayer类,录制音频及视频我们会用到MediaRecorder类。文件的来源可以是本地文件系统文件、存储在Android中的资源文件,还可以是通过网络的文件流。

Android对常用媒体格式提供了支持,支持的图片格式有JPEG、GIF、PNG、BMP,支持的音频格式有3GP、MP3、WAV,支持的视频格式有3GP、MP4等。 

一、音频及视频播放

1、从源文件中播放

1)、在项目的res/raw文件夹下放置一个Android支持的媒体文件,例如一个MP3文件

2)、创建一个MediaPlayer实例,可以使用MediaPlayer的静态方法create来完成

3)、调用start()方法开始播放,调用pause()方法暂停播放,调用stop()方法停止播放。如果希望重复播放,在调用start()方法之前,必须调用reset()和prepare()方法

	//实例化MediaPlayer
         MediaPlayer player = MediaPlayer.create(this, R.raw.music1);
         //开始播放
          player.start();

2、从文件系统中播放

例如在我们的SDCard中有一些音频及视频文件

1)、实例化一个MediaPlayer

2)、调用setDataSource()方法来设置想要播放文件的路径

3)、首先调用prepare(),然后调用start()来进行播放

 	//实例化MediaPlayer
         MediaPlayer mp = new MediaPlayer();
         //播放路径
          String path = "/sdcard/music1.mp3";
        //为MediaPlayer设置数据源
          mp.setDataSource(path);
        //准备
          mp.prepare();
        //播放
          mp.start();

3、从网络中播放

方法一:1)、创建网络URI实例

2)、创建一个MediaPlayer实例,可以使用MediaPlayer的静态方法create,通过传递URI参数来完成

3)、调用start()方法开始播放

       String path = "http://msl.m.mop.com/2008/08/27/012/music1.mp3";
       Uri uri = Uri.parse(path);
       MediaPlayer player = MediaPlayer.create(this,uri);
       player.start();

方法二:1)、实例化一个MediaPlayer

2)、调用setDataSource()方法来设置想要播放文件的路径,改路径是网络上可用的路径

3)、首先调用prepare(),然后调用start()来进行播放

      MediaPlayer mp = new MediaPlayer();
      String path = "http://msl.m.mop.com/2008/08/27/012/music1.mp3";
      mp.setDataSource(path);
      mp.prepare();
      mp.start();

二、迷你音乐播放器

具有控制界面的音乐播放器

public class MainActivity extends Activity implements OnCompletionListener {
    //声明图片按钮ImageButton
    private ImageButton playBtn,pauseBtn,stopBtn;
    //声明MediaPlayer实例
    private MediaPlayer mp;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        playBtn = (ImageButton) findViewById(R.id.play);
        pauseBtn = (ImageButton) findViewById(R.id.pause);
        stopBtn = (ImageButton) findViewById(R.id.stop);
        playBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				play();
			}
		});
        pauseBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				pause();
			}
		});
        stopBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				stop();
			}
		});
        //准备
        setup();
    }
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	if(stopBtn.isEnabled()){
    		stop();
    	}
    }
	@Override
	public void onCompletion(MediaPlayer mp) {
		stop();
	}
	private void play(){
		mp.start();
		//使播放按钮失效
		playBtn.setEnabled(false);
		//使暂停按钮生效
		pauseBtn.setEnabled(true);
		//使停止按钮生效
		stopBtn.setEnabled(true);
	}
	private void pause(){
		mp.pause();
		playBtn.setEnabled(true);
		pauseBtn.setEnabled(false);
		stopBtn.setEnabled(true);
	}
	private void stop(){
		mp.stop();
		pauseBtn.setEnabled(false);
		stopBtn.setEnabled(false);
		try {
			//准备
			mp.prepare();
			//定位到开始
			mp.seekTo(0);
			playBtn.setEnabled(true);
		} catch (Throwable t) {
			error(t);
		}
	}
	//加载播放文件
	private void loadClip(){
		try {
			mp = MediaPlayer.create(this, R.raw.music1);
			mp.setOnCompletionListener(this);
		} catch (Throwable t) {
			error(t);
		}
	}
	//准备
	private void setup(){
		loadClip();
		playBtn.setEnabled(true);
		pauseBtn.setEnabled(false);
		stopBtn.setEnabled(false);
	}
	//出错提示
	private void error(Throwable t){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("报错啦!")
		.setMessage(t.toString())
		.setPositiveButton("确定",null)
		.show();
	}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="迷你音乐播放器" />
    
    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        
        <ImageButton 
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/play" />
        
        <ImageButton 
            android:id="@+id/pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/pause" />
        
        <ImageButton 
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/stop" />
        
    </LinearLayout>

</LinearLayout>

三、迷你视频播放器

借助VideoView和MediaController组件可以很方便的实现一个视频播放器

public class VideoActivity extends Activity {
	private VideoView video;
	//声明媒体控制组件
	private MediaController ctlr;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//设置窗口特征
		getWindow().setFormat(PixelFormat.TRANSLUCENT);
		setContentView(R.layout.video);
		//实例化file
		File clip = new File("/sdcard/test.mp4");
		//判断文件是否存在
		if(clip.exists()){
			video = (VideoView) findViewById(R.id.video);
			video.setVideoPath(clip.getAbsolutePath());
			ctlr = new MediaController(this);
			//MediaController和MediaPlayer相互关联
			ctlr.setMediaPlayer(video);
			video.setMediaController(ctlr);
			//使VideoView获得焦点
			video.requestFocus();
		}
	}
}

vedio.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <VideoView 
        android:id="@+id/video"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

四、音视频的录制

通过MediaRecorder完成,常用的方法有:start()开始录制、pause()暂停录制、stop()停止录制、prepare()准备录制、reset()重新开始、release()释放资源等。

public class MainActivity extends Activity {
	private ImageButton recordBtn,stopBtn;
	private MediaRecorder mr;
	private String path;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		recordBtn = (ImageButton) findViewById(R.id.l_record);
		stopBtn = (ImageButton) findViewById(R.id.l_stop);
		recordBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				record();//录制
			}
		});
		stopBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				stop();
			}
		});
		setup();//准备
	}
	//设置路径
	private void setPath() throws IOException{
		//路径为sd扩展卡
		path = "/sdcard/test1.map3";
		//获得sd扩展卡状态
		String state = android.os.Environment.getExternalStorageState();
		//判断是否安装扩展卡
		if(!state.equals(android.os.Environment.MEDIA_MOUNTED)){
			throw new IOException("SD没有安装。它的状态是" + state);
		}
		//获得文件父目录
		File directory = new File(path).getParentFile();
		if(!directory.exists() && !directory.mkdirs()){
			throw new IOException("文件不能被创建");
		}
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if(stopBtn.isEnabled()){
			stop();
		}
	}
	//录制方法
	private void record(){
		try {
			mr.prepare();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mr.start();
		recordBtn.setEnabled(false);
		stopBtn.setEnabled(true);
	}
	//停止
	private void stop(){
		mr.stop();
		stopBtn.setEnabled(false);
		recordBtn.setEnabled(true);
		mr.release();//释放资源
	}
	//设置属性
	private void setProperty(){
		try {
			mr = new MediaRecorder();
			//设置音频源
			mr.setAudioSource(MediaRecorder.AudioSource.MIC);
			//设置输出格式
			mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			//设置音频编码器
			mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			try {
				//设置路径
				setPath();
			} catch (Throwable t) {
				error(t);
			}
			//设置输出文件
			mr.setOutputFile(path);
		} catch (Throwable t) {
			error(t);
		}
	}
	//准备
	private void setup(){
		setProperty();
		recordBtn.setEnabled(true);
		stopBtn.setEnabled(false);
	}
	//错误提示
	private void error(Throwable t){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("报错啦!")
		.setMessage(t.toString())
		.setPositiveButton("确定", null)
		.show();
	}
}

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
	<TextView 
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="迷你录音器" />
	
	<LinearLayout 
	    android:orientation="horizontal"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent" >
	    
	    <ImageButton 
	        android:id="@+id/l_record"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:src="@drawable/s" />
	    
	    <ImageButton 
	        android:id="@+id/l_stop"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:src="@drawable/stop" />
	    
	</LinearLayout>
    
</LinearLayout>

五、Camera照相

使用到了很多类,如下介绍:

  • SurfaceView:该类是一个视图组件,实现了照片的预览功能
  • SurfaceHolder:一个抽象接口,是SurfaceView的支持类,一般通过SurfaceView的getHolder()方法获得。允许你控制界面的尺寸和格式、编辑界面的像素,以及监控界面尺寸的改变
  • SurfaceHolder.Callback:SurfaceHolder的一个内部接口,可以实现该接口获得界面改变的信息。该接口中有三个方法,surfaceCreated()方法在界面创建时被调用,一般在该方法中打开照相机并设置预览。surfaceChanged()方法在界面尺寸改变时被调用,一般在该方法中设置相机的参数(大小、格式等)。surfaceDestroyed()方法在界面被销毁时调用,在该方法中清除相机实例,释放资源
  • Camera:相机类,实现拍照功能
  • Camera.PictureCallback:Camera的一个内部接口,处理照片准备好后的回调

通过上面类的介绍,我们可以实现一个拍照程序。

public class CameraActivity extends Activity {
	//声明拍照界面组件
	private SurfaceView surfaceView;
	//声明界面控制组件
	private SurfaceHolder surfaceHolder;
	//声明照相机
	private Camera camera;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.camera);
		surfaceView = (SurfaceView) findViewById(R.id.preview);
		surfaceHolder = surfaceView.getHolder();
		//实现SurfaceHolder.Callback回调接口,实现该接口中的三个方法
		SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
			@Override
			public void surfaceCreated(SurfaceHolder holder) {
				//打开照相机
				camera = Camera.open();
				try {
					//设置预览
					camera.setPreviewDisplay(holder);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			@Override
			public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
				//获取相机参数
				Camera.Parameters parameters = camera.getParameters();
				//设置照片大小
				parameters.setPreviewSize(width, height);
				//设置照片格式
				parameters.setPreviewFormat(PixelFormat.JPEG);
				//设置相机参数
				camera.setParameters(parameters);
				//开始预览
				camera.startPreview();
			}
			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				camera.stopPreview();
				camera.release();
				camera = null;
			}
		};
		//为SurfaceHolder添加回调,并设置其类型
		surfaceHolder.addCallback(surfaceCallback);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);		
	}
	
	//创建一个保存照片任务类,该类的主要功能是从硬件获得的字节流保存到设备文件中
	class SavePictureTask extends AsyncTask<byte[], String, String>{
		@Override
		protected String doInBackground(byte[]... params) {
			//创建文件
			File picture = new File(Environment.getExternalStorageDirectory(),"picture.jpg");
			//如果文件存在删除掉
			if(picture.exists())
				picture.delete();
			try {
				//获得文件输出流
				FileOutputStream fos = new FileOutputStream(picture.getPath());
				//写到该文件
				fos.write(params[0]);
				//关闭文件流
				fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}
	//实现Camera.PictureCallback回调方法,执行保存照片任务
	Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			new SavePictureTask().execute(data);
			camera.startPreview();
		}
	};
	//拍照方法
	private void takePic(){
		//停止预览
		camera.stopPreview();
		//拍照
		camera.takePicture(null, null, pictureCallback);
	}
	//响应按键事件
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH){
			takePic();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}

camera.xml

<?xml version="1.0" encoding="utf-8"?>
<android.view.SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    
</android.view.SurfaceView>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值