28.Android-多媒体(视频播放器-拍照-录像)

一.知识概要

1.拍照实现步骤:
    <1>界面使用SurfaceView控件,显示照相机的画面
    <2>SurfaceView接受摄像头界面变化的信息
        surfaceView.getHolder().addCallback()
    <3>重写三个方法
        surfaceDestroyed--->当预览界面关闭时,触发
            一般在这里执行销毁照相机的操作,释放内存
            camera.stopPreview();
            camera.release();
            camera = null;
        surfaceCreated----->预览界面被创建时,调用
            一般在这里打开照相机和设置照相机的一些参数

            // 打开摄像头
            camera = Camera.open();

            // 给摄像头设置参数
            Parameters parameters = camera.getParameters();
            // 设置每秒3栈
            parameters.setPreviewFrameRate(3);
            // 设置照片的输出格式
            parameters.setPictureFormat(PixelFormat.JPEG);
            // 设置照片的质量
            parameters.set("jpeg-quality", 85);
            // 给照相机设置参数
            camera.setParameters(parameters);
            //将摄像头的画面显示到SurfaceView控件上
            camera.setPreviewDisplay(sv_main_camera.getHolder());
            // 开始预览
            camera.startPreview();
        surfaceChanged----->当预览界面的格式和大小发生改变时,触发
    <4>保存
        camera.takePicture
        将照片保存到内存卡(压缩)

2.视频录制
    实现步骤:
    <1>将视频动画显示到SurfaceView控件上
    <2>使用MediaRecorder类进行视频的录制
        常用的方法:
        mediaRecorder.reset();
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //从照相机采集视频
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setVideoFrameRate(3); //每秒3帧
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); //设置视频编码方式
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        File videoFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+".3gp");
        mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
        mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
        mediaRecorder.prepare();//预期准备
        mediaRecorder.start();//开始刻录
        mediaRecorder.stop();//停止刻录

注意:权限



28.Android-多媒体(视频播放器-拍照-录像)_第1张图片

视频播放器有两种做法
1、使用VideoView播放视频
    audio音频
2、使用SurfaceView+MediaPlayer播放视频



二.播放视频(MediaPlayer+SurfaceView)

1.找到安装Android Studio时的SDK下面的platform-tools,再copy路径


28.Android-多媒体(视频播放器-拍照-录像)_第2张图片28.Android-多媒体(视频播放器-拍照-录像)_第3张图片

28.Android-多媒体(视频播放器-拍照-录像)_第4张图片

再使用adb命令

28.Android-多媒体(视频播放器-拍照-录像)_第5张图片28.Android-多媒体(视频播放器-拍照-录像)_第6张图片

28.Android-多媒体(视频播放器-拍照-录像)_第7张图片28.Android-多媒体(视频播放器-拍照-录像)_第8张图片

activity_main.xml




    

    

    


清单文件AndroidManifest.xml
 
    
MainActivity.java
package com.zking.android28_playvideo;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private MediaPlayer mediaPlayer;
    private SeekBar sb_main_bar;
    private SurfaceView sv_main_surface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sb_main_bar = (SeekBar) findViewById(R.id.sb_main_bar);//获取进度条
        sv_main_surface = (SurfaceView) findViewById(R.id.sv_main_surface);//1.

        sb_main_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            //进度改变
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }
            //开始滑
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }
            //停止滑
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                  //获取当前进度条的位置
                  int currentPosition=seekBar.getProgress();
                  //跳转到某个位置进行播放
                  mediaPlayer.seekTo(currentPosition);
            }
        });
    }

    public void playOrPause(View view){
            final ImageButton imageButton= (ImageButton) view;

            if(mediaPlayer==null) {//一点开始播放
                  //实例化MediaPlayer
                  //mediaPlayer = MediaPlayer.create(this, R.raw.s1);//从项目里面拿音乐
                  //点播放时拿到内存卡的路径(从内存卡中拿音乐)
                  if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                        String sdPath=Environment.getExternalStorageDirectory().getAbsolutePath();
                        mediaPlayer=new MediaPlayer();
                        //设置音频流的类型
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                        //设置音源(协议:file://)
                        try {
                            mediaPlayer.setDataSource(this, Uri.parse("file://"+sdPath+"/dcim/camera/VID_20170717_184535.mp4"));//内存卡下面  //2.
                            mediaPlayer.prepare();//不需要异步准备,只需要准备
                            //需要在清单文件中加权限
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                      //将画面展示到 SurfaceView上
                      mediaPlayer.setDisplay(sv_main_surface.getHolder()); //3.

                      mediaPlayer.start();
                      //暂停图标
                      imageButton.setImageResource(android.R.drawable.ic_media_pause);
                      //获取音乐的播放时间
                      int time=mediaPlayer.getDuration();
                      //设置进度条的最大值 为  音乐的播放时间
                      sb_main_bar.setMax(time);
                      new MyThread().start();

                        //不需要设置准备监听
//                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
//                              @Override
//                              public void onPrepared(MediaPlayer mp) {
//
//                              }
//                        });
                  }
            }else if(mediaPlayer.isPlaying()){//下一次点击如果正在播放
                  mediaPlayer.pause();//暂停
                  //播放图标
                  imageButton.setImageResource(android.R.drawable.ic_media_play);
            }else{//第三次播放
                  mediaPlayer.start();//接着播放
                  //暂停图标
                  imageButton.setImageResource(android.R.drawable.ic_media_pause);
            }
    }

    //子线程 让进度条动起来
    class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            while(sb_main_bar.getProgress()


二.视频播放(VideoView)

简单的,用系统自带的控件。

效果图:

28.Android-多媒体(视频播放器-拍照-录像)_第9张图片

具体代码实现如下:

activity_video.xml




    


AndroidManifest.xml



    
    

    
        
        
        
        
            
                

                
            
        
    

VideoActivity.java
package com.zking.android28_playvideo;

import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.MediaController;
import android.widget.VideoView;

public class VideoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);

        VideoView vv_video= (VideoView) findViewById(R.id.vv_video);
        vv_video.setVideoURI(Uri.parse("file://mnt/sdcard/dcim/camera/VID_20170715_140439.mp4"));

        MediaController mediaController=new MediaController(this);//媒体控制器  this:上下文
        mediaController.setMediaPlayer(vv_video);//让vv_video播放
        vv_video.setMediaController(mediaController);//给vv_video这个控件设置媒体控制器
    }
}



