Android視頻錄制功能的實(shí)現(xiàn)步驟
官方使用指南請(qǐng)查看Google音頻和視頻指南
視頻錄制基本步驟
1.申明權(quán)限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<--如果錄制的視頻保存在外部SD卡,還需要添加以下權(quán)限->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
注意:RECORD_AUDIO為危險(xiǎn)權(quán)限,從Android 6.0開(kāi)始(API級(jí)別23)開(kāi)始,需要?jiǎng)討B(tài)獲取。
2.視頻錄制參數(shù)配置
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.text.TextUtils;
/**
* @author Created by LRH
* @description 視頻錄制參數(shù)(參數(shù)可自行拓展)
* @date 2021/1/19 13:54
*/
public class VideoRecorderConfig {
//Camera
private Camera camera;
//攝像頭預(yù)覽寬度
private int videoWidth;
//攝像頭預(yù)覽高度
private int videoHeight;
//攝像頭預(yù)覽偏轉(zhuǎn)角度
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() {
}
/**
* 開(kāi)始錄制
*
* @param config
* @return
*/
public boolean startRecord(VideoRecorderConfig config, MediaRecorder.OnErrorListener listener) {
if (config == null || !config.checkParam()) {
LogUtils.e(TAG, "參數(shù)錯(cuò)誤");
return false;
}
if (mRecorder == null) {
mRecorder = new MediaRecorder();
}
mRecorder.reset();
if (listener != null) {
mRecorder.setOnErrorListener(listener);
}
config.getCamera().unlock();
mRecorder.setCamera(config.getCamera());
//設(shè)置音頻通道
// mRecorder.setAudioChannels(1);
//聲音源
// AudioSource.DEFAULT:默認(rèn)音頻來(lái)源
// AudioSource.MIC:麥克風(fēng)(常用)
// AudioSource.VOICE_UPLINK:電話上行
// AudioSource.VOICE_DOWNLINK:電話下行
// AudioSource.VOICE_CALL:電話、含上下行
// AudioSource.CAMCORDER:攝像頭旁的麥克風(fēng)
// AudioSource.VOICE_RECOGNITION:語(yǔ)音識(shí)別
// AudioSource.VOICE_COMMUNICATION:語(yǔ)音通信
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
//視頻源
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
try {
//推薦使用以下代碼進(jìn)行參數(shù)配置
CamcorderProfile bestCamcorderProfile = getBestCamcorderProfile(config.getCameraId());
mRecorder.setProfile(bestCamcorderProfile);
} catch (Exception e) {
//設(shè)置輸出格式
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//聲音編碼格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//視頻編碼格式
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
}
//設(shè)置視頻的長(zhǎng)寬
mRecorder.setVideoSize(config.getVideoWidth(), config.getVideoHeight());
// 設(shè)置取樣幀率
mRecorder.setVideoFrameRate(30);
// mRecorder.setAudioEncodingBitRate(44100);
// 設(shè)置比特率(比特率越高質(zhì)量越高同樣也越大)
mRecorder.setVideoEncodingBitRate(800 * 1024);
// 這里是調(diào)整旋轉(zhuǎn)角度(前置和后置的角度不一樣)
mRecorder.setOrientationHint(config.getCameraRotation());
// 設(shè)置記錄會(huì)話的最大持續(xù)時(shí)間(毫秒)
mRecorder.setMaxDuration(15 * 1000);
//設(shè)置輸出的文件路徑
mRecorder.setOutputFile(config.getPath());
//設(shè)置預(yù)覽對(duì)象(可以使用SurfaceHoler代替)
mRecorder.setPreviewDisplay(new Surface(config.getSurfaceTexture()));
//預(yù)處理
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
return false;
}
//開(kāi)始錄制
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;
}
/**
* 繼續(xù)錄制
*
* @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)){
//對(duì)比下面720 這個(gè)選擇 每幀不是很清晰
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P);
profile.videoBitRate = profile.videoBitRate/5;
return profile;
}
if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P)){
//對(duì)比上面480 這個(gè)選擇 動(dòng)作大時(shí)馬賽克!!
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, "重新開(kāi)始錄制" + resume);
}
SystemClock.sleep(1_000);
duration -= 1_000;
}
record.stopRecord();
LogUtils.d(TAG, "停止錄制");
}
其中CustomCameraView為自己封裝的相機(jī)庫(kù)
到此這篇關(guān)于Android視頻錄制功能的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Android視頻錄制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android布局之GridLayout網(wǎng)格布局
網(wǎng)格布局標(biāo)簽是GridLayout。這個(gè)布局是android4.0新增的布局。這個(gè)布局只有4.0之后的版本才能使用。本文給大家介紹Android布局之GridLayout網(wǎng)格布局相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧2015-12-12
如何設(shè)置Android studio 3.0顯示光標(biāo)返回上一次瀏覽位置的箭頭圖標(biāo)
這篇文章主要介紹了如何設(shè)置Android studio 3.0顯示光標(biāo)返回上一次瀏覽位置的箭頭圖標(biāo) 很多朋友反映剛升級(jí)了Android studio 3.0,發(fā)現(xiàn)光標(biāo)返回上一次瀏覽位置的箭頭圖標(biāo)沒(méi)有了,下文給大家介紹的非常詳細(xì),需要的朋友可以參考下2017-11-11
Android使用自定義View實(shí)現(xiàn)餅狀圖的實(shí)例代碼
這篇文章主要介紹了Android使用自定義View實(shí)現(xiàn)餅狀圖的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Android實(shí)現(xiàn)收到新短信后自動(dòng)發(fā)郵件功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)收到新短信后自動(dòng)發(fā)郵件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android 實(shí)現(xiàn)電話來(lái)去自動(dòng)錄音的功能
本文主要介紹Android 電話自動(dòng)錄音功能的開(kāi)發(fā),這里提供實(shí)現(xiàn)代碼和實(shí)現(xiàn)效果圖,有需要的小伙伴可以參考下2016-08-08
Android6.0指紋識(shí)別開(kāi)發(fā)實(shí)例詳解
這篇文章主要介紹了Android6.0指紋識(shí)別開(kāi)發(fā)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
9個(gè)非常棒的Android代碼編輯器 移動(dòng)開(kāi)發(fā)者的最?lèi)?ài)
這篇文章主要為大家分享了9個(gè)非常棒的Android代碼編輯器,據(jù)說(shuō)這可是移動(dòng)開(kāi)發(fā)者的最?lèi)?ài),知道是哪九個(gè)Android代碼編輯器2015-12-12
Android實(shí)現(xiàn)單頁(yè)顯示3個(gè)Item的ViewPager炫酷切換效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)單頁(yè)顯示3個(gè)Item的ViewPager炫酷切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10

