前提・実現したいこと
kotlinのCamera2 APIでVideo機能を実装しようとしています。
撮影した動画ファイルを、FirebaseStorageに保存します。
発生している問題・エラーメッセージ
エラーもなく、Firebaseコンソール上にもファイルが保存されたのですが、
ファイルの中身を再生してみると、0:00秒の真っ黒な動画しか保存されていません。サイズも最大で6.19KBしかなく、映像の中身だけがないような状態になっています。
該当のソースコード
録画時のボタンアクション。
//ボタンを押したときのアクション 録画スタートとストップ private fun startRecording() { // Record to the external cache directory for visibility val file = File(externalMediaDirs.first(), "${System.currentTimeMillis()}.mp4") recorder = MediaRecorder().apply { setAudioSource(MediaRecorder.AudioSource.MIC) setVideoSource(MediaRecorder.VideoSource.SURFACE); setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) setOutputFile(file.toString()) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) setVideoEncoder(MediaRecorder.VideoEncoder.VP8); try { prepare() start() } catch (e: java.lang.Exception) { } //FirebaseStorageへ アップロード val storageRef = storage.reference val photoRef = storageRef.child("images/${System.currentTimeMillis()}.mp4") val movieUri = Uri.fromFile(file) val uploadTask = photoRef.putFile(movieUri) // Register observers to listen for when the download is done or if it fails uploadTask.addOnFailureListener { Log.e("TAG","ストレージへ保存失敗") }.addOnSuccessListener { Log.e("TAG","ストレージへ保存成功") Log.e("TAG",photoRef.toString()) } } } private fun stopRecording() { recorder?.apply { stop() release() } recorder = null }
openCamera() のコード
fun openCamera(width: Int, height: Int) { val manager: CameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager //CameraIdListのゼロ番目は多くの場合、背面カメラの1倍 val permission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) val permission2 = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) if (permission != PackageManager.PERMISSION_GRANTED) { requestCameraPermission() return } if (permission2 != PackageManager.PERMISSION_GRANTED) { requestRECORD_AUDIOPermission() return } setUpCameraOptions() configureTransform(width, height) //ここにオプションやコンフィグトランスフォームの設定関数入れる? manager.openCamera(cameraId, stateCallback, backgroundHandler); }
openCamera()で使う設定
// ↑ 上のopenCameraの第2引数として利用 ↑ private val stateCallback = object : CameraDevice.StateCallback() { override fun onOpened(cameraDevice: CameraDevice) { this@Camera2Activity.cameraDevice = cameraDevice createCameraPreviewSession() } override fun onDisconnected(cameraDevice: CameraDevice) { cameraDevice.close() this@Camera2Activity.cameraDevice = null } override fun onError(cameraDevice: CameraDevice, error: Int) { onDisconnected(cameraDevice) finish() } } // ↑ 上のstateCallback関数のonOpendで使われるl関数 ↑ private fun createCameraPreviewSession() { val texture = textureView.surfaceTexture texture.setDefaultBufferSize(previewSize.width, previewSize.height) val surface = Surface(texture)//TextureViewからの撮影データの受取先 previewRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) previewRequestBuilder.addTarget(surface) // CameraCaptureSession はカメラから送られてくる画像を受け取ったり、 // 同一セッションで前に受け取った画像の再処理などをするクラスです cameraDevice?.createCaptureSession(Arrays.asList(surface, imageReader?.surface), @RequiresApi(Build.VERSION_CODES.LOLLIPOP) object : CameraCaptureSession.StateCallback() { override fun onConfigured(cameraCaptureSession: CameraCaptureSession) { if (cameraDevice == null) return; captureSession = cameraCaptureSession previewRequestBuilder.set( CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE ) //プレビュー画像を TextureView に送ります previewRequest = previewRequestBuilder.build() captureSession?.setRepeatingRequest( previewRequest, null, null ) } override fun onConfigureFailed(session: CameraCaptureSession) {} }, null ) }
試したこと
setAudioSourceや setVideoSource、エンコーダーの種類など、いろんな種類で切り替えてみましたが、うまくいきませんでした。
エミュレーターをPixel3a API30に変更してみました。
ネットから他のCamera2の実装方法も調べてみましたが、エラーメッセージもないため、どこが問題なのかもよくわかりませんでした。
補足情報(FW/ツールのバージョンなど)
Android Studio 4.0.1
初めての質問です。もし要領を得ない部分がありましたら、申し訳ありません。
お力添えいただければ幸いです。
よろしくお願い致します。
あなたの回答
tips
プレビュー