Skip to content

Instantly share code, notes, and snippets.

@yandroidUA
Created January 25, 2024 14:58
Show Gist options
  • Select an option

  • Save yandroidUA/2bf3f51329f0b480fa7555bae2e567ce to your computer and use it in GitHub Desktop.

Select an option

Save yandroidUA/2bf3f51329f0b480fa7555bae2e567ce to your computer and use it in GitHub Desktop.
iOS AudioPlayer
import io.github.aakira.napier.Napier
import kotlinx.cinterop.*
import platform.AVFAudio.AVAudioPlayer
import platform.AVFAudio.AVAudioPlayerDelegateProtocol
import platform.Foundation.NSError
import platform.Foundation.NSURL
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
import kotlin.time.toDuration
// this one comes as an 'actual' class, so put it here like that for simplicity
class LocalUrl(
val url: NSURL,
)
@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class)
internal actual class AudioPlayer {
private var player: AVAudioPlayer? = null
var delegate: AVAudioPlayerDelegateProtocol? = null
private inline fun createPlayer(url: NSURL): AVAudioPlayer? = memScoped {
val err = allocPointerTo<ObjCObjectVar<NSError?>>()
val player = AVAudioPlayer(url, err.value)
val error = err.value?.pointed?.value
return if (error != null) {
Napier.e { "Error while creating AVAudioPlayer: ${error.code}, ${error.description}" }
null
} else player
}
actual fun play(url: LocalUrl, duration: Duration) {
createPlayer(url.url)?.let {
Napier.d { "Starting: $duration" }
player = it
it.delegate = delegate
it.volume = 10.0f
it.setCurrentTime(duration.toDouble(DurationUnit.SECONDS))
it.prepareToPlay()
it.play()
}
}
@OptIn(ExperimentalTime::class)
actual fun duration(url: LocalUrl, unit: DurationUnit): Duration {
var duration = Duration.ZERO
createPlayer(url.url)?.let { player ->
duration = Duration.convert(
value = player.duration,
sourceUnit = DurationUnit.SECONDS,
targetUnit = unit
).toDuration(unit = unit)
}
return duration
}
actual fun stop() {
player?.delegate = null
player?.stop()
player = null
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment