From 643741dc9fbc0f043ac9ade1cec6e6b94bc890c9 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 1 Oct 2022 19:46:53 -0400 Subject: [PATCH] avoid stalling main thread to play video --- .../java/app/grapheneos/camera/TunePlayer.kt | 13 ++- .../camera/capturer/VideoCapturer.kt | 83 +++++++++---------- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/app/grapheneos/camera/TunePlayer.kt b/app/src/main/java/app/grapheneos/camera/TunePlayer.kt index 5b3981a3d..f0ef2e892 100644 --- a/app/src/main/java/app/grapheneos/camera/TunePlayer.kt +++ b/app/src/main/java/app/grapheneos/camera/TunePlayer.kt @@ -3,6 +3,7 @@ package app.grapheneos.camera import android.content.Context import android.media.MediaPlayer import android.net.Uri +import android.os.Handler import android.os.SystemClock import app.grapheneos.camera.ui.activities.MainActivity @@ -48,17 +49,13 @@ class TunePlayer(val context: MainActivity) { shutterPlayer.start() } - fun playVRStartSound() { + fun playVRStartSound(handler: Handler, onPlayed: Runnable) { if (shouldNotPlayTune() || !::vRecPlayer.isInitialized) return vRecPlayer.seekTo(0) vRecPlayer.start() - - // Wait until the audio is played - do { - SystemClock.sleep(10) - } while (vRecPlayer.isPlaying) - // sleep a bit more to make sure the end of this sound isn't captured by the video recorder - SystemClock.sleep(10) + vRecPlayer.setOnCompletionListener({ + handler.postDelayed(onPlayed, 10) + }) } fun playVRStopSound() { diff --git a/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt b/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt index 5a6817a2c..d6769b586 100644 --- a/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt +++ b/app/src/main/java/app/grapheneos/camera/capturer/VideoCapturer.kt @@ -187,58 +187,59 @@ class VideoCapturer(private val mActivity: MainActivity) { } beforeRecordingStarts() - - recording = pendingRecording.start(ctx.mainExecutor) { event -> - if (event is VideoRecordEvent.Finalize) { - afterRecordingStops() - - camConfig.mPlayer.playVRStopSound() - - if (event.hasError()) { - if (event.error == 8) { - ctx.showMessage(R.string.recording_too_short_to_be_saved) - } else { - ctx.showMessage(ctx.getString(R.string.unable_to_save_video_verbose, event.error)) + isRecording = true + camConfig.mPlayer.playVRStartSound(handler, { + startTimer() + recording = pendingRecording.start(ctx.mainExecutor) { event -> + if (event is VideoRecordEvent.Finalize) { + afterRecordingStops() + + camConfig.mPlayer.playVRStopSound() + + if (event.hasError()) { + if (event.error == 8) { + ctx.showMessage(R.string.recording_too_short_to_be_saved) + } else { + ctx.showMessage(ctx.getString(R.string.unable_to_save_video_verbose, event.error)) + } + return@start } - return@start - } - val uri = recordingCtx.uri + val uri = recordingCtx.uri - if (recordingCtx.isPendingMediaStoreUri) { - try { - removePendingFlagFromUri(ctx.contentResolver, uri) - } catch (e: Exception) { - ctx.showMessage(R.string.unable_to_save_video) + if (recordingCtx.isPendingMediaStoreUri) { + try { + removePendingFlagFromUri(ctx.contentResolver, uri) + } catch (e: Exception) { + ctx.showMessage(R.string.unable_to_save_video) + } } - } - if (recordingCtx.shouldAddToGallery) { - val item = CapturedItem(ITEM_TYPE_VIDEO, dateString, uri) - camConfig.updateLastCapturedItem(item) + if (recordingCtx.shouldAddToGallery) { + val item = CapturedItem(ITEM_TYPE_VIDEO, dateString, uri) + camConfig.updateLastCapturedItem(item) - ctx.updateThumbnail() + ctx.updateThumbnail() - if (ctx is SecureMainActivity) { - ctx.capturedItems.add(item) + if (ctx is SecureMainActivity) { + ctx.capturedItems.add(item) + } } - } - if (ctx is VideoCaptureActivity) { - ctx.afterRecording(uri) + if (ctx is VideoCaptureActivity) { + ctx.afterRecording(uri) + } } } - } - - try { - // FileDescriptorOutputOptions doc says that the file descriptor should be closed by the - // caller, and that it's safe to do so as soon as pendingRecording.start() returns - recordingCtx.fileDescriptor.close() - } catch (e: Exception) { - e.printStackTrace() - } - isRecording = true + try { + // FileDescriptorOutputOptions doc says that the file descriptor should be closed by the + // caller, and that it's safe to do so as soon as pendingRecording.start() returns + recordingCtx.fileDescriptor.close() + } catch (e: Exception) { + e.printStackTrace() + } + }) } private val dp16 = 16 * mActivity.resources.displayMetrics.density @@ -250,7 +251,6 @@ class VideoCapturer(private val mActivity: MainActivity) { // TODO: Uncomment this once the main indicator UI gets implemented // mActivity.micOffIcon.visibility = View.GONE - camConfig.mPlayer.playVRStartSound() val gd: GradientDrawable = mActivity.captureButton.drawable as GradientDrawable @@ -283,7 +283,6 @@ class VideoCapturer(private val mActivity: MainActivity) { mActivity.tabLayout.visibility = View.INVISIBLE mActivity.timerView.setText(R.string.start_value_timer) mActivity.timerView.visibility = View.VISIBLE - startTimer() } private fun afterRecordingStops() {