mirror of
				https://github.com/SimpleMobileTools/Simple-Camera.git
				synced 2025-06-27 09:02:59 +02:00 
			
		
		
		
	handle playing media sounds
- add MediaSoundHelper to separate logic for playing media action sounds - add support for playing media action sounds (shutter, start and stop recording) in CameraXPreview
This commit is contained in:
		| @@ -39,6 +39,7 @@ import com.simplemobiletools.commons.helpers.PERMISSION_RECORD_AUDIO | ||||
| import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE | ||||
| import com.simplemobiletools.commons.helpers.REFRESH_PATH | ||||
| import com.simplemobiletools.commons.models.Release | ||||
| import java.util.concurrent.TimeUnit | ||||
| import kotlinx.android.synthetic.main.activity_main.btn_holder | ||||
| import kotlinx.android.synthetic.main.activity_main.capture_black_screen | ||||
| import kotlinx.android.synthetic.main.activity_main.change_resolution | ||||
| @@ -549,6 +550,24 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera | ||||
|         updateFlashlightState(flashMode) | ||||
|     } | ||||
|  | ||||
|     override fun onVideoRecordingStarted() { | ||||
|         shutter.setImageResource(R.drawable.ic_video_stop) | ||||
|         toggle_camera.beInvisible() | ||||
|         video_rec_curr_timer.beVisible() | ||||
|     } | ||||
|  | ||||
|     override fun onVideoRecordingStopped() { | ||||
|         shutter.setImageResource(R.drawable.ic_video_rec) | ||||
|         video_rec_curr_timer.text = 0.getFormattedDuration() | ||||
|         video_rec_curr_timer.beGone() | ||||
|         toggle_camera.beVisible() | ||||
|     } | ||||
|  | ||||
|     override fun onVideoDurationChanged(durationNanos: Long) { | ||||
|         val seconds = TimeUnit.NANOSECONDS.toSeconds(durationNanos).toInt() | ||||
|         video_rec_curr_timer.text = seconds.getFormattedDuration() | ||||
|     } | ||||
|  | ||||
|     fun setRecordingState(isRecording: Boolean) { | ||||
|         runOnUiThread { | ||||
|             if (isRecording) { | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| package com.simplemobiletools.camera.helpers | ||||
|  | ||||
| import android.media.MediaActionSound | ||||
|  | ||||
| class MediaSoundHelper { | ||||
|     private val mediaActionSound = MediaActionSound() | ||||
|  | ||||
|     fun loadSounds() { | ||||
|         mediaActionSound.load(MediaActionSound.START_VIDEO_RECORDING) | ||||
|         mediaActionSound.load(MediaActionSound.STOP_VIDEO_RECORDING) | ||||
|         mediaActionSound.load(MediaActionSound.SHUTTER_CLICK) | ||||
|     } | ||||
|  | ||||
|     fun playShutterSound() { | ||||
|         mediaActionSound.play(MediaActionSound.SHUTTER_CLICK) | ||||
|     } | ||||
|  | ||||
|     fun playStartVideoRecordingSound() { | ||||
|         mediaActionSound.play(MediaActionSound.START_VIDEO_RECORDING) | ||||
|     } | ||||
|  | ||||
|     fun playStopVideoRecordingSound() { | ||||
|         mediaActionSound.play(MediaActionSound.STOP_VIDEO_RECORDING) | ||||
|     } | ||||
| } | ||||
| @@ -37,6 +37,7 @@ import com.simplemobiletools.camera.R | ||||
| import com.simplemobiletools.camera.extensions.config | ||||
| import com.simplemobiletools.camera.extensions.toAppFlashMode | ||||
| import com.simplemobiletools.camera.extensions.toCameraXFlashMode | ||||
| import com.simplemobiletools.camera.helpers.MediaSoundHelper | ||||
| import com.simplemobiletools.camera.interfaces.MyPreview | ||||
| import com.simplemobiletools.commons.extensions.showErrorToast | ||||
| import com.simplemobiletools.commons.extensions.toast | ||||
| @@ -63,6 +64,7 @@ class CameraXPreview( | ||||
|     private val config = activity.config | ||||
|     private val contentResolver = activity.contentResolver | ||||
|     private val mainExecutor = activity.mainExecutor | ||||
|     private val mediaSoundHelper = MediaSoundHelper() | ||||
|     private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate() | ||||
|     private val orientationEventListener = object : OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL) { | ||||
|         @SuppressLint("RestrictedApi") | ||||
| @@ -109,6 +111,7 @@ class CameraXPreview( | ||||
|  | ||||
|     init { | ||||
|         bindToLifeCycle() | ||||
|         mediaSoundHelper.loadSounds() | ||||
|         viewFinder.doOnLayout { | ||||
|             startCamera() | ||||
|         } | ||||
| @@ -315,6 +318,7 @@ class CameraXPreview( | ||||
|             .setMetadata(metadata) | ||||
|             .build() | ||||
|  | ||||
|  | ||||
|         imageCapture.takePicture(outputOptions, mainExecutor, object : OnImageSavedCallback { | ||||
|             override fun onImageSaved(outputFileResults: OutputFileResults) { | ||||
|                 listener.toggleBottomButtons(false) | ||||
| @@ -327,6 +331,7 @@ class CameraXPreview( | ||||
|                 Log.e(TAG, "Error", exception) | ||||
|             } | ||||
|         }) | ||||
|         playShutterSoundIfEnabled() | ||||
|     } | ||||
|  | ||||
|     override fun initPhotoMode() { | ||||
| @@ -368,15 +373,25 @@ class CameraXPreview( | ||||
|             .withAudioEnabled() | ||||
|             .start(mainExecutor) { recordEvent -> | ||||
|                 Log.d(TAG, "recordEvent=$recordEvent ") | ||||
|                 if (recordEvent !is VideoRecordEvent.Status) { | ||||
|                     recordingState = recordEvent | ||||
|                 } | ||||
|                 recordingState = recordEvent | ||||
|                 when(recordEvent){ | ||||
|                     is VideoRecordEvent.Start -> { | ||||
|                         playStartVideoRecordingSoundIfEnabled() | ||||
|                         listener.onVideoRecordingStarted() | ||||
|                     } | ||||
|  | ||||
|                 if (recordEvent is VideoRecordEvent.Finalize) { | ||||
|                     if (recordEvent.hasError()) { | ||||
|                         // TODO: Handle errors | ||||
|                     } else { | ||||
|                         listener.onMediaCaptured(recordEvent.outputResults.outputUri) | ||||
|                     is VideoRecordEvent.Status -> { | ||||
|                         listener.onVideoDurationChanged(recordEvent.recordingStats.recordedDurationNanos) | ||||
|                     } | ||||
|  | ||||
|                     is VideoRecordEvent.Finalize -> { | ||||
|                         playStopVideoRecordingSoundIfEnabled() | ||||
|                         listener.onVideoRecordingStopped() | ||||
|                         if (recordEvent.hasError()) { | ||||
|                             // TODO: Handle errors | ||||
|                         } else { | ||||
|                             listener.onMediaCaptured(recordEvent.outputResults.outputUri) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @@ -391,4 +406,22 @@ class CameraXPreview( | ||||
|             "VID_$timestamp" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun playShutterSoundIfEnabled(){ | ||||
|         if(config.isSoundEnabled){ | ||||
|             mediaSoundHelper.playShutterSound() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun playStartVideoRecordingSoundIfEnabled(){ | ||||
|         if(config.isSoundEnabled){ | ||||
|             mediaSoundHelper.playStartVideoRecordingSound() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun playStopVideoRecordingSoundIfEnabled(){ | ||||
|         if(config.isSoundEnabled){ | ||||
|             mediaSoundHelper.playStopVideoRecordingSound() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -10,4 +10,7 @@ interface CameraXPreviewListener { | ||||
|     fun toggleBottomButtons(hide:Boolean) | ||||
|     fun onMediaCaptured(uri: Uri) | ||||
|     fun onChangeFlashMode(flashMode: Int) | ||||
|     fun onVideoRecordingStarted() | ||||
|     fun onVideoRecordingStopped() | ||||
|     fun onVideoDurationChanged(durationNanos: Long) | ||||
| } | ||||
|   | ||||
| @@ -96,7 +96,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|     private val mCameraToPreviewMatrix = Matrix() | ||||
|     private val mPreviewToCameraMatrix = Matrix() | ||||
|     private val mCameraOpenCloseLock = Semaphore(1) | ||||
|     private val mMediaActionSound = MediaActionSound() | ||||
|     private val mediaSoundHelper = MediaSoundHelper() | ||||
|     private var mZoomRect: Rect? = null | ||||
|  | ||||
|     constructor(context: Context) : super(context) | ||||
| @@ -114,7 +114,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|  | ||||
|         mUseFrontCamera = false | ||||
|         mIsInVideoMode = !initPhotoMode | ||||
|         loadSounds() | ||||
|         mediaSoundHelper.loadSounds() | ||||
|  | ||||
|         val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { | ||||
|             override fun onSingleTapConfirmed(e: MotionEvent?): Boolean { | ||||
| @@ -182,12 +182,6 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun loadSounds() { | ||||
|         mMediaActionSound.load(MediaActionSound.START_VIDEO_RECORDING) | ||||
|         mMediaActionSound.load(MediaActionSound.STOP_VIDEO_RECORDING) | ||||
|         mMediaActionSound.load(MediaActionSound.SHUTTER_CLICK) | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("MissingPermission") | ||||
|     private fun openCamera(width: Int, height: Int) { | ||||
|         try { | ||||
| @@ -576,7 +570,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|             } | ||||
|  | ||||
|             if (mActivity.config.isSoundEnabled) { | ||||
|                 mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK) | ||||
|                 mediaSoundHelper.playShutterSound() | ||||
|             } | ||||
|  | ||||
|             mCameraState = STATE_PICTURE_TAKEN | ||||
| @@ -824,7 +818,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|         closeCaptureSession() | ||||
|         setupMediaRecorder() | ||||
|         if (mActivity.config.isSoundEnabled) { | ||||
|             mMediaActionSound.play(MediaActionSound.START_VIDEO_RECORDING) | ||||
|             mediaSoundHelper.playStartVideoRecordingSound() | ||||
|         } | ||||
|  | ||||
|         try { | ||||
| @@ -853,7 +847,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview { | ||||
|     private fun stopRecording() { | ||||
|         mCameraState = STATE_STOPING_RECORDING | ||||
|         if (mActivity.config.isSoundEnabled) { | ||||
|             mMediaActionSound.play(MediaActionSound.STOP_VIDEO_RECORDING) | ||||
|             mediaSoundHelper.playStopVideoRecordingSound() | ||||
|         } | ||||
|  | ||||
|         mIsRecording = false | ||||
|   | ||||
		Reference in New Issue
	
	Block a user