![](https://i-blog.csdnimg.cn/blog_migrate/282d80b435fa7a532fe0ccb40f7a41f4.png)
通过系统自带的摄像机可以很方便地录制视频,只要指定摄像动作为MediaStore.ACTION_VIDEO_CAPTURE即可。
当然,需要事先设定下列的录像参数:
1、MediaStore.EXTRA_VIDEO_QUALITY:用于设定视频质量;2、MediaStore.EXTRA_SIZE_LIMIT:用于设定文件大小的上限;3、MediaStore.EXTRA_DURATION_LIMIT:用于设定视频时长的上限。
// 获取视频文件中的某帧图片
public static Bitmap getOneFrame(Context ctx, Uri uri)
{
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(ctx, uri);
// 获得视频的播放时长,大于1秒的取第1秒的帧图,不足1秒的取第0秒的帧图
String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
int pos = (Integer.parseInt(duration)/1000)>1 ? 1 : 0;
// 获取并返回指定时间的帧图
return retriever.getFrameAtTime(pos * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
}
===========================================================================================================
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_recorder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开摄像机"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_video"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:textColor="@color/black"
android:textSize="17sp" />
<RelativeLayout
android:id="@+id/rl_video"
android:layout_width="match_parent"
android:layout_height="300dp"
android:visibility="gone">
<ImageView
android:id="@+id/iv_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/play_video" />
</RelativeLayout>
</LinearLayout>
MediaUtil
package com.example.myapplication.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import java.io.File;
@SuppressLint("DefaultLocale")
public class MediaUtil {
private final static String TAG = "MediaUtil";
// 格式化播放时长(mm:ss)
public static String formatDuration(int milliseconds) {
int seconds = milliseconds / 1000;
int hour = seconds / 3600;
int minute = seconds / 60;
int second = seconds % 60;
String str;
if (hour > 0) {
str = String.format("%02d:%02d:%02d", hour, minute, second);
} else {
str = String.format("%02d:%02d", minute, second);
}
return str;
}
// 获得音视频文件的缓存路径
public static String getRecordFilePath(Context context, String dir_name, String extend_name) {
String path = "";
File recordDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + dir_name + "/");
if (!recordDir.exists()) {
recordDir.mkdirs();
}
try {
File recordFile = File.createTempFile(DateUtil.getNowDateTime(), extend_name, recordDir);
path = recordFile.getAbsolutePath();
Log.d(TAG, "dir_name=" + dir_name + ", extend_name=" + extend_name + ", path=" + path);
} catch (Exception e) {
e.printStackTrace();
}
return path;
}
// 获取视频文件中的某帧图片
public static Bitmap getOneFrame(Context ctx, Uri uri) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(ctx, uri);
// 获得视频的播放时长,大于1秒的取第1秒处的帧图,不足1秒的取第0秒处的帧图
String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
Log.d(TAG, "duration="+duration);
int pos = (Integer.parseInt(duration)/1000)>1 ? 1 : 0;
// 获取指定时间的帧图,注意getFrameAtTime方法的时间单位是微秒
return retriever.getFrameAtTime(pos * 1000 * 1000);
}
}
主代码:
package com.example.myapplication;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapplication.util.MediaUtil;
public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
private final static String TAG = "VideoRecordActivity";
private int RECORDER_CODE = 1; // 录制操作的请求码
private TextView tv_video;
private RelativeLayout rl_video;
private ImageView iv_video;
private Uri mVideoUri; // 视频文件的路径对象
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_video = findViewById(R.id.tv_video);
rl_video = findViewById(R.id.rl_video);
iv_video = findViewById(R.id.iv_video);
findViewById(R.id.btn_recorder).setOnClickListener(this);
findViewById(R.id.rl_video).setOnClickListener(this);
}
@Override
public void onClick(View v)
{
if (v.getId() == R.id.btn_recorder)
{
// 下面准备跳到系统的摄像机,并获得录制完的视频文件
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // 视频质量。0 低质量;1 高质量
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10485760L); // 大小限制,单位字节
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10); // 时长限制,单位秒
startActivityForResult(intent, RECORDER_CODE); // 打开系统摄像机
}
else if (v.getId() == R.id.rl_video)
{
// 创建一个内容获取动作的意图(准备跳到系统播放器)
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(mVideoUri, "video/*"); // 类型为视频
startActivity(intent); // 打开系统的视频播放器
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode==RESULT_OK && requestCode==RECORDER_CODE) // 从摄像机返回
{
mVideoUri = intent.getData(); // 获得已录制视频的路径对象
// // 生成临时视频的保存路径
// String filePath = String.format("%s/%s.mp4",
// getExternalFilesDir(Environment.DIRECTORY_MOVIES), "video_"+ DateUtil.getNowDateTime());
// // 把录制完的视频保存到临时路径
// FileUtil.saveFileFromUri(this, mVideoUri, filePath);
tv_video.setText("录制完成的视频地址为:"+mVideoUri.toString());
rl_video.setVisibility(View.VISIBLE);
// 获取视频文件的某帧图片
Bitmap bitmap = MediaUtil.getOneFrame(this, mVideoUri);
iv_video.setImageBitmap(bitmap); // 设置图像视图的位图对象
}
}
}