既にStackOverFlowにて同様の質問をしておりますが、より多くの方々からご意見をいただきたいため、失礼を承知でこちらでも質問を共有させていただきます。
目的
以下の機能を持ったカメラアプリを作成すること。
1)カメラのプレビューを全画面で表示する。
2)カメラの露光感度、シャッタースピード、フレームレートをシークバーでリアルタイムに変更できる。
3)プレビュー中に端末のLEDライトを点灯できる。
4)ボタンを押したら録画が開始される。録画したデータは端末のメインストレージ直下に保存される。
やったこと
1)2)3)の機能については、すでに実装が完了しています。
4)については、ボタンの設定やパーミッションの設定、録画処理を作成しているのですが、現状うまくいっていません。
コード
文字数の関係でコード全文の共有は割愛します。詳細はマルチリンク先をご参照ください。
該当部分
MainActivity.ktの以下の部分で録画の準備を行なっています。
kotlin
1 // 録画クラスMediaRecorderの初期化 -> MediaRecorderが非推奨になってしまっているが問題ないか 2 @RequiresApi(Build.VERSION_CODES.O) 3 private fun prepareVideoRecorder(): Boolean { 4 // MediaRecorderをインスタンス化 5 recorder = MediaRecorder() 6 cameraManager?.let { cameraDevice -> 7 recorder?.run { 8 setVideoSource(MediaRecorder.VideoSource.CAMERA) // 録画の入力元となるカメラを設定 9 setOutputFormat(MediaRecorder.OutputFormat.DEFAULT) // ビデオのエンコーダを指定 10 setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT) // ファイルフォーマットを指定 11 val dir = Environment.getExternalStorageDirectory() // ディレクトリを取得 12 val file = File.createTempFile("video", ".mp4", dir) // 一時ファイルをディレクトリに保存 13 recorder?.setOutputFile(file.absolutePath) // 出力ファイル名を設定(ランダムな数字を付加) 14 // 録画準備 15 return try { 16 Log.i("start","prepare") 17 prepare() 18 Log.i("finish","prepare") 19 true 20 } catch (e: IllegalStateException) { 21 Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}") 22 releaseMediaRecorder() 23 false 24 } catch (e: IOException) { 25 Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}") 26 releaseMediaRecorder() 27 false 28 } 29 } 30 } 31 return false 32 }
録画の開始、停止は以下の録画ボタンの処理に応じて実行しています。
kotlin
1// 録画ボタンの設定 2 @RequiresApi(Build.VERSION_CODES.O) 3 private fun configRecButton() { 4 // 録画ボタンのイベント登録 5 button_rec = findViewById(R.id.button_rec) 6 button_rec.setOnClickListener { 7 storagePermission() // 外部ストレージへの書き込み許可を取得 8 stateRecButton = !stateRecButton // 値を反転 9 if (stateRecButton){ 10 if (prepareVideoRecorder()) { 11 Log.i("start","record") 12 recorder?.start() 13 } else { 14 releaseMediaRecorder() 15 } 16 } 17 else{ 18 Log.i("stop","stop") 19 recorder?.stop() // stop the recording 20 Log.i("release","release") 21 releaseMediaRecorder() // release the MediaRecorder object 22 } 23 } 24 }
エラー内容
以上のコードを実行すると、以下のエラーが表示されます。
W/Binder:28069_5: type=1400 audit(0.0:850327): avc: denied { read } for name="u:object_r:vendor_camera_prop:s0" dev="tmpfs" ino=18399 scontext=u:r:untrusted_app:s0:c213,c256,c512,c768 tcontext=u:object_r:vendor_camera_prop:s0 tclass=file permissive=0 E/libc: Access denied finding property "persist.vendor.camera.privapp.list" E/libc: Access denied finding property "vendor.camera.aux.packagelist" E/libc: Access denied finding property "vendor.camera.aux.packagelist" E/libc: Access denied finding property "vendor.camera.aux.packagelist" E/libc: Access denied finding property "vendor.camera.aux.packagelist" E/MediaRecorder: start failed: -22 D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main
見たところ、「Access denied finding property」とあり、何かしらのアクセスがうまくいっていないのかと考えています。
カメラのプレビューは表示されておりますので、ストレージへのアクセスで問題が発生しているのかもしれません。
質問内容
確認したところ、prepareを実行したタイミングでエラーが発生しているようなので、設定項目に何か間違いがあるのか、権限の付与がうまくいっていないのだと思いますが、調査をしても明確な原因がわかっていない状態です。
ちなみに、アプリの権限の状態を確認すると、「カメラ」と「ストレージ」の項目はONになっており、権限が付与されていることが確認できております。
私と同じように録画機能を実装する中で同じ問題に直面している例が見当たらず、解決に至れていない状態です。
調査すると、中には似たような例もあるのですが、そこに記載されている内容を試しても解決に至れておりません。
そのため、お手数ですが、コードをご確認の上、どの部分に間違いがあるのかをご指摘いただけますと幸いです。。。
(カメラを使用するため、検証にはandroidの実機が必要になります。)
端末情報
以下の端末で動作の確認をしています。
SHARP AQUOS SHV48(Android 9)
参考にしたサイト
Qiita - Camera2apiを使って動画を撮影する
Qiita - DCIMに保存してギャラリーで表示させる方法
Softbank - 録画アプリの作り方
StackOverFlow - ストレージへのファイルの書き込みがうまくいかない
TECHBOOSTER - MediaRecorderで録画する
Android - camera2での録画サンプル
Android - MediaRecorderについて
StackOverFlow - 同様のエラー内容に関する質問1
GitHub - 同様のエラー内容に関する質問2
TitanWolf - 同様のエラー内容に関する質問3
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。