多媒体——视频——使用摄像机录制视频
通过系统自带的摄像机可以很方便地录制视频,只要指定摄像动作为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); // 设置图像视图的位图对象 } } }