react-native-audio-browser 0.2.0-next.24 → 0.2.0-next.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -87,6 +87,7 @@ import com.margelo.nitro.audiobrowser.TimedMetadata
|
|
|
87
87
|
import com.margelo.nitro.audiobrowser.Track
|
|
88
88
|
import com.margelo.nitro.audiobrowser.TrackMetadata
|
|
89
89
|
import com.margelo.nitro.audiobrowser.TransformableRequestConfig
|
|
90
|
+
import com.margelo.nitro.core.NullType
|
|
90
91
|
import com.margelo.nitro.core.Promise
|
|
91
92
|
import java.util.concurrent.TimeUnit
|
|
92
93
|
import java.util.concurrent.atomic.AtomicReference
|
|
@@ -916,24 +917,27 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
|
|
|
916
917
|
// ============================================================================
|
|
917
918
|
|
|
918
919
|
override fun load(track: Track) {
|
|
920
|
+
// Throws without a player, as on iOS: a track asked for and silently dropped hides a mistake.
|
|
921
|
+
val player = player
|
|
919
922
|
launchInScope { player.load(track) }
|
|
920
923
|
}
|
|
921
924
|
|
|
922
|
-
override fun reset() =
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
925
|
+
override fun reset() =
|
|
926
|
+
commandPlayer("reset") { player ->
|
|
927
|
+
player.stop()
|
|
928
|
+
player.clear()
|
|
929
|
+
// clear() while IDLE emits no engine event, so the state machine never
|
|
930
|
+
// leaves STOPPED — a reset queue is "nothing loaded".
|
|
931
|
+
player.setPlaybackState(PlaybackState.NONE)
|
|
932
|
+
}
|
|
929
933
|
|
|
930
|
-
override fun play() =
|
|
934
|
+
override fun play() = commandPlayer("play") { it.play() }
|
|
931
935
|
|
|
932
|
-
override fun pause() =
|
|
936
|
+
override fun pause() = commandPlayer("pause") { it.pause() }
|
|
933
937
|
|
|
934
|
-
override fun togglePlayback() =
|
|
938
|
+
override fun togglePlayback() = commandPlayer("togglePlayback") { it.togglePlayback() }
|
|
935
939
|
|
|
936
|
-
override fun stop() =
|
|
940
|
+
override fun stop() = commandPlayer("stop") { it.stop() }
|
|
937
941
|
|
|
938
942
|
override fun setPlayWhenReady(playWhenReady: Boolean) = runBlockingOnMain {
|
|
939
943
|
// Pre-setup this stages the intent for the player to come up with — never throws.
|
|
@@ -945,35 +949,41 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
|
|
|
945
949
|
connectedService?.player?.playWhenReady ?: pendingPlayWhenReady ?: false
|
|
946
950
|
}
|
|
947
951
|
|
|
948
|
-
override fun seekTo(position: Double) =
|
|
949
|
-
|
|
950
|
-
|
|
952
|
+
override fun seekTo(position: Double) =
|
|
953
|
+
commandPlayer("seekTo") { player ->
|
|
954
|
+
player.seekTo((position * 1000).toLong(), TimeUnit.MILLISECONDS)
|
|
955
|
+
}
|
|
951
956
|
|
|
952
|
-
override fun seekBy(offset: Double) =
|
|
953
|
-
|
|
954
|
-
|
|
957
|
+
override fun seekBy(offset: Double) =
|
|
958
|
+
commandPlayer("seekBy") { player ->
|
|
959
|
+
player.seekBy((offset * 1000).toLong(), TimeUnit.MILLISECONDS)
|
|
960
|
+
}
|
|
955
961
|
|
|
956
|
-
override fun seekToLiveEdge() =
|
|
962
|
+
override fun seekToLiveEdge() = commandPlayer("seekToLiveEdge") { it.seekToLiveEdge() }
|
|
957
963
|
|
|
958
|
-
override fun setVolume(level: Double) =
|
|
964
|
+
override fun setVolume(level: Double) = commandPlayer("setVolume") { it.volume = level.toFloat() }
|
|
959
965
|
|
|
960
|
-
override fun getVolume(): Double =
|
|
966
|
+
override fun getVolume(): Double = readPlayer(1.0) { it.volume.toDouble() }
|
|
961
967
|
|
|
962
|
-
override fun setRate(rate: Double) =
|
|
968
|
+
override fun setRate(rate: Double) =
|
|
969
|
+
commandPlayer("setRate") { it.playbackSpeed = rate.toFloat() }
|
|
963
970
|
|
|
964
|
-
override fun getRate(): Double =
|
|
971
|
+
override fun getRate(): Double = readPlayer(1.0) { it.playbackSpeed.toDouble() }
|
|
965
972
|
|
|
966
|
-
override fun getProgress(): Progress =
|
|
967
|
-
Progress(
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
+
override fun getProgress(): Progress =
|
|
974
|
+
readPlayer(Progress(duration = 0.0, position = 0.0, buffered = 0.0)) { player ->
|
|
975
|
+
Progress(
|
|
976
|
+
duration = player.duration.toSeconds(),
|
|
977
|
+
position = player.position.toSeconds(),
|
|
978
|
+
buffered = player.bufferedPosition.toSeconds(),
|
|
979
|
+
)
|
|
980
|
+
}
|
|
973
981
|
|
|
974
|
-
override fun getPlayback(): Playback =
|
|
982
|
+
override fun getPlayback(): Playback =
|
|
983
|
+
readPlayer(Playback(PlaybackState.NONE, null)) { it.getPlayback() }
|
|
975
984
|
|
|
976
|
-
override fun getPlayingState(): PlayingState =
|
|
985
|
+
override fun getPlayingState(): PlayingState =
|
|
986
|
+
readPlayer(PlayingState(playing = false, buffering = false)) { it.getPlayingState() }
|
|
977
987
|
|
|
978
988
|
override fun getRepeatMode(): RepeatMode = runBlockingOnMain {
|
|
979
989
|
connectedService?.player?.repeatMode ?: pendingRepeatMode ?: RepeatMode.OFF
|
|
@@ -984,121 +994,121 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
|
|
|
984
994
|
connectedService?.player?.let { it.repeatMode = mode } ?: run { pendingRepeatMode = mode }
|
|
985
995
|
}
|
|
986
996
|
|
|
987
|
-
override fun getShuffleEnabled(): Boolean =
|
|
997
|
+
override fun getShuffleEnabled(): Boolean = readPlayer(false) { it.shuffleMode }
|
|
988
998
|
|
|
989
|
-
override fun setShuffleEnabled(enabled: Boolean) =
|
|
990
|
-
player.shuffleMode = enabled
|
|
991
|
-
}
|
|
999
|
+
override fun setShuffleEnabled(enabled: Boolean) =
|
|
1000
|
+
commandPlayer("setShuffleEnabled") { player -> player.shuffleMode = enabled }
|
|
992
1001
|
|
|
993
|
-
override fun setPlaybackIntervalEnabled(enabled: Boolean) =
|
|
994
|
-
|
|
995
|
-
|
|
1002
|
+
override fun setPlaybackIntervalEnabled(enabled: Boolean) =
|
|
1003
|
+
commandPlayer("setPlaybackIntervalEnabled") { player ->
|
|
1004
|
+
player.setPlaybackIntervalEnabled(enabled)
|
|
1005
|
+
}
|
|
996
1006
|
|
|
997
|
-
override fun getPlaybackError(): PlaybackError? =
|
|
1007
|
+
override fun getPlaybackError(): PlaybackError? = readPlayer(null) { it.playbackError }
|
|
998
1008
|
|
|
999
|
-
override fun retry() =
|
|
1009
|
+
override fun retry() = commandPlayer("retry") { it.prepare() }
|
|
1000
1010
|
|
|
1001
1011
|
// ============================================================================
|
|
1002
1012
|
// MARK: Queue Management
|
|
1003
1013
|
// ============================================================================
|
|
1004
1014
|
|
|
1005
|
-
override fun add(tracks: Array<Track>, insertBeforeIndex: Double?) =
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1015
|
+
override fun add(tracks: Array<Track>, insertBeforeIndex: Double?) =
|
|
1016
|
+
commandPlayer("add") { player ->
|
|
1017
|
+
val inputIndex = insertBeforeIndex?.toInt() ?: -1
|
|
1018
|
+
player.add(tracks, inputIndex)
|
|
1019
|
+
}
|
|
1009
1020
|
|
|
1010
|
-
override fun move(fromIndex: Double, toIndex: Double) =
|
|
1011
|
-
player.move(fromIndex.toInt(), toIndex.toInt())
|
|
1012
|
-
}
|
|
1021
|
+
override fun move(fromIndex: Double, toIndex: Double) =
|
|
1022
|
+
commandPlayer("move") { player -> player.move(fromIndex.toInt(), toIndex.toInt()) }
|
|
1013
1023
|
|
|
1014
|
-
override fun remove(indexes: DoubleArray) =
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1024
|
+
override fun remove(indexes: DoubleArray) =
|
|
1025
|
+
commandPlayer("remove") { player ->
|
|
1026
|
+
val indexList = indexes.map { it.toInt() }
|
|
1027
|
+
player.remove(indexList)
|
|
1028
|
+
}
|
|
1018
1029
|
|
|
1019
|
-
override fun removeUpcomingTracks() =
|
|
1030
|
+
override fun removeUpcomingTracks() =
|
|
1031
|
+
commandPlayer("removeUpcomingTracks") { it.removeUpcomingTracks() }
|
|
1020
1032
|
|
|
1021
|
-
override fun skip(index: Double, initialPosition: Double?) =
|
|
1022
|
-
|
|
1033
|
+
override fun skip(index: Double, initialPosition: Double?) =
|
|
1034
|
+
commandPlayer("skip") { player ->
|
|
1035
|
+
player.skipTo(index.toInt())
|
|
1023
1036
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1037
|
+
if (initialPosition != null && initialPosition >= 0) {
|
|
1038
|
+
player.seekTo((initialPosition * 1000).toLong(), TimeUnit.MILLISECONDS)
|
|
1039
|
+
}
|
|
1026
1040
|
}
|
|
1027
|
-
}
|
|
1028
1041
|
|
|
1029
|
-
override fun skipToNext(initialPosition: Double?) =
|
|
1030
|
-
|
|
1042
|
+
override fun skipToNext(initialPosition: Double?) =
|
|
1043
|
+
commandPlayer("skipToNext") { player ->
|
|
1044
|
+
player.next()
|
|
1031
1045
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1046
|
+
if (initialPosition != null && initialPosition >= 0) {
|
|
1047
|
+
player.seekTo((initialPosition * 1000).toLong(), TimeUnit.MILLISECONDS)
|
|
1048
|
+
}
|
|
1034
1049
|
}
|
|
1035
|
-
}
|
|
1036
1050
|
|
|
1037
|
-
override fun skipToPrevious(initialPosition: Double?) =
|
|
1038
|
-
|
|
1051
|
+
override fun skipToPrevious(initialPosition: Double?) =
|
|
1052
|
+
commandPlayer("skipToPrevious") { player ->
|
|
1053
|
+
player.previous()
|
|
1039
1054
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1055
|
+
if (initialPosition != null && initialPosition >= 0) {
|
|
1056
|
+
player.seekTo((initialPosition * 1000).toLong(), TimeUnit.MILLISECONDS)
|
|
1057
|
+
}
|
|
1042
1058
|
}
|
|
1043
|
-
}
|
|
1044
1059
|
|
|
1045
1060
|
override fun setQueue(tracks: Array<Track>, startIndex: Double?, startPosition: Double?) =
|
|
1046
|
-
|
|
1061
|
+
commandPlayer("setQueue") { player ->
|
|
1047
1062
|
player.setQueue(tracks, startIndex?.toInt() ?: 0, ((startPosition ?: 0.0) * 1000).toLong())
|
|
1048
1063
|
}
|
|
1049
1064
|
|
|
1050
|
-
override fun setActiveTrackFavorited(favorited: Boolean): Unit =
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1065
|
+
override fun setActiveTrackFavorited(favorited: Boolean): Unit =
|
|
1066
|
+
commandPlayer("setActiveTrackFavorited") { player ->
|
|
1067
|
+
// Applied-result is for MediaSession honesty; the JS API stays fire-and-forget.
|
|
1068
|
+
player.setActiveTrackFavorited(favorited)
|
|
1069
|
+
}
|
|
1055
1070
|
|
|
1056
|
-
override fun toggleActiveTrackFavorited(): Unit =
|
|
1057
|
-
|
|
1058
|
-
Unit
|
|
1059
|
-
}
|
|
1071
|
+
override fun toggleActiveTrackFavorited(): Unit =
|
|
1072
|
+
commandPlayer("toggleActiveTrackFavorited") { it.toggleActiveTrackFavorited() }
|
|
1060
1073
|
|
|
1061
|
-
override fun getQueue(): Array<Track> =
|
|
1074
|
+
override fun getQueue(): Array<Track> = readPlayer(emptyArray()) { it.tracks }
|
|
1062
1075
|
|
|
1063
|
-
override fun getTrack(index: Double): Track? =
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1076
|
+
override fun getTrack(index: Double): Track? =
|
|
1077
|
+
readPlayer(null) { player ->
|
|
1078
|
+
try {
|
|
1079
|
+
player.getTrack(index.toInt())
|
|
1080
|
+
} catch (e: IllegalArgumentException) {
|
|
1081
|
+
null
|
|
1082
|
+
}
|
|
1068
1083
|
}
|
|
1069
|
-
}
|
|
1070
1084
|
|
|
1071
|
-
override fun getActiveTrackIndex(): Double? =
|
|
1072
|
-
player.currentIndex?.toDouble()
|
|
1073
|
-
}
|
|
1085
|
+
override fun getActiveTrackIndex(): Double? = readPlayer(null) { it.currentIndex?.toDouble() }
|
|
1074
1086
|
|
|
1075
|
-
override fun getActiveTrack(): Track? =
|
|
1087
|
+
override fun getActiveTrack(): Track? = readPlayer(null) { it.currentTrack }
|
|
1076
1088
|
|
|
1077
1089
|
// ============================================================================
|
|
1078
1090
|
// MARK: Now Playing Metadata
|
|
1079
1091
|
// ============================================================================
|
|
1080
1092
|
|
|
1081
|
-
override fun updateNowPlaying(update: NowPlayingUpdate?) =
|
|
1082
|
-
player.nowPlaying.updateNowPlaying(update)
|
|
1083
|
-
}
|
|
1093
|
+
override fun updateNowPlaying(update: NowPlayingUpdate?) =
|
|
1094
|
+
commandPlayer("updateNowPlaying") { player -> player.nowPlaying.updateNowPlaying(update) }
|
|
1084
1095
|
|
|
1085
|
-
override fun flashNowPlaying(update: NowPlayingUpdate, durationMs: Double) =
|
|
1086
|
-
|
|
1087
|
-
|
|
1096
|
+
override fun flashNowPlaying(update: NowPlayingUpdate, durationMs: Double) =
|
|
1097
|
+
commandPlayer("flashNowPlaying") { player ->
|
|
1098
|
+
player.nowPlaying.flashNowPlaying(update, durationMs)
|
|
1099
|
+
}
|
|
1088
1100
|
|
|
1089
|
-
override fun clearNowPlayingFlash() =
|
|
1090
|
-
player.nowPlaying.clearNowPlayingFlash()
|
|
1091
|
-
}
|
|
1101
|
+
override fun clearNowPlayingFlash() =
|
|
1102
|
+
commandPlayer("clearNowPlayingFlash") { player -> player.nowPlaying.clearNowPlayingFlash() }
|
|
1092
1103
|
|
|
1093
|
-
override fun getNowPlaying(): NowPlayingMetadata? =
|
|
1094
|
-
player.nowPlaying.getNowPlaying()
|
|
1095
|
-
}
|
|
1104
|
+
override fun getNowPlaying(): NowPlayingMetadata? =
|
|
1105
|
+
readPlayer(null) { player -> player.nowPlaying.getNowPlaying() }
|
|
1096
1106
|
|
|
1097
1107
|
// ============================================================================
|
|
1098
1108
|
// MARK: Network Connectivity
|
|
1099
1109
|
// ============================================================================
|
|
1100
1110
|
|
|
1101
|
-
override fun getOnline(): Boolean =
|
|
1111
|
+
override fun getOnline(): Boolean = readPlayer(true) { it.getOnline() }
|
|
1102
1112
|
|
|
1103
1113
|
// ============================================================================
|
|
1104
1114
|
// MARK: System Volume
|
|
@@ -1124,35 +1134,32 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
|
|
|
1124
1134
|
// MARK: Equalizer (Android only)
|
|
1125
1135
|
// ============================================================================
|
|
1126
1136
|
|
|
1127
|
-
override fun getEqualizerSettings(): EqualizerSettings? =
|
|
1128
|
-
player.equalizer.getSettings()
|
|
1129
|
-
}
|
|
1137
|
+
override fun getEqualizerSettings(): EqualizerSettings? =
|
|
1138
|
+
readPlayer(null) { player -> player.equalizer.getSettings() }
|
|
1130
1139
|
|
|
1131
|
-
override fun setEqualizerEnabled(enabled: Boolean) =
|
|
1132
|
-
player.equalizer.setEnabled(enabled)
|
|
1133
|
-
}
|
|
1140
|
+
override fun setEqualizerEnabled(enabled: Boolean) =
|
|
1141
|
+
commandPlayer("setEqualizerEnabled") { player -> player.equalizer.setEnabled(enabled) }
|
|
1134
1142
|
|
|
1135
|
-
override fun setEqualizerPreset(preset: String) =
|
|
1136
|
-
player.equalizer.setPreset(preset)
|
|
1137
|
-
}
|
|
1143
|
+
override fun setEqualizerPreset(preset: String) =
|
|
1144
|
+
commandPlayer("setEqualizerPreset") { player -> player.equalizer.setPreset(preset) }
|
|
1138
1145
|
|
|
1139
|
-
override fun setEqualizerLevels(levels: DoubleArray) =
|
|
1140
|
-
player.equalizer.setLevels(levels)
|
|
1141
|
-
}
|
|
1146
|
+
override fun setEqualizerLevels(levels: DoubleArray) =
|
|
1147
|
+
commandPlayer("setEqualizerLevels") { player -> player.equalizer.setLevels(levels) }
|
|
1142
1148
|
|
|
1143
1149
|
// ============================================================================
|
|
1144
1150
|
// MARK: Sleep Timer
|
|
1145
1151
|
// ============================================================================
|
|
1146
1152
|
|
|
1147
|
-
override fun getSleepTimer(): SleepTimer =
|
|
1153
|
+
override fun getSleepTimer(): SleepTimer =
|
|
1154
|
+
readPlayer(SleepTimer.create(NullType.NULL)) { it.sleepTimer.get() }
|
|
1148
1155
|
|
|
1149
|
-
override fun setSleepTimer(seconds: Double, fadeDuration: Double?) =
|
|
1150
|
-
player.sleepTimer.setAfter(seconds, fadeDuration)
|
|
1151
|
-
}
|
|
1156
|
+
override fun setSleepTimer(seconds: Double, fadeDuration: Double?) =
|
|
1157
|
+
commandPlayer("setSleepTimer") { player -> player.sleepTimer.setAfter(seconds, fadeDuration) }
|
|
1152
1158
|
|
|
1153
|
-
override fun setSleepTimerToEndOfTrack() =
|
|
1159
|
+
override fun setSleepTimerToEndOfTrack() =
|
|
1160
|
+
commandPlayer("setSleepTimerToEndOfTrack") { it.sleepTimer.setEndOfTrack() }
|
|
1154
1161
|
|
|
1155
|
-
override fun clearSleepTimer(): Boolean =
|
|
1162
|
+
override fun clearSleepTimer(): Boolean = readPlayer(false) { it.sleepTimer.clear() }
|
|
1156
1163
|
|
|
1157
1164
|
// ============================================================================
|
|
1158
1165
|
// MARK: Battery Optimization (Android only)
|
|
@@ -1293,6 +1300,29 @@ class AudioBrowser : HybridAudioBrowserSpec(), ServiceConnection {
|
|
|
1293
1300
|
private val service: Service
|
|
1294
1301
|
get() = connectedService ?: throw Exception("Player not initialized")
|
|
1295
1302
|
|
|
1303
|
+
/**
|
|
1304
|
+
* The player while its service is connected: not before setupPlayer, nor while the service
|
|
1305
|
+
* restarts.
|
|
1306
|
+
*/
|
|
1307
|
+
private val connectedPlayer: Player?
|
|
1308
|
+
get() = connectedService?.player
|
|
1309
|
+
|
|
1310
|
+
/** What [read] gets from the player, or without one [fallback], the answer iOS gives then. */
|
|
1311
|
+
private fun <T> readPlayer(fallback: T, read: suspend (Player) -> T): T = runBlockingOnMain {
|
|
1312
|
+
val player = connectedPlayer ?: return@runBlockingOnMain fallback
|
|
1313
|
+
read(player)
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
/** Runs [command] on the player; without one it is dropped with a warning, as iOS drops it. */
|
|
1317
|
+
private fun commandPlayer(name: String, command: suspend (Player) -> Unit) = runBlockingOnMain {
|
|
1318
|
+
val player = connectedPlayer
|
|
1319
|
+
if (player == null) {
|
|
1320
|
+
Timber.w("$name before the player is set up, or while its service restarts: ignored")
|
|
1321
|
+
} else {
|
|
1322
|
+
command(player)
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1296
1326
|
internal val player
|
|
1297
1327
|
get() = service.player
|
|
1298
1328
|
|