多媒体——视频——使用摄像机录制视频

 

 

 

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

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-10-15 13:23  小白龙白龙马  阅读(475)  评论(0编辑  收藏  举报