Android视频录制功能的实现步骤
官方使用指南请查看Google音频和视频指南
视频录制基本步骤
1.申明权限
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <--如果录制的视频保存在外部SD卡,还需要添加以下权限-> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
注意:RECORD_AUDIO为危险权限,从Android 6.0开始(API级别23)开始,需要动态获取。
2.视频录制参数配置
import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.text.TextUtils; /** * @author Created by LRH * @description 视频录制参数(参数可自行拓展) * @date 2021/1/19 13:54 */ public class VideoRecorderConfig { //Camera private Camera camera; //摄像头预览宽度 private int videoWidth; //摄像头预览高度 private int videoHeight; //摄像头预览偏转角度 private int cameraRotation; //保存的文件路径 private String path; //由于Camera使用的是SurfaceTexture,所以这里使用了SurfaceTexture //也可使用SurfaceHolder private SurfaceTexture mSurfaceTexture; private int cameraId = 0; public SurfaceTexture getSurfaceTexture() { return mSurfaceTexture; } public void setSurfaceTexture(SurfaceTexture surfaceTexture) { mSurfaceTexture = surfaceTexture; } public Camera getCamera() { return camera; } public void setCamera(Camera camera) { this.camera = camera; } public int getVideoWidth() { return videoWidth; } public void setVideoWidth(int videoWidth) { this.videoWidth = videoWidth; } public int getVideoHeight() { return videoHeight; } public void setVideoHeight(int videoHeight) { this.videoHeight = videoHeight; } public int getCameraRotation() { return cameraRotation; } public void setCameraRotation(int cameraRotation) { this.cameraRotation = cameraRotation; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public int getCameraId() { return cameraId; } public void setCameraId(int cameraId) { this.cameraId = cameraId; } public boolean checkParam() { return mSurfaceTexture != null && camera != null && videoWidth > 0 && videoHeight > 0 && !TextUtils.isEmpty(path); } }
3.视频录制接口封装(使用MediaRecorder)
import android.media.CamcorderProfile; import android.media.MediaRecorder; import android.os.Build; import android.view.Surface; import com.emp.yjy.baselib.utils.LogUtils; import java.io.IOException; /** * @author Created by LRH * @description * @date 2021/1/19 13:53 */ public class VideoRecorder { private static final String TAG = "VideoRecord"; private MediaRecorder mRecorder; public VideoRecorder() { } /** * 开始录制 * * @param config * @return */ public boolean startRecord(VideoRecorderConfig config, MediaRecorder.OnErrorListener listener) { if (config == null || !config.checkParam()) { LogUtils.e(TAG, "参数错误"); return false; } if (mRecorder == null) { mRecorder = new MediaRecorder(); } mRecorder.reset(); if (listener != null) { mRecorder.setOnErrorListener(listener); } config.getCamera().unlock(); mRecorder.setCamera(config.getCamera()); //设置音频通道 // mRecorder.setAudioChannels(1); //声音源 // AudioSource.DEFAULT:默认音频来源 // AudioSource.MIC:麦克风(常用) // AudioSource.VOICE_UPLINK:电话上行 // AudioSource.VOICE_DOWNLINK:电话下行 // AudioSource.VOICE_CALL:电话、含上下行 // AudioSource.CAMCORDER:摄像头旁的麦克风 // AudioSource.VOICE_RECOGNITION:语音识别 // AudioSource.VOICE_COMMUNICATION:语音通信 mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); //视频源 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); try { //推荐使用以下代码进行参数配置 CamcorderProfile bestCamcorderProfile = getBestCamcorderProfile(config.getCameraId()); mRecorder.setProfile(bestCamcorderProfile); } catch (Exception e) { //设置输出格式 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); //声音编码格式 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //视频编码格式 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); } //设置视频的长宽 mRecorder.setVideoSize(config.getVideoWidth(), config.getVideoHeight()); // 设置取样帧率 mRecorder.setVideoFrameRate(30); // mRecorder.setAudioEncodingBitRate(44100); // 设置比特率(比特率越高质量越高同样也越大) mRecorder.setVideoEncodingBitRate(800 * 1024); // 这里是调整旋转角度(前置和后置的角度不一样) mRecorder.setOrientationHint(config.getCameraRotation()); // 设置记录会话的最大持续时间(毫秒) mRecorder.setMaxDuration(15 * 1000); //设置输出的文件路径 mRecorder.setOutputFile(config.getPath()); //设置预览对象(可以使用SurfaceHoler代替) mRecorder.setPreviewDisplay(new Surface(config.getSurfaceTexture())); //预处理 try { mRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); return false; } //开始录制 mRecorder.start(); return true; } /** * 停止录制 */ public void stopRecord() { if (mRecorder != null) { try { mRecorder.stop(); mRecorder.reset(); mRecorder.release(); mRecorder = null; } catch (Exception e) { e.printStackTrace(); LogUtils.e(TAG, e.getMessage()); } } } /** * 暂停录制 * * @return */ public boolean pause() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && mRecorder != null) { mRecorder.pause(); return true; } return false; } /** * 继续录制 * * @return */ public boolean resume() { if (mRecorder != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mRecorder.resume(); return true; } return false; } } public CamcorderProfile getBestCamcorderProfile(int cameraID){ CamcorderProfile profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_LOW); if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_480P)){ //对比下面720 这个选择 每帧不是很清晰 profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P); profile.videoBitRate = profile.videoBitRate/5; return profile; } if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P)){ //对比上面480 这个选择 动作大时马赛克!! profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_720P); profile.videoBitRate = profile.videoBitRate/35; return profile; } if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_CIF)){ profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_CIF); return profile; } if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_QVGA)){ profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_QVGA); return profile; } return profile; }
3.使用示例
public void recordVideo(CustomCameraView CameraView) { VideoRecorderConfig config = new VideoRecorderConfig(); String path = App.sGlobalContext.getExternalFilesDir("video").getAbsolutePath() + File.separator + "test1.mp4"; config.setCamera(CameraView.getCamera()); config.setCameraRotation(CameraView.getCameraRotation()); config.setVideoHeight(CameraView.getCameraSize().height); config.setVideoWidth(CameraView.getCameraSize().width); config.setPath(path); config.setSurfaceTexture(CameraView.getSurfaceTexture()); config.setCameraId(0); VideoRecorder record = new VideoRecorder(); boolean start = record.startRecord(config, null); int duration = 15_000; while (duration > 0) { if (duration == 10_000) { boolean pause = record.pause(); LogUtils.e(TAG, "暂停录制" + pause); } if (duration == 5_000) { boolean resume = record.resume(); LogUtils.e(TAG, "重新开始录制" + resume); } SystemClock.sleep(1_000); duration -= 1_000; } record.stopRecord(); LogUtils.d(TAG, "停止录制"); }
其中CustomCameraView
为自己封装的相机库
到此这篇关于Android视频录制功能的实现步骤的文章就介绍到这了,更多相关Android视频录制内容请搜索海外IDC网以前的文章或继续浏览下面的相关文章希望大家以后多多支持海外IDC网!
【转自:http://www.nextecloud.cn/jap.html 欢迎转载】