您的位置:首页 > 移动开发 > Android开发

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

2017-05-18 09:47 691 查看
Android视频录制、播放的两种方式
1、通过Intent的方式:Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
2、使用Camera的API,调用Media的MediaRecorder

Intent的方式
注意:这里播放camera录制的视频使用VideoView,不使用MediaPlayer和SurfaceView的结合。用帧布局Framelayout布局,VideoView和ImageView,播放时隐藏视频缩略图,暂停时或初始化时显示视频缩略图。
因为VideoView没有设置监听播放和暂停状态的事件,所以我自定义一个CustomVideoView继承了VideoView,在里面创建一个监听方法和重写VideoView的播放、暂停的方法。
使用相机intent获取视频是使用最少代码使得你的应用获取视频的捷径.一个视频获取intent可以包含以下额外信息:

MediaStore.EXTRA_OUTPUT-此设置需要一个保存视频的路径和文件名的Uri.此设置是可选的但是强列推荐的.如果你不指定此值,相机应用就把请求到的图像以默认的文件名保存到默认的文件夹下,这些信息保存在返回的intent的Intent.getData()字段中.
MediaStore.EXTRA_VIDEO_QUALITY- 此值在最低质量最小文件尺寸时是0,在最高质量最大文件尺寸时是1.
MediaStore.EXTRA_DURATION_LIMIT-
此值设置获取视频的长度,以秒为单位.
MediaStore.EXTRA_SIZE_LIMIT- 此值设置获取视频文件的大小,以字节为单位.
XML布局视图:



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方式的效果图:



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)



代码:

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;

}

}

}

效果图:



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();

}

});

}

}

效果图:



DEMO下载(百度云):
http://pan.baidu.com/s/1pLPTEPH
提取码:z3ul
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: