前言
前段时间,产品大大要求在App上添加一个录制视频的功能,并支持选择相册中的视频、回放和上传。第一时间想到的就是系统的录像功能了。就是通过跳转至相机的录制视频,并保存到指定的路径。
一、录制视频:
录制视频有两种方法:系统相机的录制视频功能和通过安卓自带的MediaRecorder来录制视频,通过Camera来播放,这里主要讲第一种。
首先跳转
String filePath = FileManager.get().getRootFile() + "/msc/" + itemId + ".mp4"; // 保存路径
Uri uri = Uri.fromFile(new File(filePath)); // 将路径转换为Uri对象
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); // 表示跳转至相机的录视频界面
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // MediaStore.EXTRA_VIDEO_QUALITY 表示录制视频的质量,从 0-1,越大表示质量越好,同时视频也越大
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 表示录制完后保存的录制,如果不写,则会保存到默认的路径,在onActivityResult()的回调,通过intent.getData中返回保存的路径
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 30); // 设置视频录制的最长时间
context.startActivityForResult(intent, REQUEST_CODE_RECORD_VIDEO); // 跳转
录制完回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && null != data)
if (requestCode == REQUEST_CODE_RECORD_VIDEO) {
Uri Uri = data.getData(); // 视频的保存路径
}
}
获取视频时长
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(context, uri);
mediaPlayer.prepare();
int duration = mediaPlayer.getDuration() / 1000; // 获取到的是毫秒值
获取视频的第一帧的图片
MediaMetadataRetriever media = new MediaMetadataRetriever();
String videoPath = uri.getPath(); // 通过Uri获取绝对路径
media.setDataSource(videoPath);
Bitmap bitmap = media.getFrameAtTime(); // 视频的第一帧图片
二、选择本地视频:
使用系统的选择本地视频的方法,这里有个坑,就是兼容性问题。
使用ACTION_PICK的方式打开相册在oppo、vivo、华为、小米使用均没问题,但是在魅族和一加都不可以(跳转后的界面无法选择视频)。而魅族手机使用ACTION_OPEN_DOCUMENT方式可以选择视频文件,但是在华为手机(测试用的华为)上则会出现闪退(无法获取到被选中的视频文件的路径)。
出现这些问题主要是不同品牌的手机调取系统图库显示的方法不尽相同,当时我的解决方案就是通过区分不同手机来进行分别兼容。
Intent intent = new Intent();
if("Meizu".equalsIgnoreCase(android.os.Build.MANUFACTURER)){ // 判断用户手机是否是“魅族”。忽略大小写的比较
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("video/*");
}else {
intent.setAction(Intent.ACTION_PICK);
intent.setData(android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
}
context.startActivityForResult(intent, REQUEST_CODE_CHOOSE_VIDEO);
选择视频后回调
public void handleVideoResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && null != data)
if (requestCode == REQUEST_CODE_CHOOSE_VIDEO) {
try {
Uri selectedVideo = data.getData(); // 获取视频的Uri
String[] filePathColumn = {MediaStore.Video.Media.DATA};
cursor = context.getContentResolver().query(selectedVideo,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String path = cursor.getString(columnIndex); // 视频路径
} finally {
if (cursor != null) cursor.close(); // 关闭cursor
}
}
}
选中后,可以获取到视频的各种信息
// 视频ID:MediaStore.Audio.Media._ID
int videoId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
// 视频名称:MediaStore.Audio.Media.TITLE
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
// 视频路径:MediaStore.Audio.Media.DATA
String videoPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
// 视频时长:MediaStore.Audio.Media.DURATION
int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
// 视频大小:MediaStore.Audio.Media.SIZE
long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
// 视频缩略图路径:MediaStore.Images.Media.DATA
String imagePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
// 缩略图ID:MediaStore.Audio.Media._ID
int imageId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));