三.拍照

28.Android-多媒体(视频播放器-拍照-录像)_第10张图片

28.Android-多媒体(视频播放器-拍照-录像)_第11张图片

28.Android-多媒体(视频播放器-拍照-录像)_第12张图片

activity_camera.xml




    

    
AndroidManifest.xml



    
    
    
    
    
    
    
    

    
        
        
        
            
                

                
            
        
    

CameraActivity.java
package com.zking.android28_playvideo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;

public class CameraActivity extends AppCompatActivity {

    private SurfaceView sv_camera_surface;
    private Camera camera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_camera);

            sv_camera_surface = (SurfaceView) findViewById(R.id.sv_camera_surface);
            //给SurfaceView添加回调函数
            sv_camera_surface.getHolder().addCallback(new SurfaceHolder.Callback() {
                //surface:想象成画面
                //画面创建,画面开始
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                      //打开摄像头
                      camera = Camera.open(); //.hardware:硬件  默认打开后置摄像头 括号里面Ctrl+P查看参数
                      //设置摄像参数
                      Camera.Parameters parameters= camera.getParameters();//拿到参数
                      parameters.setPictureFormat(PixelFormat.JPEG);//照片的后缀
                      parameters.set("jpeg-quality",100);//照片的质量 0-100值越大照片的质量越高
                      camera.setParameters(parameters);
                      //开启预览效果
                      camera.startPreview();
                      //将画面展示到surfaceView
                      try {
                           camera.setPreviewDisplay(sv_camera_surface.getHolder());
                      } catch (IOException e) {
                           e.printStackTrace();
                      }
                }
                //画面改变时
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

                }
                //画面销毁时
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                       camera.stopPreview();//摄像头关闭
                       camera.release();//让摄像头释放内存
                }
            });
    }

    //拍照的点击事件
    public void takePhoto(View view){
            camera.takePicture(null, null, new Camera.PictureCallback() {//Ctrl+P查看参数
                //图片压缩技术  oom:内存溢出
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {//data字节数组,放图片
                      Bitmap bitmap= BitmapFactory.decodeByteArray(data,0,data.length);//先有一个图片 转码:从0到data.length

                      //时间戳
                      Calendar calendar=Calendar.getInstance();//拿年月日
                      int year=calendar.get(Calendar.YEAR);
                      int month=calendar.get(Calendar.MONTH);
                      int day=calendar.get(Calendar.DAY_OF_MONTH);
                      try {
                           FileOutputStream fos = new FileOutputStream("/mnt/sdcard/dcim/camera/IMG_"+year+(month+1)+day+"_"+System.currentTimeMillis()+".jpg");//照片名字的标准格式
                           //压缩
                           bitmap.compress(Bitmap.CompressFormat.JPEG,85,fos);//压缩的格式,质量,压缩到哪里去
                           //拍完之后接着拍
                          camera.stopPreview();//停一下
                          camera.startPreview();//再给camera开一下,就好比如重启
                      } catch (FileNotFoundException e) {
                          e.printStackTrace();
                      }
                }
            });



    }
}





你可能感兴趣的:(Android)