Skip to content

Commit

Permalink
V0.2.3 (#52)
Browse files Browse the repository at this point in the history
* Updated Basic-Sound Audio to catch thrown errors as AudioState.Error(error)
* Restored Kotlin 2.0.21 due to GitLive dependency not being compatible with 2.1.0 yet.
* Updated Android Library to version 8.7.3
* Updated KTOR to version 3.0.2
* Updated Google Play Services Ads transitive dependency to 23.6.0
  • Loading branch information
robertjamison authored Dec 12, 2024
1 parent 30ca45c commit 2674b21
Show file tree
Hide file tree
Showing 168 changed files with 382 additions and 325 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

![GitHub License](https://img.shields.io/github/license/lexilabs-app/basic)
![GitHub Release Date](https://img.shields.io/github/release-date/lexilabs-app/basic)
[![Kotlin](https://img.shields.io/badge/Kotlin-2.1.0-7f52ff.svg?style=flat&logo=kotlin)](https://kotlinlang.org)
[![Kotlin](https://img.shields.io/badge/Kotlin-2.0.21-7f52ff.svg?style=flat&logo=kotlin)](https://kotlinlang.org)

A Kotlin Multiplatform library to rapidly add basic features like pictures, logging, and audio to any project in a small and fast way.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,92 +49,96 @@ public actual class Audio actual constructor(): AudioBuilder {
* ```
*/
public actual override fun load() {
_audioState.value = AudioState.LOADING
mediaPlayer = MediaPlayer().apply {
setDataSource(resource)
prepareAsync()
setOnPreparedListener {
// Ready to play
_audioState.value = AudioState.READY
if (autoPlay) {
play()
try {
_audioState.value = AudioState.LOADING
mediaPlayer = MediaPlayer().apply {
setDataSource(resource)
prepareAsync()
setOnPreparedListener {
// Ready to play
_audioState.value = AudioState.READY
if (autoPlay) {
play()
}
}
setOnErrorListener { _, what, extra ->
throw Exception("init: MediaPlayer Error: $resource")
}
setOnCompletionListener {
_audioState.value = AudioState.READY
}
}
setOnErrorListener { _, what, extra ->
// Handle error
_audioState.value = AudioState.ERROR("init: MediaPlayer Error: what=$what, extra=$extra")
true // Indicating that the error was handled
}
setOnCompletionListener {
_audioState.value = AudioState.READY
}
} catch (e: Exception) {
Log.e(tag, "load:failure: $e")
_audioState.value = AudioState.ERROR("load:failure: $e")
}
}

public actual override fun play() {
mediaPlayer?.let {
if (!it.isPlaying) {
when (audioState.value) {
is AudioState.PLAYING -> {
/** do nothing **/
Log.d(tag, "play:AudioState.PLAYING: do you want it louder or something, lady?" )
}

is AudioState.LOADING -> {
/** do nothing **/
Log.d(tag, "play:AudioState.LOADING: wait for player to load" )
}

is AudioState.NONE -> {
Log.e(tag, "play:AudioState.NONE: mediaPlayer not initialized" )
_audioState.value =
AudioState.ERROR("play:AudioState.NONE: mediaPlayer not initialized")
throw IllegalStateException("play:AudioState.NONE: mediaPlayer not initialized")
}

is AudioState.ERROR -> {
Log.e(tag, "play:AudioState.ERROR: ${(audioState.value as AudioState.ERROR).message}" )
throw Exception("play:AudioState.ERROR: ${(audioState.value as AudioState.ERROR).message}")
}

is AudioState.PAUSED -> {
Log.i(tag,"play:AudioState.PAUSED: resuming" )
it.start()
_audioState.value = AudioState.PLAYING
}

is AudioState.READY -> {
Log.i(tag, "play:AudioState.READY: playing" )
it.start()
_audioState.value = AudioState.PLAYING
try {
mediaPlayer?.let {
if (!it.isPlaying) {
when (audioState.value) {
is AudioState.LOADING,
is AudioState.PLAYING -> { /** do nothing **/ }
is AudioState.NONE -> {
throw Exception ("AudioState.NONE: mediaPlayer not initialized")
// throw IllegalStateException("play:AudioState.NONE: mediaPlayer not initialized")
}
is AudioState.ERROR -> {
throw Exception("AudioState.ERROR: ${(audioState.value as AudioState.ERROR).message}")
}
is AudioState.PAUSED,
is AudioState.READY -> {
it.start()
_audioState.value = AudioState.PLAYING
}
}
}
}
} catch (e: Exception) {
Log.e(tag, "play:failure: $e")
_audioState.value = AudioState.ERROR("play:failure: $e")
}
}

public actual override fun pause() {
mediaPlayer?.let {
if (it.isPlaying) {
it.pause()
_audioState.value = AudioState.PAUSED
try {
mediaPlayer?.let {
if (it.isPlaying) {
it.pause()
_audioState.value = AudioState.PAUSED
}
}
} catch (e: Exception) {
Log.e(tag, "pause:failure: $e")
_audioState.value = AudioState.ERROR("pause:failure: $e")
}
}

public actual override fun stop() {
mediaPlayer?.let {
if (it.isPlaying) {
it.stop()
it.prepareAsync()
_audioState.value = AudioState.READY
try {
mediaPlayer?.let {
if (it.isPlaying) {
it.stop()
it.prepareAsync()
_audioState.value = AudioState.READY
}
}
} catch (e: Exception) {
Log.e(tag, "stop:failure: $e")
_audioState.value = AudioState.ERROR("stop:failure: $e")
}
}

public actual override fun release() {
_audioState.value = AudioState.NONE
mediaPlayer?.release()
mediaPlayer = null
try {
_audioState.value = AudioState.NONE
mediaPlayer?.release()
mediaPlayer = null
} catch (e: Exception) {
Log.e(tag, "release:failure: $e")
_audioState.value = AudioState.ERROR("release:failure: $e")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package app.lexilabs.basic.sound

import app.lexilabs.basic.logging.Log
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -26,6 +27,8 @@ import platform.Foundation.dataWithContentsOfURL
@ExperimentalBasicSound
public actual class Audio actual constructor(): AudioBuilder {

private val tag = "Basic-Sound Audio"

private val _audioState = MutableStateFlow<AudioState>(AudioState.NONE)
public actual override val audioState: StateFlow<AudioState> = _audioState.asStateFlow()

Expand All @@ -41,34 +44,39 @@ public actual class Audio actual constructor(): AudioBuilder {
}

public actual override fun load() {
_audioState.value = AudioState.LOADING
val data: NSData
if (resource.substring(0,4) == "http") {
val url: NSURL = NSURL.URLWithString(resource)
?: throw IllegalStateException("load:The URL provided was invalid")
data = NSData.dataWithContentsOfURL(url)
?: throw IllegalStateException("load:NS failed to load URL as data")
} else {
data = NSData.dataWithContentsOfFile(resource)
?: throw IllegalStateException("load:The path provided was invalid")
}
player = AVAudioPlayer(data, error = null)
_audioState.value = AudioState.READY
if (autoPlay) {
play()
try {
_audioState.value = AudioState.LOADING
val data: NSData
if (resource.substring(0, 4) == "http") {
val url: NSURL = NSURL.URLWithString(resource)
?: throw IllegalStateException("load:The URL provided was invalid")
data = NSData.dataWithContentsOfURL(url)
?: throw IllegalStateException("load:NS failed to load URL as data")
} else {
data = NSData.dataWithContentsOfFile(resource)
?: throw IllegalStateException("load:The path provided was invalid")
}
player = AVAudioPlayer(data, error = null)
_audioState.value = AudioState.READY
if (autoPlay) {
play()
}
} catch (e: Exception) {
Log.e(tag, "load:failure: $e")
_audioState.value = AudioState.ERROR("load:failure: $e")
}
}

public actual override fun play() {
if (audioState.value == AudioState.NONE) {
throw IllegalStateException("play:AudioState.NONE: mediaPlayer not initialized")
}
try {
if (audioState.value == AudioState.NONE) {
throw IllegalStateException("play:AudioState.NONE: mediaPlayer not initialized")
}
player?.play()
_audioState.value = AudioState.PLAYING
} catch (e: Exception) {
Log.e(tag, "play:failure:$e")
_audioState.value = AudioState.ERROR("play: $e")
throw Exception("play:$e")
}
}

Expand All @@ -77,6 +85,7 @@ public actual class Audio actual constructor(): AudioBuilder {
player?.pause()
_audioState.value = AudioState.PAUSED
} catch (e: Exception) {
Log.e(tag, "pause:failure: $e")
_audioState.value = AudioState.ERROR("pause: $e")
}
}
Expand All @@ -88,6 +97,7 @@ public actual class Audio actual constructor(): AudioBuilder {
player?.currentTime = 0.0
_audioState.value = AudioState.READY
} catch (e: Exception) {
Log.e(tag, "stop:failure: $e")
_audioState.value = AudioState.ERROR("stop: $e")
}
}
Expand All @@ -97,6 +107,7 @@ public actual class Audio actual constructor(): AudioBuilder {
player = null
_audioState.value = AudioState.NONE
} catch (e: Exception) {
Log.e(tag, "release:failure: $e")
_audioState.value = AudioState.ERROR("release: $e")
}
}
Expand Down
Loading

0 comments on commit 2674b21

Please sign in to comment.