mirror of
https://github.com/SimpleMobileTools/Simple-Camera.git
synced 2025-02-18 04:10:45 +01: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:
parent
074351b88f
commit
c398370446
@ -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.PERMISSION_WRITE_STORAGE
|
||||||
import com.simplemobiletools.commons.helpers.REFRESH_PATH
|
import com.simplemobiletools.commons.helpers.REFRESH_PATH
|
||||||
import com.simplemobiletools.commons.models.Release
|
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.btn_holder
|
||||||
import kotlinx.android.synthetic.main.activity_main.capture_black_screen
|
import kotlinx.android.synthetic.main.activity_main.capture_black_screen
|
||||||
import kotlinx.android.synthetic.main.activity_main.change_resolution
|
import kotlinx.android.synthetic.main.activity_main.change_resolution
|
||||||
@ -549,6 +550,24 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
updateFlashlightState(flashMode)
|
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) {
|
fun setRecordingState(isRecording: Boolean) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (isRecording) {
|
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.config
|
||||||
import com.simplemobiletools.camera.extensions.toAppFlashMode
|
import com.simplemobiletools.camera.extensions.toAppFlashMode
|
||||||
import com.simplemobiletools.camera.extensions.toCameraXFlashMode
|
import com.simplemobiletools.camera.extensions.toCameraXFlashMode
|
||||||
|
import com.simplemobiletools.camera.helpers.MediaSoundHelper
|
||||||
import com.simplemobiletools.camera.interfaces.MyPreview
|
import com.simplemobiletools.camera.interfaces.MyPreview
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
@ -63,6 +64,7 @@ class CameraXPreview(
|
|||||||
private val config = activity.config
|
private val config = activity.config
|
||||||
private val contentResolver = activity.contentResolver
|
private val contentResolver = activity.contentResolver
|
||||||
private val mainExecutor = activity.mainExecutor
|
private val mainExecutor = activity.mainExecutor
|
||||||
|
private val mediaSoundHelper = MediaSoundHelper()
|
||||||
private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
|
private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
|
||||||
private val orientationEventListener = object : OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL) {
|
private val orientationEventListener = object : OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL) {
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
@ -109,6 +111,7 @@ class CameraXPreview(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
bindToLifeCycle()
|
bindToLifeCycle()
|
||||||
|
mediaSoundHelper.loadSounds()
|
||||||
viewFinder.doOnLayout {
|
viewFinder.doOnLayout {
|
||||||
startCamera()
|
startCamera()
|
||||||
}
|
}
|
||||||
@ -315,6 +318,7 @@ class CameraXPreview(
|
|||||||
.setMetadata(metadata)
|
.setMetadata(metadata)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
||||||
imageCapture.takePicture(outputOptions, mainExecutor, object : OnImageSavedCallback {
|
imageCapture.takePicture(outputOptions, mainExecutor, object : OnImageSavedCallback {
|
||||||
override fun onImageSaved(outputFileResults: OutputFileResults) {
|
override fun onImageSaved(outputFileResults: OutputFileResults) {
|
||||||
listener.toggleBottomButtons(false)
|
listener.toggleBottomButtons(false)
|
||||||
@ -327,6 +331,7 @@ class CameraXPreview(
|
|||||||
Log.e(TAG, "Error", exception)
|
Log.e(TAG, "Error", exception)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
playShutterSoundIfEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initPhotoMode() {
|
override fun initPhotoMode() {
|
||||||
@ -368,15 +373,25 @@ class CameraXPreview(
|
|||||||
.withAudioEnabled()
|
.withAudioEnabled()
|
||||||
.start(mainExecutor) { recordEvent ->
|
.start(mainExecutor) { recordEvent ->
|
||||||
Log.d(TAG, "recordEvent=$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) {
|
is VideoRecordEvent.Status -> {
|
||||||
if (recordEvent.hasError()) {
|
listener.onVideoDurationChanged(recordEvent.recordingStats.recordedDurationNanos)
|
||||||
// TODO: Handle errors
|
}
|
||||||
} else {
|
|
||||||
listener.onMediaCaptured(recordEvent.outputResults.outputUri)
|
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"
|
"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 toggleBottomButtons(hide:Boolean)
|
||||||
fun onMediaCaptured(uri: Uri)
|
fun onMediaCaptured(uri: Uri)
|
||||||
fun onChangeFlashMode(flashMode: Int)
|
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 mCameraToPreviewMatrix = Matrix()
|
||||||
private val mPreviewToCameraMatrix = Matrix()
|
private val mPreviewToCameraMatrix = Matrix()
|
||||||
private val mCameraOpenCloseLock = Semaphore(1)
|
private val mCameraOpenCloseLock = Semaphore(1)
|
||||||
private val mMediaActionSound = MediaActionSound()
|
private val mediaSoundHelper = MediaSoundHelper()
|
||||||
private var mZoomRect: Rect? = null
|
private var mZoomRect: Rect? = null
|
||||||
|
|
||||||
constructor(context: Context) : super(context)
|
constructor(context: Context) : super(context)
|
||||||
@ -114,7 +114,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview {
|
|||||||
|
|
||||||
mUseFrontCamera = false
|
mUseFrontCamera = false
|
||||||
mIsInVideoMode = !initPhotoMode
|
mIsInVideoMode = !initPhotoMode
|
||||||
loadSounds()
|
mediaSoundHelper.loadSounds()
|
||||||
|
|
||||||
val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
|
||||||
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
|
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")
|
@SuppressLint("MissingPermission")
|
||||||
private fun openCamera(width: Int, height: Int) {
|
private fun openCamera(width: Int, height: Int) {
|
||||||
try {
|
try {
|
||||||
@ -576,7 +570,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mActivity.config.isSoundEnabled) {
|
if (mActivity.config.isSoundEnabled) {
|
||||||
mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK)
|
mediaSoundHelper.playShutterSound()
|
||||||
}
|
}
|
||||||
|
|
||||||
mCameraState = STATE_PICTURE_TAKEN
|
mCameraState = STATE_PICTURE_TAKEN
|
||||||
@ -824,7 +818,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview {
|
|||||||
closeCaptureSession()
|
closeCaptureSession()
|
||||||
setupMediaRecorder()
|
setupMediaRecorder()
|
||||||
if (mActivity.config.isSoundEnabled) {
|
if (mActivity.config.isSoundEnabled) {
|
||||||
mMediaActionSound.play(MediaActionSound.START_VIDEO_RECORDING)
|
mediaSoundHelper.playStartVideoRecordingSound()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -853,7 +847,7 @@ class CameraPreview : ViewGroup, TextureView.SurfaceTextureListener, MyPreview {
|
|||||||
private fun stopRecording() {
|
private fun stopRecording() {
|
||||||
mCameraState = STATE_STOPING_RECORDING
|
mCameraState = STATE_STOPING_RECORDING
|
||||||
if (mActivity.config.isSoundEnabled) {
|
if (mActivity.config.isSoundEnabled) {
|
||||||
mMediaActionSound.play(MediaActionSound.STOP_VIDEO_RECORDING)
|
mediaSoundHelper.playStopVideoRecordingSound()
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsRecording = false
|
mIsRecording = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user