mirror of
https://github.com/SimpleMobileTools/Simple-Camera.git
synced 2025-06-27 09:02:59 +02:00
handle countdown timer sounds
This commit is contained in:
@ -53,6 +53,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
const val PHOTO_MODE_INDEX = 1
|
const val PHOTO_MODE_INDEX = 1
|
||||||
const val VIDEO_MODE_INDEX = 0
|
const val VIDEO_MODE_INDEX = 0
|
||||||
private const val MIN_SWIPE_DISTANCE_X = 100
|
private const val MIN_SWIPE_DISTANCE_X = 100
|
||||||
|
private const val TIMER_2_SECONDS = 2001
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var defaultScene: Scene
|
private lateinit var defaultScene: Scene
|
||||||
@ -60,6 +61,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
private lateinit var timerScene: Scene
|
private lateinit var timerScene: Scene
|
||||||
private lateinit var mOrientationEventListener: OrientationEventListener
|
private lateinit var mOrientationEventListener: OrientationEventListener
|
||||||
private lateinit var mFocusCircleView: FocusCircleView
|
private lateinit var mFocusCircleView: FocusCircleView
|
||||||
|
private lateinit var mediaSoundHelper: MediaSoundHelper
|
||||||
private var mPreview: MyPreview? = null
|
private var mPreview: MyPreview? = null
|
||||||
private var mediaSizeToggleGroup: MaterialButtonToggleGroup? = null
|
private var mediaSizeToggleGroup: MaterialButtonToggleGroup? = null
|
||||||
private var mPreviewUri: Uri? = null
|
private var mPreviewUri: Uri? = null
|
||||||
@ -172,6 +174,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
mPreview = null
|
mPreview = null
|
||||||
|
mediaSoundHelper.release()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
@ -182,6 +185,8 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
|
|
||||||
private fun initVariables() {
|
private fun initVariables() {
|
||||||
mIsHardwareShutterHandled = false
|
mIsHardwareShutterHandled = false
|
||||||
|
mediaSoundHelper = MediaSoundHelper(this)
|
||||||
|
mediaSoundHelper.loadSounds()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||||
@ -321,6 +326,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
mPreview = CameraXInitializer(this).createCameraXPreview(
|
mPreview = CameraXInitializer(this).createCameraXPreview(
|
||||||
preview_view,
|
preview_view,
|
||||||
listener = this,
|
listener = this,
|
||||||
|
mediaSoundHelper = mediaSoundHelper,
|
||||||
outputUri = outputUri,
|
outputUri = outputUri,
|
||||||
isThirdPartyIntent = isThirdPartyIntent,
|
isThirdPartyIntent = isThirdPartyIntent,
|
||||||
initInPhotoMode = isInPhotoMode,
|
initInPhotoMode = isInPhotoMode,
|
||||||
@ -487,6 +493,7 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelTimer() {
|
private fun cancelTimer() {
|
||||||
|
mediaSoundHelper.stopTimerCountdown2SecondsSound()
|
||||||
countDownTimer?.cancel()
|
countDownTimer?.cancel()
|
||||||
countDownTimer = null
|
countDownTimer = null
|
||||||
resetViewsOnTimerFinish()
|
resetViewsOnTimerFinish()
|
||||||
@ -855,10 +862,19 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
|
|||||||
hideViewsOnTimerStart()
|
hideViewsOnTimerStart()
|
||||||
shutter.setImageState(intArrayOf(R.attr.state_timer_cancel), true)
|
shutter.setImageState(intArrayOf(R.attr.state_timer_cancel), true)
|
||||||
timer_text.beVisible()
|
timer_text.beVisible()
|
||||||
|
var playSound = true
|
||||||
countDownTimer = object : CountDownTimer(timerMode.millisInFuture, 1000) {
|
countDownTimer = object : CountDownTimer(timerMode.millisInFuture, 1000) {
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
val seconds = (TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) + 1).toString()
|
val seconds = (TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) + 1).toString()
|
||||||
timer_text.setText(seconds)
|
timer_text.setText(seconds)
|
||||||
|
if (playSound && config.isSoundEnabled) {
|
||||||
|
if (millisUntilFinished <= TIMER_2_SECONDS) {
|
||||||
|
mediaSoundHelper.playTimerCountdown2SecondsSound()
|
||||||
|
playSound = false
|
||||||
|
} else {
|
||||||
|
mediaSoundHelper.playTimerCountdownSound()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
|
@ -8,6 +8,8 @@ import android.net.Uri
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.annotation.RawRes
|
||||||
|
import com.simplemobiletools.camera.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,59 +17,59 @@ import java.io.File
|
|||||||
*/
|
*/
|
||||||
class MediaActionSound(private val context: Context) {
|
class MediaActionSound(private val context: Context) {
|
||||||
companion object {
|
companion object {
|
||||||
|
val SHUTTER_CLICK = MediaSound.ManufacturerSound("camera_click.ogg")
|
||||||
|
val FOCUS_COMPLETE = MediaSound.ManufacturerSound("camera_focus.ogg")
|
||||||
|
val START_VIDEO_RECORDING = MediaSound.ManufacturerSound("VideoRecord.ogg")
|
||||||
|
val STOP_VIDEO_RECORDING = MediaSound.ManufacturerSound("VideoStop.ogg")
|
||||||
|
val TIMER_COUNTDOWN = MediaSound.RawResSound(R.raw.beep)
|
||||||
|
val TIMER_COUNTDOWN_2_SECONDS = MediaSound.RawResSound(R.raw.beep_2_secs)
|
||||||
|
|
||||||
private const val NUM_MEDIA_SOUND_STREAMS = 1
|
private const val NUM_MEDIA_SOUND_STREAMS = 1
|
||||||
private val SOUND_DIRS = arrayOf(
|
private val SOUND_DIRS = arrayOf(
|
||||||
"/product/media/audio/ui/",
|
"/product/media/audio/ui/", "/system/media/audio/ui/"
|
||||||
"/system/media/audio/ui/"
|
|
||||||
)
|
|
||||||
private val SOUND_FILES = arrayOf(
|
|
||||||
"camera_click.ogg",
|
|
||||||
"camera_focus.ogg",
|
|
||||||
"VideoRecord.ogg",
|
|
||||||
"VideoStop.ogg"
|
|
||||||
)
|
)
|
||||||
private const val TAG = "MediaActionSound"
|
private const val TAG = "MediaActionSound"
|
||||||
const val SHUTTER_CLICK = 0
|
|
||||||
const val FOCUS_COMPLETE = 1
|
|
||||||
const val START_VIDEO_RECORDING = 2
|
|
||||||
const val STOP_VIDEO_RECORDING = 3
|
|
||||||
private const val STATE_NOT_LOADED = 0
|
private const val STATE_NOT_LOADED = 0
|
||||||
private const val STATE_LOADING = 1
|
private const val STATE_LOADING = 1
|
||||||
private const val STATE_LOADING_PLAY_REQUESTED = 2
|
private const val STATE_LOADING_PLAY_REQUESTED = 2
|
||||||
private const val STATE_LOADED = 3
|
private const val STATE_LOADED = 3
|
||||||
|
private val SOUNDS = arrayOf(SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, STOP_VIDEO_RECORDING, TIMER_COUNTDOWN, TIMER_COUNTDOWN_2_SECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SoundState(val name: Int) {
|
sealed class MediaSound {
|
||||||
var id = 0 // 0 is an invalid sample ID.
|
class ManufacturerSound(val fileName: String, var path: String = "") : MediaSound()
|
||||||
|
class RawResSound(@RawRes val resId: Int) : MediaSound()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SoundState(
|
||||||
|
val mediaSound: MediaSound,
|
||||||
|
// 0 is an invalid sample ID.
|
||||||
|
var loadId: Int = 0,
|
||||||
|
var streamId: Int = 0,
|
||||||
var state: Int = STATE_NOT_LOADED
|
var state: Int = STATE_NOT_LOADED
|
||||||
var path: String? = null
|
)
|
||||||
}
|
|
||||||
|
|
||||||
private var soundPool: SoundPool? = SoundPool.Builder()
|
private var soundPool: SoundPool? = SoundPool.Builder().setMaxStreams(NUM_MEDIA_SOUND_STREAMS).setAudioAttributes(
|
||||||
.setMaxStreams(NUM_MEDIA_SOUND_STREAMS)
|
AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
|
||||||
.setAudioAttributes(
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build()
|
||||||
AudioAttributes.Builder()
|
).build()
|
||||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
|
||||||
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
|
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
|
||||||
.build()
|
|
||||||
).build()
|
|
||||||
private var mediaPlayer: MediaPlayer? = null
|
private var mediaPlayer: MediaPlayer? = null
|
||||||
private var playCompletionRunnable: Runnable? = null
|
private var playCompletionRunnable: Runnable? = null
|
||||||
|
|
||||||
private val mSounds: Array<SoundState?> = arrayOfNulls(SOUND_FILES.size)
|
private val sounds = SOUNDS.map { SoundState(it) }
|
||||||
|
|
||||||
private val playTimeHandler = Handler(Looper.getMainLooper())
|
private val playTimeHandler = Handler(Looper.getMainLooper())
|
||||||
private val mLoadCompleteListener = SoundPool.OnLoadCompleteListener { _, sampleId, status ->
|
private val mLoadCompleteListener = SoundPool.OnLoadCompleteListener { _, sampleId, status ->
|
||||||
for (sound in mSounds) {
|
for (sound in sounds) {
|
||||||
if (sound!!.id != sampleId) {
|
if (sound.loadId != sampleId) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var soundToBePlayed: SoundState? = null
|
var soundToBePlayed: SoundState? = null
|
||||||
synchronized(sound) {
|
synchronized(sound) {
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
sound.state = STATE_NOT_LOADED
|
sound.state = STATE_NOT_LOADED
|
||||||
sound.id = 0
|
sound.loadId = 0
|
||||||
Log.e(TAG, "OnLoadCompleteListener() error: $status loading sound: ${sound.name}")
|
Log.e(TAG, "OnLoadCompleteListener() error: $status loading sound: ${sound.mediaSound}")
|
||||||
return@OnLoadCompleteListener
|
return@OnLoadCompleteListener
|
||||||
}
|
}
|
||||||
when (sound.state) {
|
when (sound.state) {
|
||||||
@ -76,11 +78,11 @@ class MediaActionSound(private val context: Context) {
|
|||||||
soundToBePlayed = sound
|
soundToBePlayed = sound
|
||||||
sound.state = STATE_LOADED
|
sound.state = STATE_LOADED
|
||||||
}
|
}
|
||||||
else -> Log.e(TAG, "OnLoadCompleteListener() called in wrong state: ${sound.state} for sound: ${sound.name}")
|
else -> Log.e(TAG, "OnLoadCompleteListener() called in wrong state: ${sound.state} for sound: ${sound.mediaSound}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (soundToBePlayed != null) {
|
if (soundToBePlayed != null) {
|
||||||
playSoundPool(soundToBePlayed!!)
|
playWithSoundPool(soundToBePlayed!!)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -88,89 +90,113 @@ class MediaActionSound(private val context: Context) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
soundPool!!.setOnLoadCompleteListener(mLoadCompleteListener)
|
soundPool!!.setOnLoadCompleteListener(mLoadCompleteListener)
|
||||||
for (i in mSounds.indices) {
|
|
||||||
mSounds[i] = SoundState(i)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSound(sound: SoundState?): Int {
|
private fun loadSound(sound: SoundState): Int {
|
||||||
val soundFileName = SOUND_FILES[sound!!.name]
|
var id = 0
|
||||||
for (soundDir in SOUND_DIRS) {
|
when (val mediaSound = sound.mediaSound) {
|
||||||
val soundPath = soundDir + soundFileName
|
is MediaSound.ManufacturerSound -> {
|
||||||
sound.path = soundPath
|
for (soundDir in SOUND_DIRS) {
|
||||||
val id = soundPool!!.load(soundPath, 1)
|
val soundPath = soundDir + mediaSound.fileName
|
||||||
if (id > 0) {
|
mediaSound.path = soundPath
|
||||||
sound.state = STATE_LOADING
|
id = soundPool!!.load(soundPath, 1)
|
||||||
sound.id = id
|
break
|
||||||
return id
|
}
|
||||||
|
}
|
||||||
|
is MediaSound.RawResSound -> {
|
||||||
|
id = soundPool!!.load(context, mediaSound.resId, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id > 0) {
|
||||||
|
sound.state = STATE_LOADING
|
||||||
|
sound.loadId = id
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun load(soundName: Int) {
|
fun load(mediaSound: MediaSound) {
|
||||||
if (soundName < 0 || soundName >= SOUND_FILES.size) {
|
val sound = sounds.first { it.mediaSound == mediaSound }
|
||||||
throw RuntimeException("Unknown sound requested: $soundName")
|
synchronized(sound) {
|
||||||
}
|
|
||||||
val sound = mSounds[soundName]
|
|
||||||
synchronized(sound!!) {
|
|
||||||
when (sound.state) {
|
when (sound.state) {
|
||||||
STATE_NOT_LOADED -> {
|
STATE_NOT_LOADED -> {
|
||||||
loadSound(sound).let { soundId ->
|
loadSound(sound).let { soundId ->
|
||||||
if (soundId <= 0) {
|
if (soundId <= 0) {
|
||||||
Log.e(TAG, "load() error loading sound: $soundName")
|
Log.e(TAG, "load() error loading sound: $mediaSound")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> Log.e(TAG, "load() called in wrong state: $sound for sound: $soundName")
|
else -> Log.e(TAG, "load() called in wrong state: $sound for sound: $mediaSound")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun play(soundName: Int, onPlayComplete: (() -> Unit)? = null) {
|
fun play(mediaSound: MediaSound, onPlayComplete: (() -> Unit)? = null) {
|
||||||
if (soundName < 0 || soundName >= SOUND_FILES.size) {
|
|
||||||
throw RuntimeException("Unknown sound requested: $soundName")
|
|
||||||
}
|
|
||||||
removeHandlerCallbacks()
|
removeHandlerCallbacks()
|
||||||
if (onPlayComplete != null) {
|
if (onPlayComplete != null) {
|
||||||
playCompletionRunnable = Runnable {
|
playCompletionRunnable = Runnable {
|
||||||
onPlayComplete.invoke()
|
onPlayComplete.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val sound = mSounds[soundName]
|
val sound = sounds.first { it.mediaSound == mediaSound }
|
||||||
synchronized(sound!!) {
|
synchronized(sound) {
|
||||||
when (sound.state) {
|
when (sound.state) {
|
||||||
STATE_NOT_LOADED -> {
|
STATE_NOT_LOADED -> {
|
||||||
val soundId = loadSound(sound)
|
val soundId = loadSound(sound)
|
||||||
if (soundId <= 0) {
|
if (soundId <= 0) {
|
||||||
Log.e(TAG, "play() error loading sound: $soundName")
|
Log.e(TAG, "play() error loading sound: $mediaSound")
|
||||||
} else {
|
} else {
|
||||||
sound.state = STATE_LOADING_PLAY_REQUESTED
|
sound.state = STATE_LOADING_PLAY_REQUESTED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STATE_LOADING -> sound.state = STATE_LOADING_PLAY_REQUESTED
|
STATE_LOADING -> sound.state = STATE_LOADING_PLAY_REQUESTED
|
||||||
STATE_LOADED -> {
|
STATE_LOADED -> {
|
||||||
playSoundPool(sound)
|
playWithSoundPool(sound)
|
||||||
}
|
}
|
||||||
else -> Log.e(TAG, "play() called in wrong state: ${sound.state} for sound: $soundName")
|
else -> Log.e(TAG, "play() called in wrong state: ${sound.state} for sound: $mediaSound")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playSoundPool(sound: SoundState) {
|
private fun playWithSoundPool(sound: SoundState) {
|
||||||
if (playCompletionRunnable != null) {
|
if (playCompletionRunnable != null) {
|
||||||
val duration = getSoundDuration(sound.path!!)
|
val duration = getSoundDuration(sound.mediaSound)
|
||||||
playTimeHandler.postDelayed(playCompletionRunnable!!, duration)
|
playTimeHandler.postDelayed(playCompletionRunnable!!, duration)
|
||||||
}
|
}
|
||||||
soundPool!!.play(sound.id, 1.0f, 1.0f, 0, 0, 1.0f)
|
val streamId = soundPool!!.play(sound.loadId, 1.0f, 1.0f, 0, 0, 1.0f)
|
||||||
|
sound.streamId = streamId
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSoundDuration(mediaSound: MediaSound): Long {
|
||||||
|
releaseMediaPlayer()
|
||||||
|
mediaPlayer = when (mediaSound) {
|
||||||
|
is MediaSound.ManufacturerSound -> MediaPlayer.create(context, Uri.fromFile(File(mediaSound.path)))
|
||||||
|
is MediaSound.RawResSound -> MediaPlayer.create(context, mediaSound.resId)
|
||||||
|
}
|
||||||
|
return mediaPlayer!!.duration.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop(mediaSound: MediaSound) {
|
||||||
|
val sound = sounds.first { it.mediaSound == mediaSound }
|
||||||
|
synchronized(sound) {
|
||||||
|
when (sound.state) {
|
||||||
|
STATE_LOADED -> {
|
||||||
|
soundPool!!.stop(sound.streamId)
|
||||||
|
}
|
||||||
|
else -> Log.w(TAG, "stop() should be called after sound is loaded for sound: $mediaSound")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun release() {
|
fun release() {
|
||||||
if (soundPool != null) {
|
if (soundPool != null) {
|
||||||
for (sound in mSounds) {
|
for (sound in sounds) {
|
||||||
synchronized(sound!!) {
|
synchronized(sound) {
|
||||||
sound.state = STATE_NOT_LOADED
|
sound.state = STATE_NOT_LOADED
|
||||||
sound.id = 0
|
sound.loadId = 0
|
||||||
|
sound.streamId = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
soundPool?.release()
|
soundPool?.release()
|
||||||
@ -189,10 +215,4 @@ class MediaActionSound(private val context: Context) {
|
|||||||
mediaPlayer?.release()
|
mediaPlayer?.release()
|
||||||
mediaPlayer = null
|
mediaPlayer = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSoundDuration(soundPath: String): Long {
|
|
||||||
releaseMediaPlayer()
|
|
||||||
mediaPlayer = MediaPlayer.create(context, Uri.fromFile(File(soundPath)))
|
|
||||||
return mediaPlayer!!.duration.toLong()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ class MediaSoundHelper(context: Context) {
|
|||||||
mediaActionSound.load(MediaActionSound.START_VIDEO_RECORDING)
|
mediaActionSound.load(MediaActionSound.START_VIDEO_RECORDING)
|
||||||
mediaActionSound.load(MediaActionSound.STOP_VIDEO_RECORDING)
|
mediaActionSound.load(MediaActionSound.STOP_VIDEO_RECORDING)
|
||||||
mediaActionSound.load(MediaActionSound.SHUTTER_CLICK)
|
mediaActionSound.load(MediaActionSound.SHUTTER_CLICK)
|
||||||
|
mediaActionSound.load(MediaActionSound.TIMER_COUNTDOWN)
|
||||||
|
mediaActionSound.load(MediaActionSound.TIMER_COUNTDOWN_2_SECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun playShutterSound() {
|
fun playShutterSound() {
|
||||||
@ -23,6 +25,18 @@ class MediaSoundHelper(context: Context) {
|
|||||||
mediaActionSound.play(MediaActionSound.STOP_VIDEO_RECORDING)
|
mediaActionSound.play(MediaActionSound.STOP_VIDEO_RECORDING)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun playTimerCountdownSound() {
|
||||||
|
mediaActionSound.play(MediaActionSound.TIMER_COUNTDOWN)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun playTimerCountdown2SecondsSound() {
|
||||||
|
mediaActionSound.play(MediaActionSound.TIMER_COUNTDOWN_2_SECONDS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopTimerCountdown2SecondsSound() {
|
||||||
|
mediaActionSound.stop(MediaActionSound.TIMER_COUNTDOWN_2_SECONDS)
|
||||||
|
}
|
||||||
|
|
||||||
fun release() {
|
fun release() {
|
||||||
mediaActionSound.release()
|
mediaActionSound.release()
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import android.net.Uri
|
|||||||
import androidx.camera.view.PreviewView
|
import androidx.camera.view.PreviewView
|
||||||
import com.simplemobiletools.camera.helpers.CameraErrorHandler
|
import com.simplemobiletools.camera.helpers.CameraErrorHandler
|
||||||
import com.simplemobiletools.camera.helpers.MediaOutputHelper
|
import com.simplemobiletools.camera.helpers.MediaOutputHelper
|
||||||
|
import com.simplemobiletools.camera.helpers.MediaSoundHelper
|
||||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
|
|
||||||
class CameraXInitializer(private val activity: BaseSimpleActivity) {
|
class CameraXInitializer(private val activity: BaseSimpleActivity) {
|
||||||
@ -11,6 +12,7 @@ class CameraXInitializer(private val activity: BaseSimpleActivity) {
|
|||||||
fun createCameraXPreview(
|
fun createCameraXPreview(
|
||||||
previewView: PreviewView,
|
previewView: PreviewView,
|
||||||
listener: CameraXPreviewListener,
|
listener: CameraXPreviewListener,
|
||||||
|
mediaSoundHelper: MediaSoundHelper,
|
||||||
outputUri: Uri?,
|
outputUri: Uri?,
|
||||||
isThirdPartyIntent: Boolean,
|
isThirdPartyIntent: Boolean,
|
||||||
initInPhotoMode: Boolean,
|
initInPhotoMode: Boolean,
|
||||||
@ -20,6 +22,7 @@ class CameraXInitializer(private val activity: BaseSimpleActivity) {
|
|||||||
return CameraXPreview(
|
return CameraXPreview(
|
||||||
activity,
|
activity,
|
||||||
previewView,
|
previewView,
|
||||||
|
mediaSoundHelper,
|
||||||
mediaOutputHelper,
|
mediaOutputHelper,
|
||||||
cameraErrorHandler,
|
cameraErrorHandler,
|
||||||
listener,
|
listener,
|
||||||
|
@ -37,6 +37,7 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||||||
class CameraXPreview(
|
class CameraXPreview(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity,
|
||||||
private val previewView: PreviewView,
|
private val previewView: PreviewView,
|
||||||
|
private val mediaSoundHelper: MediaSoundHelper,
|
||||||
private val mediaOutputHelper: MediaOutputHelper,
|
private val mediaOutputHelper: MediaOutputHelper,
|
||||||
private val cameraErrorHandler: CameraErrorHandler,
|
private val cameraErrorHandler: CameraErrorHandler,
|
||||||
private val listener: CameraXPreviewListener,
|
private val listener: CameraXPreviewListener,
|
||||||
@ -49,14 +50,12 @@ class CameraXPreview(
|
|||||||
private const val AF_SIZE = 1.0f / 6.0f
|
private const val AF_SIZE = 1.0f / 6.0f
|
||||||
private const val AE_SIZE = AF_SIZE * 1.5f
|
private const val AE_SIZE = AF_SIZE * 1.5f
|
||||||
private const val CAMERA_MODE_SWITCH_WAIT_TIME = 500L
|
private const val CAMERA_MODE_SWITCH_WAIT_TIME = 500L
|
||||||
private const val TOGGLE_FLASH_DELAY = 700L
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val config = activity.config
|
private val config = activity.config
|
||||||
private val contentResolver = activity.contentResolver
|
private val contentResolver = activity.contentResolver
|
||||||
private val mainExecutor = ContextCompat.getMainExecutor(activity)
|
private val mainExecutor = ContextCompat.getMainExecutor(activity)
|
||||||
private val displayManager = activity.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
private val displayManager = activity.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||||
private val mediaSoundHelper = MediaSoundHelper(activity)
|
|
||||||
private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
|
private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
|
||||||
private val videoQualityManager = VideoQualityManager(activity)
|
private val videoQualityManager = VideoQualityManager(activity)
|
||||||
private val imageQualityManager = ImageQualityManager(activity)
|
private val imageQualityManager = ImageQualityManager(activity)
|
||||||
@ -123,7 +122,6 @@ class CameraXPreview(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
bindToLifeCycle()
|
bindToLifeCycle()
|
||||||
mediaSoundHelper.loadSounds()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindToLifeCycle() {
|
private fun bindToLifeCycle() {
|
||||||
@ -354,11 +352,6 @@ class CameraXPreview(
|
|||||||
orientationEventListener.disable()
|
orientationEventListener.disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy(owner: LifecycleOwner) {
|
|
||||||
super.onDestroy(owner)
|
|
||||||
mediaSoundHelper.release()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isInPhotoMode(): Boolean {
|
override fun isInPhotoMode(): Boolean {
|
||||||
return isPhotoCapture
|
return isPhotoCapture
|
||||||
}
|
}
|
||||||
|
BIN
app/src/main/res/raw/beep.mp3
Normal file
BIN
app/src/main/res/raw/beep.mp3
Normal file
Binary file not shown.
BIN
app/src/main/res/raw/beep_2_secs.mp3
Normal file
BIN
app/src/main/res/raw/beep_2_secs.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user