日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

aac mediarecorder录制_Android音视频录制之MediaRecorder+camera

發布時間:2023/12/16 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aac mediarecorder录制_Android音视频录制之MediaRecorder+camera 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本篇介紹使用Android 中視頻錄制,錄制工具是:

MediaRecorder : 視頻編碼封裝

camera : 視頻畫面原始數據采集

TextureView : 提供預覽畫面

MediaRecorder基本api介紹

MediaRecorder是android中面向應用層的封裝,用于提供便捷的音視頻編碼封裝操作,在使用的過程中要嚴格按照官方指定的生命周期調用順序,即下圖所示的使用步驟

image.png

從圖中可以看出,MediaRecorder的生命周期有以下幾個階段,并且必須按順序執行

initial : 在MediaRecorder被創建(剛new 出來)或者滴啊用reset()方法后,會處于該狀態

initialized : 當調用setAudioSource()或者setVideoSource()后,處于該狀態。這兩個方法主要用于設置音視頻的源配置,通常音頻是麥克風,視頻是攝像頭。該狀態可以通過調用reset()方法回到initial狀態

DataSourceConfigured : 當調用setOutputFormat()方法后,會處于該狀態。該方法主要用于設置輸出的文件格式,可以是音視頻如MP4,也可以是單獨的音頻如mp3。當處于該狀態之后,可以進一步設置音頻和視頻的配置參數,例如音頻封裝格式,采樣率,視頻碼率,幀率等等該狀態可以通過調用reset()方法回到initial狀態

Prepared : 在上面幾個步驟都配置好之后,可以通過調用prepare()方法進入該狀態,只有處于該狀態,才能調用start()

Recording : 通過調用start()方法進入該狀態,該狀態就是真正開始進行視頻錄制編碼的階段,通過調用stop()或者reset()可以回到initial狀態

error狀態 : 當錄制過程中發生次錯誤時,會進入該狀態,調用reset()方法回到initial狀態。

release : 只有在initial狀態才可以通過調用release()方法進入該狀態,釋放所占用的系統資源

編碼的步驟

在開始編碼之前,應該先規劃一下編碼的步驟,因為錄制視頻需要預覽畫面,所以我們肯定需要構建一個預覽的界面,通過camera+TextureView可以實現,音頻不需要預覽。構建好預覽畫面之后,就是開始配置MediaRecorder開始錄制了。

配置Camera

demo只演示后置攝像頭的捕捉,因為使用MediaRecorder進行錄制無法處理幀數據,在切換前置攝像頭之后,視頻會出現左右翻轉的問題,無法通過單純的旋轉解決,暫時還沒找到方法。

camera的配置重點

預覽尺寸,預覽尺寸的寬高比應該盡量和TextureView的寬高比一致,這樣可以保證畫面不變形;

對焦模式,對焦模式一般首選FOCUS_MODE_CONTINUOUS_VIDEO,如果機型不包含,則選擇FOCUS_MODE_CONTINUOUS_PICTURE,如果還不包含,則選擇FOCUS_MODE_AUTO,然后通過手指點擊重新對焦(手指點擊TextureView,調用mCamera.autoFocus(null););

預覽界面旋轉,由于傳感器方向和手機自然方向不一致,所以需要調整預覽界面進行一定的旋轉,旋轉的角度大小可以通過google官方提供的方法計算,查看mCamera.setDisplayOrientation(mRotationDegree);方法源碼查看注釋里有這段代碼(shift/command+鼠標左鍵點擊方法)

示例代碼

/**

* 初始化相機

*/

