序章
Android API は、画像をキャプチャするカメラを制御するための Camera クラスを提供します。api21 以降、Android は Camera2 も提供します。カメラは廃止されましたが、互換性のために、ここでは Camera がまだ使用されています。ビデオを録画するには、 Android 公式 API ドキュメント
に記載されている MediaRecorder を使用できます。
使用
カメラを使用して写真やビデオを撮影する前に、まず許可を申請する必要があります。
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 录音权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 相机模块 -->
<uses-feature android:name="android.hardware.camera"/>
<!-- 自动对焦模块 -->
<uses-feature android:name="android.hardware.camera.autofocus"/>
次に、カメラのプレビュー プロセス:
- Camera.open(int) カメラインスタンスの取得
- setParameters カメラパラメータを設定します
- setDisplayOrientation は正しいプレビューの方向を設定します
- SurfaceViewを関連付けてプレビュー画面を表示する
- startPreview はプレビューを開始し、stopPreview はプレビューを停止します
- release カメラリソースをリリースします
ビデオ録画プロセス:
- オーディオとビデオを記録するための MediaRecorder オブジェクトを作成する
- MediaRecorder とカメラを関連付けて、カメラから画像をキャプチャします
- MediaRecorder関連のパラメータ、ビデオフォーマット、エンコーディング、サイズなどを設定します。
- setOrientationHint はビデオの最終的な回転角度を設定できます
- start 録音を開始、stop 録音を停止
- releaseリリースのリソース
スペースが長くなりすぎることを避けるため、ここではすべてのコードを示しません。詳細なコードについては、github のソース コードを参照してください。
次に、重要なポイントをいくつか挙げます。
ビデオの品質
ビデオの品質はビデオの明瞭さとファイル サイズに直接影響します。これらは個々のニーズに応じて調整でき、ビット レートは小さすぎても大きすぎてもいけません。
/**
* 获取适合的视频质量配置
* 影响视频清晰度和文件大小,根据自身需要调整
* @param cameraID 摄像头ID
*/
fun getBestCamcorderProfile(cameraID: Int): CamcorderProfile? {
var profile: CamcorderProfile? = null
when {
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_1080P) -> {
//1080P,优先
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_1080P)
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P) -> {
//720P
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_720P)
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_480P) -> {
//480P
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P)
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_HIGH) -> {
//高品质
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_HIGH)
profile.videoBitRate /= 8
return profile
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_CIF) -> {
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_CIF)
return profile
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_QVGA) -> {
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_QVGA)
}
CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_LOW) -> {
profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_LOW)
}
}
if (profile != null) {
//视频码率
profile.videoBitRate = 6000000
}
return profile
}
ビデオプレビュー角度
/**
* 根据屏幕方向获取对应预览角度
* setDisplayOrientation只能改变预览的角度,与视频最终结果角度无关
* @param cameraID 相机ID
*/
fun getCameraPreviewOrientation(cameraID: Int, activity: Activity): Int {
val info = Camera.CameraInfo();
Camera.getCameraInfo(cameraID, info);
//屏幕选择角度
val rotation = activity.windowManager.defaultDisplay.rotation
var degrees = 0
when (rotation) {
Surface.ROTATION_0 ->
degrees = 0
Surface.ROTATION_90 ->
degrees = 90
Surface.ROTATION_180 ->
degrees = 180
Surface.ROTATION_270 ->
degrees = 270
}
var result = 90
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360
result = (360 - result) % 360
} else {
result = (info.orientation - degrees + 360) % 360
}
return result;
}
カメラプレビュー
/**
* 初始化相机设置并开启预览
*/
private fun startPreview() {
try {
//开启后置摄像头
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
//设置预览角度
val rotation = CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK,this)
camera?.setDisplayOrientation(rotation)
// 在SurfaceView上预览
camera?.setPreviewDisplay(sv_camera.holder)
val parameters = camera?.getParameters()
//获取支持的预览大小,注意这里获取的宽高是根据横屏的
val sizes = parameters?.supportedPreviewSizes
//宽高建议根据横竖屏切换
val previewSize =
CameraUtil.findFitPreviewSize(sv_camera.height,sv_camera.width,sizes)
if (previewSize != null) {
//设置预览大小
parameters?.setPreviewSize(previewSize.width, previewSize.height)
}
//设置自动对焦模式
CameraUtil.setAutoFocusMode(parameters)
camera?.setParameters(parameters)
//开始预览
camera?.startPreview()
} catch (e: Exception) {
Log.e("Test", "出错了", e)
}
}
ビデオ録画
/**
* 开始录制
* 注意方法调用的先后顺序
*/
private fun startRecorder() {
if (camera == null) {
return
}
if (recorder != null) {
stopRecord()
}
try {
val videoSize = CameraUtil.findFitVideoSize(camera!!.parameters,
sv_camera.height / sv_camera.width.toFloat()
)
//先停止camera预览,释放camera
camera?.stopPreview()
camera?.unlock()
//创建MediaRecorder对象
recorder = MediaRecorder()
//关联camera
recorder?.setCamera(camera)
//设置视频角度;
val rotation =
CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK, this)
recorder?.setOrientationHint(rotation)
//设置预览区域
recorder?.setPreviewDisplay(sv_camera.holder.surface)
//设置音频来源
recorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
//设置视频来源,来自摄像头
recorder?.setVideoSource(MediaRecorder.VideoSource.CAMERA)
//设置输出格式
// recorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
val profile = CameraUtil.getBestCamcorderProfile(Camera.CameraInfo.CAMERA_FACING_BACK)
if (profile != null) {
//设置视频码率
recorder?.setProfile(profile)
}
//设置视频帧率,注意设备支持
recorder?.setVideoFrameRate(30)
//设置视频宽高
recorder?.setVideoSize(videoSize.width, videoSize.height)
val file =
File(getExternalFilesDir(Environment.DIRECTORY_MOVIES)?.absolutePath, "test.mp4")
//设置音频文件的存储位置 {
recorder?.setOutputFile(file.absolutePath)
//准备
recorder?.prepare()
//开始录制
recorder?.start()
ct_time.start()
} catch (e: Exception) {
Log.e("Test", e.message, e)
}
}
以上がCamera+MediaRecordで動画を録画する方法でした!もう終わりにしましょう!ご質問がございましたら、議論の場に上げてください。