Android视频录制、播放的两种方式

Android视频录制、播放的两种方式

1、通过Intent的方式:Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

2、使用CameraAPI,调用MediaMediaRecorder

Intent的方式

注意:这里播放camera录制的视频使用VideoView,不使用MediaPlayerSurfaceView的结合。用帧布局Framelayout布局,VideoViewImageView,播放时隐藏视频缩略图,暂停时或初始化时显示视频缩略图。

因为VideoView没有设置监听播放和暂停状态的事件,所以我自定义一个CustomVideoView继承了VideoView,在里面创建一个监听方法和重写VideoView的播放、暂停的方法。

使用相机intent获取视频是使用最少代码使得你的应用获取视频的捷径.一个视频获取intent可以包含以下额外信息:

 

MediaStore.EXTRA_OUTPUT-此设置需要一个保存视频的路径和文件名的Uri.此设置是可选的但是强列推荐的.如果你不指定此值,相机应用就把请求到的图像以默认的文件名保存到默认的文件夹下,这些信息保存在返回的intentIntent.getData()字段中.

MediaStore.EXTRA_VIDEO_QUALITY- 此值在最低质量最小文件尺寸时是0,在最高质量最大文件尺寸时是1.

MediaStore.EXTRA_DURATION_LIMIT- 此值设置获取视频的长度,以秒为单位.

MediaStore.EXTRA_SIZE_LIMIT- 此值设置获取视频文件的大小,以字节为单位.

XML布局视图:

Android视频录制、播放的两种方式

public class MainActivity extends AppCompatActivity {
    private static int REQUST_VIDEO = 1;
    private Button btn;
    private Button btn_start;
    private FrameLayout fl;
    private CustomVideoView video;
    private ImageView iv;
    private String sdCard;
    private String videoPath;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    private void init(){
        btn = ((Button) findViewById(R.id.btn_recoder));
        btn_start = ((Button) findViewById(R.id.btn_start));
        fl = ((FrameLayout) findViewById(R.id.fl_video));
        video = ((CustomVideoView) findViewById(R.id.video));
        iv = ((ImageView) findViewById(R.id.iv));
        sdCard = Environment.getExternalStorageDirectory().getPath();
        String currenTimeMillis = new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(new Date(System.currentTimeMillis()));
        videoPath = sdCard + "/" +  "0000.mp4";
        MediaController controller = new MediaController(this);
        video.setMediaController(controller);
        if (video.isPlaying()){
            iv.setVisibility(View.INVISIBLE);
        }
        video.setPlayPauseListener(new CustomVideoView.PlayPauseListener() {
            @Override
            public void onPlay() {
                Toast.makeText(MainActivity.this,"播放",Toast.LENGTH_SHORT).show();
                iv.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onPause() {
                Toast.makeText(MainActivity.this,"暂停",Toast.LENGTH_SHORT).show();
                iv.setVisibility(View.VISIBLE);
            }
        });
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT,videoPath);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);
                startActivityForResult(intent,REQUST_VIDEO);
            }
        });
    }
    private Bitmap getVideoBitmap(String videoPath){
        MediaMetadataRetriever retriever = null;
        try {
            retriever = new MediaMetadataRetriever();
            retriever.setDataSource(videoPath);
            Bitmap bitmap = retriever.getFrameAtTime();
            return bitmap;
        }finally {
            retriever.release();
        }
    }
    private Bitmap getVideoBitmap2(Uri uri){
        MediaMetadataRetriever retriever = null;
        try {
            retriever = new MediaMetadataRetriever();
            retriever.setDataSource(this,uri);
            Bitmap bitmap = retriever.getFrameAtTime();
            return bitmap;
        }finally {
            retriever.release();
        }
    }
    public void start(View view){
        iv.setVisibility(View.INVISIBLE);
        video.start();
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK){
            if (requestCode == REQUST_VIDEO){
                fl.setVisibility(View.VISIBLE);
                btn_start.setVisibility(View.VISIBLE);
                Uri uri = data.getData();
                video.setVideoURI(uri);
//                Bitmap bitmap = getVideoBitmap(videoPath);
                Bitmap bitmap = getVideoBitmap2(uri);
                iv.setImageBitmap(bitmap);
            }
        }
    }
}