private void initCamera() {

if (mSurfaceTexture == null) return;

if (mCamera != null) {

releaseCamera();

}

mCamera = Camera.open(mCameraId);

if (mCamera == null) {

Toast.makeText(this, "沒有可用相機", Toast.LENGTH_SHORT).show();

return;

}

try {

mCamera.setPreviewTexture(mSurfaceTexture);

mRotationDegree = CameraUtil.getCameraDisplayOrientation(this, mCameraId);

mCamera.setDisplayOrientation(mRotationDegree);

setCameraParameter(mCamera);

mCamera.startPreview();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 設置相機的參數

*

* @param camera

*/

private void setCameraParameter(Camera camera) {

if (camera == null) return;

Camera.Parameters parameters = camera.getParameters();

//獲取相機支持的>=20fps的幀率,用于設置給MediaRecorder

//因為獲取的數值是*1000的,所以要除以1000

List previewFpsRange = parameters.getSupportedPreviewFpsRange();

for (int[] ints : previewFpsRange) {

if (ints[0] >= 20000) {

mFps = ints[0] / 1000;

break;

}

}

//設置聚焦模式

List focusModes = parameters.getSupportedFocusModes();

if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

} else {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

}

//設置預覽尺寸,因為預覽的尺寸和最終是錄制視頻的尺寸無關,所以我們選取最大的數值

//通常最大的是手機的分辨率,這樣可以讓預覽畫面盡可能清晰并且尺寸不變形,前提是TextureView的尺寸是全屏或者接近全屏

List supportedPreviewSizes = parameters.getSupportedPreviewSizes();

parameters.setPreviewSize(supportedPreviewSizes.get(0).width, supportedPreviewSizes.get(0).height);

//縮短Recording啟動時間

parameters.setRecordingHint(true);

//是否支持影像穩定能力,支持則開啟

if (parameters.isVideoStabilizationSupported())

parameters.setVideoStabilization(true);

camera.setParameters(parameters);

}

配置MediaRecorder

按照生命周期進行每一步的配置,重點關注

編碼參數,配置MediaRecorder的編碼參數有兩種方式;

通過系統提供的CamcorderProfile類,搭配mMediaRecorder.setProfile(profile);方法進行設置,CamcorderProfile對象包含了輸出封裝格式,視頻編碼格式,幀率,碼率,分辨率,音頻采樣率,聲道數,碼率等參數。

示例代碼

/**

* 通過系統的CamcorderProfile設置MediaRecorder的錄制參數

* 首先查看系統是否包含對應質量的封裝參數,然后再設置,根據具體需要的視頻質量進行判斷和設置

*/

private void setProfile() {

CamcorderProfile profile = null;

if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P);

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);

}

if (profile != null) {

mMediaRecorder.setProfile(profile);

}

}

自定義參數,通過profile可以一步到位配置各個參數,但是缺點是沒辦法設置自己想要的視頻清晰度,因為視頻清晰度是根據碼率和分辨率決定的,而每個profile已經固定了碼率和分辨率,所以無法進行調整。這種情況我們就可以自己配置參數。

需要注意

幀率不可以隨便定義,如果系統不支持就會報錯。應該先通過camera獲取支持的幀率,然后再設置。

視頻尺寸的大小,可以根據需要的質量,比如需要高清720的尺寸,那么先獲取系統720p的profile,然后取profile.videoFrameWidth; profile.videoFrameHeight作為輸出寬高。我這里為了方便直接寫了1280:720,大部分手機都尺寸這個參數。

示例代碼

/**

* 自定義MediaRecorder的錄制參數

*/

private void setConfig() {

//設置封裝格式 默認是MP4

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

//音頻編碼

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

//圖像編碼

mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

//聲道

mMediaRecorder.setAudioChannels(1);

//設置最大錄像時間 單位:毫秒

mMediaRecorder.setMaxDuration(60 * 1000);

//設置最大錄制的大小60M 單位,字節

mMediaRecorder.setMaxFileSize(60 * 1024 * 1024);

//再用44.1Hz采樣率

mMediaRecorder.setAudioEncodingBitRate(22050);

//設置幀率,該幀率必須是硬件支持的,可以通過Camera.CameraParameter.getSupportedPreviewFpsRange()方法獲取相機支持的幀率

mMediaRecorder.setVideoFrameRate(mFps);

//設置碼率

mMediaRecorder.setVideoEncodingBitRate(500 * 1024 * 8);

//設置視頻尺寸,通常搭配碼率一起使用,可調整視頻清晰度

mMediaRecorder.setVideoSize(1280, 720);

}

錄制的控制

控制流代碼如下 chronometer是用于計時的

/**

* 開始錄制和停止錄制

*

* @param v

*/

public void control(View v) {

if (mStatus == RecorderStatus.RECORDING) {

stopRecord();

} else {

startRecord();

}

}

/**

* 開始錄制

*/

private void startRecord() {

initCamera();

mCamera.unlock();

initMediaRecorder();

try {

mMediaRecorder.prepare();

mMediaRecorder.start();

} catch (IOException e) {

e.printStackTrace();

}

chronometer.setBase(SystemClock.elapsedRealtime());

chronometer.start();

mStatus = RecorderStatus.RECORDING;

}

/**

* 停止錄制

*/

private void stopRecord() {

releaseMediaRecorder();

releaseCamera();

}

視頻錄制好之后可以在手機目錄aaamedia文件夾下找到,以aaa開頭方便查找!

總結

以上是生活随笔為你收集整理的aac mediarecorder录制_Android音视频录制之MediaRecorder+camera的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。