//自定义VideoView
public class CustomVideoView extends VideoView {
    private PlayPauseListener listener;
    public CustomVideoView(Context context) {
        super(context);
    }
    public CustomVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CustomVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public void setPlayPauseListener(PlayPauseListener listener){
        this.listener = listener;
    }
    @Override
    public void pause() {
        super.pause();
        if (listener!=null){
            listener.onPause();
        }
    }
    @Override
    public void start() {
        super.start();
        if (listener!=null){
            listener.onPlay();
        }
    }
    interface PlayPauseListener{
        void onPlay();
        void onPause();
    }
}

最终Intent方式的效果图:

Android视频录制、播放的两种方式

DEMO下载(百度云):

http://pan.baidu.com/s/1c1Nsbqo

提取码:yydc


方式二-MediaRecorder

权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

例子中先用mediarecorder录制保存一个视频然后播放看看效果,点击“跳转”可以调到第二个Main2Activity中,用VideoView播放刚才录制的视频,Main2Activity主要测试如何播放在本地手机的视频。

XML布局:(MainActivity

Android视频录制、播放的两种方式

代码:

 

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{
    private static final String TAG = "MainActivity";
    private SurfaceView mSurfaceview;
    private Button btn_start_or_stop;
    private Button btn_play;
    private Button btn_turnto;
    private boolean isRecording = false;//是否正在录像
    private boolean isPlay = false;//是否正在播放录像
    private MediaRecorder mRecorder;
    private SurfaceHolder mSurfaceHolder;
    private ImageView mImageView;
    private Camera camera;
    private MediaPlayer mediaPlayer;
    private String path;
    private TextView time;
    private int text = 0;

    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            text++;
            time.setText("录制"+text+"秒");
            handler.postDelayed(this,1000);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        mSurfaceview = (SurfaceView) findViewById(R.id.surfaceview);
        mImageView = (ImageView) findViewById(R.id.imageview);
        btn_start_or_stop = (Button) findViewById(R.id.btn_start_or_stop);
        btn_turnto = (Button) findViewById(R.id.btn_turnto);
        btn_play = (Button) findViewById(R.id.btn_play);
        time = (TextView)findViewById(R.id.time);
        btn_turnto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (path != null){
                    File file = new File(path);
                    if(file.exists()){
                        Intent intent = new Intent(MainActivity.this,Main2Activity.class);
                        intent.putExtra("path",path);
                        startActivity(intent);
                    }else {
                        Toast.makeText(MainActivity.this,"视频文件不存在",Toast.LENGTH_SHORT).show();
                    }
                }else {
                    Toast.makeText(MainActivity.this,"文件路径不存在",Toast.LENGTH_SHORT).show();
                }
            }
        });
        btn_start_or_stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlay){
                    if (mediaPlayer != null){
                        isPlay = false;
                        mediaPlayer.stop();
                        mediaPlayer.reset();
                        mediaPlayer.release();
                        mediaPlayer = null;
                    }
                }
                if (!isRecording){
                    handler.postDelayed(runnable,1000);
                    mImageView.setVisibility(View.GONE);
                    if (mRecorder == null){
                        mRecorder = new MediaRecorder();// 创建mediarecorder对象
                        text = 0;//当点击停止之后,每一次进到这里都要重置录制的时间数
                    }
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    if (camera != null){
                        camera.setDisplayOrientation(90);//摄像图旋转90度
                        camera.unlock();
                        mRecorder.setCamera(camera);// 设置录制视频源为Camera(相机)
                    }
                    try{
                        mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); // 这两项需要放在setOutputFormat之前
                        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 这两项需要放在setOutputFormat之前
                        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置录制视频的输出格式
                        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频编码格式
                        mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);//设置视频编码格式// 设置录制的视频编码h263 h264
                        mRecorder.setVideoSize(640,480);//设置视频的分辨率,必须放在设置编码和格式的后面,否则报错
                        mRecorder.setVideoFrameRate(30);//这是设置视频录制的帧率,即1秒钟30帧。。必须放在设置编码和格式的后面,否则报错
                        mRecorder.setVideoEncodingBitRate(4 * 1024 * 1024);//这个属性很重要,这个也直接影响到视频录制的大小,这个设置的越大,视频越清晰
                        mRecorder.setOrientationHint(90);//视频旋转90度
                        mRecorder.setMaxDuration(30 * 1000);//设置录制最长时间为30秒
                        mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());//设置录制视频时的预览画面
                        path = getSdPath();
                        if (path != null){
                            File dir = new File(path + "/recordtest");
                            if (!dir.exists()){
                                dir.mkdir();
                            }
                            path = dir + "/" + getDate() + ".mp4";
                            mRecorder.setOutputFile(path);// 设置视频文件输出的路径
                            mRecorder.prepare();// 准备录制
                            mRecorder.start();// 开始录制
                            isRecording = true;
                            btn_start_or_stop.setText("停止");
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }else {
                    if (isRecording){
                        try {
                            handler.removeCallbacks(runnable);
                            mRecorder.stop();// 停止录制
                            mRecorder.reset();// 恢复到未初始化的状态
                            mRecorder.release();// 释放资源
                            mRecorder = null;
                            btn_start_or_stop.setText("开始");
                            if (camera != null){
                                camera.release();
                                camera = null;
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        isRecording = false;
                    }
                }
            }
        });
        btn_play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isPlay = true;
                mImageView.setVisibility(View.GONE);
                if (mediaPlayer == null){
                    mediaPlayer = new MediaPlayer();
                }
                mediaPlayer.reset();
                Uri uri = Uri.parse(path);
                if (uri == null){
                    Toast.makeText(MainActivity.this,"请先录制视频",Toast.LENGTH_SHORT).show();
                    return;
                }
                mediaPlayer = MediaPlayer.create(MainActivity.this,uri);//使用mediaplayer播放uri视频
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置播放流媒体类型。
                mediaPlayer.setDisplay(mSurfaceHolder);// 设置屏幕
                try{
                    mediaPlayer.prepare();
                }catch (Exception e){
                    e.printStackTrace();
                }
                mediaPlayer.start();
            }
        });
        SurfaceHolder holder = mSurfaceview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!isRecording){
            mImageView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mSurfaceHolder = holder;
    }
    /**
     * 获取系统时间
     *
     * @return
     */
    private static String getDate(){
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        int minute = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR);
        int second = calendar.get(Calendar.SECOND);
        String date = "" + year + (month + 1) + day + hour + minute + second;
        return date;
    }
    /**
     * 获取SD path
     *
     * @return
     */
    public String getSdPath(){
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);//判断sd卡是否存在
        if (sdCardExist){
            sdDir = Environment.getExternalStorageDirectory();//获取根目录
            return sdDir.toString();
        }
        return null;
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder
        mSurfaceHolder = holder;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // surfaceDestroyed的时候同时对象设置为null
        mSurfaceview = null;
        mSurfaceHolder = null;
        handler.removeCallbacks(runnable);
        if (mRecorder != null) {
            mRecorder.release();
            mRecorder = null;
        }
        if (camera != null) {
            camera.release();
            camera = null;
        }
        if (mediaPlayer != null){
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
}

 

效果图:

Android视频录制、播放的两种方式


MAin2Activity

XML布局(MAin2Activity

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="project.wgc.mymediarecordertest01.Main2Activity">
    <VideoView
        android:id="@+id/video"
        android:layout_width="300dp"
        android:layout_height="400dp"
        />
    <Button
        android:id="@+id/btn_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放"/>
</LinearLayout>

Main2Activity代码:

public class Main2Activity extends AppCompatActivity {
    private Button play;
    private VideoView video;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        video = ((VideoView) findViewById(R.id.video));
        Intent intent = getIntent();
        String path = intent.getStringExtra("path");
        //Uri uri = Uri.parse(path);//第一种。把路径转换为uri,然后给videoview设置,
//        video.setVideoURI(uri);
        video.setVideoPath(path);//第二种,直接把本地视频的路径设置给VideoView也可以.
        play = ((Button) findViewById(R.id.btn_play));
        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                video.start();
            }
        });
    }
}

 

效果图:

Android视频录制、播放的两种方式

DEMO下载(百度云):

http://pan.baidu.com/s/1pLPTEPH

提取码:z3ul