@javascriptcommon/react-native-track-player 1.2.9 → 1.2.24
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.
- package/android/build.gradle +61 -4
- package/android/src/main/AndroidManifest.xml +2 -4
- package/android/src/main/ic_home-playstore.png +0 -0
- package/android/src/main/ic_repeat-playstore.png +0 -0
- package/android/src/main/ic_repeat_50-playstore.png +0 -0
- package/android/src/main/ic_shuffle-playstore.png +0 -0
- package/android/src/main/ic_shuffle_50-playstore.png +0 -0
- package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
- package/android/src/main/ic_stop-playstore.png +0 -0
- package/android/src/main/ic_test-playstore.png +0 -0
- package/android/src/main/java/com/guichaguri/trackplayer/{service/HeadlessJsMediaService.java → HeadlessJsMediaService.java} +83 -32
- package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +25 -0
- package/android/src/main/java/com/guichaguri/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/EventHolder.kt +30 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +20 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/PlayerEventHolder.kt +111 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +10 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioContentType.kt +10 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +66 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioPlayerState.kt +30 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/BufferConfig.kt +8 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/CacheConfig.kt +17 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/Capability.kt +19 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/FocusChangeData.kt +3 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/MediaSessionCallback.kt +17 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +43 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +8 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +8 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayWhenReadyChangeData.kt +5 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackError.kt +6 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackMetadata.kt +200 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerConfig.kt +33 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +9 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PositionChangedReason.kt +39 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +49 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +678 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +10 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +864 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/QueuedAudioPlayer.kt +269 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +35 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +26 -0
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +12 -0
- package/android/src/main/java/com/guichaguri/trackplayer/model/MetadataAdapter.kt +224 -0
- package/android/src/main/java/com/guichaguri/trackplayer/model/State.kt +13 -0
- package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +120 -0
- package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +19 -0
- package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +11 -0
- package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +151 -0
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.kt +66 -0
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +1192 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/BundleUtils.kt +117 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +31 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +347 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +1268 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +228 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +141 -0
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +396 -0
- package/android/src/main/res/drawable-hdpi/ic_home.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_home.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_home.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_home.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_home.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
- package/android/src/main/res/strings.xml +6 -0
- package/android/src/main/res/values/strings.xml +6 -0
- package/index.d.ts +62 -1
- package/lib/index.js +10 -9
- package/package.json +1 -1
- package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.java +0 -28
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.java +0 -55
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.java +0 -298
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.java +0 -47
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.java +0 -383
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.java +0 -271
- package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.java +0 -243
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.java +0 -148
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.java +0 -379
- package/android/src/main/java/com/guichaguri/trackplayer/service/models/Track.java +0 -141
- package/android/src/main/java/com/guichaguri/trackplayer/service/models/TrackType.java +0 -35
- package/android/src/main/res/drawable-hdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_logo.png +0 -0
package/android/build.gradle
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
repositories {
|
|
3
|
+
mavenLocal()
|
|
4
|
+
mavenCentral()
|
|
5
|
+
google()
|
|
6
|
+
}
|
|
7
|
+
dependencies {
|
|
8
|
+
classpath 'com.android.tools.build:gradle:7.4.2'
|
|
9
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
apply plugin: 'com.android.library'
|
|
14
|
+
apply plugin: 'org.jetbrains.kotlin.android'
|
|
2
15
|
|
|
3
16
|
def safeExtGet(prop, fallback) {
|
|
4
17
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
@@ -7,12 +20,13 @@ def safeExtGet(prop, fallback) {
|
|
|
7
20
|
android {
|
|
8
21
|
compileSdkVersion safeExtGet('compileSdkVersion', 28)
|
|
9
22
|
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
|
|
10
|
-
|
|
23
|
+
|
|
11
24
|
compileOptions {
|
|
12
25
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
13
26
|
sourceCompatibility JavaVersion.VERSION_1_8
|
|
14
27
|
}
|
|
15
28
|
|
|
29
|
+
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
16
30
|
defaultConfig {
|
|
17
31
|
minSdkVersion safeExtGet('minSdkVersion', 16)
|
|
18
32
|
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
|
@@ -22,13 +36,56 @@ android {
|
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
dependencies {
|
|
25
|
-
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
|
26
39
|
|
|
27
40
|
// All support libs must use the same version
|
|
28
41
|
implementation 'androidx.work:work-runtime:2.7.1'
|
|
29
|
-
implementation "androidx.core:core:1.7.0"
|
|
30
|
-
implementation "androidx.media:media:1.5.0"
|
|
31
42
|
implementation "androidx.localbroadcastmanager:localbroadcastmanager:1.1.0"
|
|
32
43
|
implementation "com.github.bumptech.glide:glide:4.13.2"
|
|
33
44
|
|
|
45
|
+
// implementation 'com.github.lovegaoshi:KotlinAudio:v2.0.0-rc7-podverse-13'
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
implementation "com.facebook.react:react-native:+"
|
|
49
|
+
|
|
50
|
+
// Make sure we're using androidx
|
|
51
|
+
implementation "androidx.core:core-ktx:1.7.0"
|
|
52
|
+
implementation "androidx.localbroadcastmanager:localbroadcastmanager:1.1.0"
|
|
53
|
+
implementation "androidx.lifecycle:lifecycle-process:2.6.1"
|
|
54
|
+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3"
|
|
55
|
+
implementation 'androidx.media:media:1.6.0'
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
implementation "androidx.car.app:app:1.4.0"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
implementation 'io.coil-kt:coil:1.4.0'
|
|
64
|
+
implementation 'androidx.media:media:1.6.0'
|
|
65
|
+
api 'com.google.android.exoplayer:exoplayer:2.18.1'
|
|
66
|
+
api 'com.google.android.exoplayer:extension-mediasession:2.18.1'
|
|
67
|
+
api 'com.jakewharton.timber:timber:5.0.1'
|
|
68
|
+
|
|
69
|
+
implementation 'androidx.test:rules:1.4.0'
|
|
70
|
+
|
|
71
|
+
// Asynchronous Testing
|
|
72
|
+
androidTestImplementation('org.awaitility:awaitility:4.2.0') {
|
|
73
|
+
transitive = false
|
|
74
|
+
}
|
|
75
|
+
androidTestImplementation('org.awaitility:awaitility-kotlin:4.2.0') {
|
|
76
|
+
transitive = false
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// (Required) Writing and executing Unit Tests on the JUnit Platform
|
|
80
|
+
androidTestImplementation("androidx.test:runner:1.4.0")
|
|
81
|
+
androidTestImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
|
|
82
|
+
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
|
83
|
+
|
|
84
|
+
// (Optional) If you need "Parameterized Tests"
|
|
85
|
+
testImplementation("org.junit.jupiter:junit-jupiter-params:5.8.2")
|
|
86
|
+
|
|
87
|
+
// The instrumentation test companion libraries
|
|
88
|
+
androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.3.0")
|
|
89
|
+
androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.3.0")
|
|
90
|
+
|
|
34
91
|
}
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
<application>
|
|
10
10
|
|
|
11
11
|
<!-- The main service, handles playback, playlists and media buttons -->
|
|
12
|
-
<service android:name=".service.MusicService"
|
|
13
|
-
android:enabled="true"
|
|
14
|
-
android:foregroundServiceType="mediaPlayback"
|
|
15
|
-
android:exported="true">
|
|
12
|
+
<service android:name="com.guichaguri.trackplayer.service.MusicService" android:enabled="true" android:exported="true" android:foregroundServiceType="mediaPlayback">
|
|
16
13
|
<intent-filter>
|
|
17
14
|
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
|
15
|
+
<action android:name="android.media.browse.MediaBrowserService" />
|
|
18
16
|
</intent-filter>
|
|
19
17
|
</service>
|
|
20
18
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
package com.guichaguri.trackplayer;
|
|
2
9
|
|
|
3
10
|
import android.annotation.SuppressLint;
|
|
4
11
|
import android.content.BroadcastReceiver;
|
|
@@ -6,12 +13,14 @@ import android.content.Context;
|
|
|
6
13
|
import android.content.Intent;
|
|
7
14
|
import android.os.IBinder;
|
|
8
15
|
import android.os.PowerManager;
|
|
9
|
-
|
|
16
|
+
import androidx.annotation.NonNull;
|
|
10
17
|
import androidx.annotation.Nullable;
|
|
11
18
|
import androidx.media.MediaBrowserServiceCompat;
|
|
12
19
|
import com.facebook.infer.annotation.Assertions;
|
|
20
|
+
import com.facebook.react.ReactHost;
|
|
13
21
|
import com.facebook.react.bridge.ReactContext;
|
|
14
22
|
import com.facebook.react.bridge.UiThreadUtil;
|
|
23
|
+
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
|
15
24
|
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
|
|
16
25
|
import com.facebook.react.jstasks.HeadlessJsTaskContext;
|
|
17
26
|
import com.facebook.react.jstasks.HeadlessJsTaskEventListener;
|
|
@@ -35,17 +44,21 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|
|
35
44
|
* {@link BroadcastReceiver#onReceive}, to make sure the device doesn't go to sleep before the
|
|
36
45
|
* service is started.
|
|
37
46
|
*/
|
|
47
|
+
|
|
38
48
|
public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat implements HeadlessJsTaskEventListener {
|
|
39
49
|
|
|
40
50
|
private final Set<Integer> mActiveTasks = new CopyOnWriteArraySet<>();
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
public static @Nullable PowerManager.WakeLock sWakeLock;
|
|
43
52
|
|
|
53
|
+
private boolean initialized = false;
|
|
44
54
|
|
|
45
55
|
@Override
|
|
46
56
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
57
|
+
super.onStartCommand(intent, flags, startId);
|
|
47
58
|
HeadlessJsTaskConfig taskConfig = getTaskConfig(intent);
|
|
48
|
-
if (taskConfig != null) {
|
|
59
|
+
if (!initialized && taskConfig != null) {
|
|
60
|
+
// HACK: ensure headlessJsMediaService tasks are only registered once.
|
|
61
|
+
initialized = true;
|
|
49
62
|
startTask(taskConfig);
|
|
50
63
|
return START_REDELIVER_INTENT;
|
|
51
64
|
}
|
|
@@ -99,19 +112,9 @@ public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat i
|
|
|
99
112
|
protected void startTask(final HeadlessJsTaskConfig taskConfig) {
|
|
100
113
|
UiThreadUtil.assertOnUiThread();
|
|
101
114
|
acquireWakeLockNow(this);
|
|
102
|
-
|
|
103
|
-
getReactNativeHost().getReactInstanceManager();
|
|
104
|
-
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
|
115
|
+
ReactContext reactContext = getReactContext();
|
|
105
116
|
if (reactContext == null) {
|
|
106
|
-
|
|
107
|
-
new ReactInstanceEventListener() {
|
|
108
|
-
@Override
|
|
109
|
-
public void onReactContextInitialized(ReactContext reactContext) {
|
|
110
|
-
invokeStartTask(reactContext, taskConfig);
|
|
111
|
-
reactInstanceManager.removeReactInstanceEventListener(this);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
reactInstanceManager.createReactContextInBackground();
|
|
117
|
+
createReactContextAndScheduleTask(taskConfig);
|
|
115
118
|
} else {
|
|
116
119
|
invokeStartTask(reactContext, taskConfig);
|
|
117
120
|
}
|
|
@@ -123,12 +126,9 @@ public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat i
|
|
|
123
126
|
headlessJsTaskContext.addTaskEventListener(this);
|
|
124
127
|
|
|
125
128
|
UiThreadUtil.runOnUiThread(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
int taskId = headlessJsTaskContext.startTask(taskConfig);
|
|
130
|
-
mActiveTasks.add(taskId);
|
|
131
|
-
}
|
|
129
|
+
() -> {
|
|
130
|
+
int taskId = headlessJsTaskContext.startTask(taskConfig);
|
|
131
|
+
mActiveTasks.add(taskId);
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -136,14 +136,11 @@ public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat i
|
|
|
136
136
|
public void onDestroy() {
|
|
137
137
|
super.onDestroy();
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
HeadlessJsTaskContext.getInstance(reactContext);
|
|
145
|
-
headlessJsTaskContext.removeTaskEventListener(this);
|
|
146
|
-
}
|
|
139
|
+
ReactContext reactContext = getReactContext();
|
|
140
|
+
if (reactContext != null) {
|
|
141
|
+
HeadlessJsTaskContext headlessJsTaskContext =
|
|
142
|
+
HeadlessJsTaskContext.getInstance(reactContext);
|
|
143
|
+
headlessJsTaskContext.removeTaskEventListener(this);
|
|
147
144
|
}
|
|
148
145
|
if (sWakeLock != null) {
|
|
149
146
|
sWakeLock.release();
|
|
@@ -156,7 +153,7 @@ public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat i
|
|
|
156
153
|
@Override
|
|
157
154
|
public void onHeadlessJsTaskFinish(int taskId) {
|
|
158
155
|
mActiveTasks.remove(taskId);
|
|
159
|
-
if (mActiveTasks.
|
|
156
|
+
if (mActiveTasks.isEmpty()) {
|
|
160
157
|
stopSelf();
|
|
161
158
|
}
|
|
162
159
|
}
|
|
@@ -171,4 +168,58 @@ public abstract class HeadlessJsMediaService extends MediaBrowserServiceCompat i
|
|
|
171
168
|
protected ReactNativeHost getReactNativeHost() {
|
|
172
169
|
return ((ReactApplication) getApplication()).getReactNativeHost();
|
|
173
170
|
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get the {@link ReactHost} used by this app. By default, assumes {@link #getApplication()}
|
|
174
|
+
* is an instance of {@link ReactApplication} and calls {@link
|
|
175
|
+
* ReactApplication#getReactHost()}.
|
|
176
|
+
* This method assumes it is called in new architecture and returns null if not.
|
|
177
|
+
*/
|
|
178
|
+
protected ReactHost getReactHost() {
|
|
179
|
+
return ((ReactApplication) getApplication()).getReactHost();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@SuppressLint("VisibleForTests")
|
|
183
|
+
protected ReactContext getReactContext() {
|
|
184
|
+
if (DefaultNewArchitectureEntryPoint.getBridgelessEnabled()) {
|
|
185
|
+
ReactHost reactHost = getReactHost();
|
|
186
|
+
Assertions.assertNotNull(reactHost, "React host is null in newArchitecture");
|
|
187
|
+
return reactHost.getCurrentReactContext();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
final ReactInstanceManager reactInstanceManager =
|
|
191
|
+
getReactNativeHost().getReactInstanceManager();
|
|
192
|
+
return reactInstanceManager.getCurrentReactContext();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
private void createReactContextAndScheduleTask(final HeadlessJsTaskConfig taskConfig) {
|
|
197
|
+
|
|
198
|
+
if (DefaultNewArchitectureEntryPoint.getBridgelessEnabled()) { // new arch
|
|
199
|
+
final ReactHost reactHost = getReactHost();
|
|
200
|
+
reactHost.addReactInstanceEventListener(
|
|
201
|
+
new ReactInstanceEventListener() {
|
|
202
|
+
@Override
|
|
203
|
+
public void onReactContextInitialized(@NonNull ReactContext reactContext) {
|
|
204
|
+
invokeStartTask(reactContext, taskConfig);
|
|
205
|
+
reactHost.removeReactInstanceEventListener(this);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
reactHost.start();
|
|
210
|
+
} else { // old arch
|
|
211
|
+
final ReactInstanceManager reactInstanceManager =
|
|
212
|
+
getReactNativeHost().getReactInstanceManager();
|
|
213
|
+
|
|
214
|
+
reactInstanceManager.addReactInstanceEventListener(
|
|
215
|
+
new ReactInstanceEventListener() {
|
|
216
|
+
@Override
|
|
217
|
+
public void onReactContextInitialized(@NonNull ReactContext reactContext) {
|
|
218
|
+
invokeStartTask(reactContext, taskConfig);
|
|
219
|
+
reactInstanceManager.removeReactInstanceEventListener(this);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
reactInstanceManager.createReactContextInBackground();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
174
225
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import com.facebook.react.ReactPackage
|
|
5
|
+
import com.facebook.react.bridge.NativeModule
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.uimanager.ReactShadowNode
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager
|
|
9
|
+
import com.guichaguri.trackplayer.module.MusicModule
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* TrackPlayer
|
|
13
|
+
* https://github.com/react-native-kit/react-native-track-player
|
|
14
|
+
* @author Guichaguri
|
|
15
|
+
*/
|
|
16
|
+
class TrackPlayer : ReactPackage {
|
|
17
|
+
|
|
18
|
+
override fun createViewManagers(
|
|
19
|
+
reactContext: ReactApplicationContext
|
|
20
|
+
): MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()
|
|
21
|
+
|
|
22
|
+
override fun createNativeModules(
|
|
23
|
+
reactContext: ReactApplicationContext
|
|
24
|
+
): MutableList<NativeModule> = listOf(MusicModule(reactContext)).toMutableList()
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.extensions
|
|
2
|
+
|
|
3
|
+
import com.guichaguri.trackplayer.kotlinaudio.models.AudioPlayerState
|
|
4
|
+
import com.guichaguri.trackplayer.model.State
|
|
5
|
+
|
|
6
|
+
val AudioPlayerState.asLibState: State
|
|
7
|
+
get() {
|
|
8
|
+
return when(this) {
|
|
9
|
+
AudioPlayerState.LOADING -> State.Loading
|
|
10
|
+
AudioPlayerState.READY -> State.Ready
|
|
11
|
+
AudioPlayerState.BUFFERING -> State.Buffering
|
|
12
|
+
AudioPlayerState.PAUSED -> State.Paused
|
|
13
|
+
AudioPlayerState.PLAYING -> State.Playing
|
|
14
|
+
AudioPlayerState.IDLE -> State.None
|
|
15
|
+
AudioPlayerState.ENDED -> State.Ended
|
|
16
|
+
AudioPlayerState.ERROR -> State.Error
|
|
17
|
+
AudioPlayerState.STOPPED -> State.Stopped
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.event
|
|
2
|
+
|
|
3
|
+
class EventHolder internal constructor(private val notificationEventHolder: NotificationEventHolder, private val playerEventHolder: PlayerEventHolder) {
|
|
4
|
+
val audioItemTransition
|
|
5
|
+
get() = playerEventHolder.audioItemTransition
|
|
6
|
+
|
|
7
|
+
val notificationStateChange
|
|
8
|
+
get() = notificationEventHolder.notificationStateChange
|
|
9
|
+
|
|
10
|
+
val onAudioFocusChanged
|
|
11
|
+
get() = playerEventHolder.onAudioFocusChanged
|
|
12
|
+
|
|
13
|
+
val onPlaybackMetadata
|
|
14
|
+
get() = playerEventHolder.onPlaybackMetadata
|
|
15
|
+
|
|
16
|
+
val onPlayerActionTriggeredExternally
|
|
17
|
+
get() = playerEventHolder.onPlayerActionTriggeredExternally
|
|
18
|
+
|
|
19
|
+
val playbackEnd
|
|
20
|
+
get() = playerEventHolder.playbackEnd
|
|
21
|
+
|
|
22
|
+
val playWhenReadyChange
|
|
23
|
+
get() = playerEventHolder.playWhenReadyChange
|
|
24
|
+
|
|
25
|
+
val stateChange
|
|
26
|
+
get() = playerEventHolder.stateChange
|
|
27
|
+
|
|
28
|
+
val playbackError
|
|
29
|
+
get() = playerEventHolder.playbackError
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.event
|
|
2
|
+
|
|
3
|
+
import com.guichaguri.trackplayer.kotlinaudio.models.NotificationState
|
|
4
|
+
import kotlinx.coroutines.MainScope
|
|
5
|
+
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
6
|
+
import kotlinx.coroutines.flow.asSharedFlow
|
|
7
|
+
import kotlinx.coroutines.launch
|
|
8
|
+
|
|
9
|
+
class NotificationEventHolder {
|
|
10
|
+
private val coroutineScope = MainScope()
|
|
11
|
+
|
|
12
|
+
private var _notificationStateChange = MutableSharedFlow<NotificationState>(1)
|
|
13
|
+
var notificationStateChange = _notificationStateChange.asSharedFlow()
|
|
14
|
+
|
|
15
|
+
internal fun updateNotificationState(state: NotificationState) {
|
|
16
|
+
coroutineScope.launch {
|
|
17
|
+
_notificationStateChange.emit(state)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/PlayerEventHolder.kt
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.event
|
|
2
|
+
|
|
3
|
+
// import com.doublesymmetry.kotlinaudio.models.*
|
|
4
|
+
import com.guichaguri.trackplayer.kotlinaudio.models.*
|
|
5
|
+
import kotlinx.coroutines.MainScope
|
|
6
|
+
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
7
|
+
import kotlinx.coroutines.flow.asSharedFlow
|
|
8
|
+
import kotlinx.coroutines.launch
|
|
9
|
+
|
|
10
|
+
class PlayerEventHolder {
|
|
11
|
+
private val coroutineScope = MainScope()
|
|
12
|
+
|
|
13
|
+
private var _stateChange = MutableSharedFlow<AudioPlayerState>(1)
|
|
14
|
+
var stateChange = _stateChange.asSharedFlow()
|
|
15
|
+
|
|
16
|
+
private var _playbackEnd = MutableSharedFlow<PlaybackEndedReason?>(1)
|
|
17
|
+
var playbackEnd = _playbackEnd.asSharedFlow()
|
|
18
|
+
|
|
19
|
+
private var _playbackError = MutableSharedFlow<PlaybackError>(1)
|
|
20
|
+
var playbackError = _playbackError.asSharedFlow()
|
|
21
|
+
|
|
22
|
+
private var _playWhenReadyChange = MutableSharedFlow<PlayWhenReadyChangeData>(1)
|
|
23
|
+
/**
|
|
24
|
+
* Use these events to track when [com.doublesymmetry.kotlinaudio.players.BaseAudioPlayer.playWhenReady]
|
|
25
|
+
* changes.
|
|
26
|
+
*/
|
|
27
|
+
var playWhenReadyChange = _playWhenReadyChange.asSharedFlow()
|
|
28
|
+
|
|
29
|
+
private var _audioItemTransition = MutableSharedFlow<AudioItemTransitionReason?>(1)
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Use these events to track when and why an [AudioItem] transitions to another.
|
|
33
|
+
*
|
|
34
|
+
* Examples of an audio transition include changes to [AudioItem] queue, an [AudioItem] on repeat, skipping an [AudioItem], or simply when the [AudioItem] has finished.
|
|
35
|
+
*/
|
|
36
|
+
var audioItemTransition = _audioItemTransition.asSharedFlow()
|
|
37
|
+
|
|
38
|
+
private var _positionChanged = MutableSharedFlow<PositionChangedReason?>(1)
|
|
39
|
+
var positionChanged = _positionChanged.asSharedFlow()
|
|
40
|
+
|
|
41
|
+
private var _onAudioFocusChanged = MutableSharedFlow<FocusChangeData>(1)
|
|
42
|
+
var onAudioFocusChanged = _onAudioFocusChanged.asSharedFlow()
|
|
43
|
+
|
|
44
|
+
private var _onPlaybackMetadata = MutableSharedFlow<PlaybackMetadata>(1)
|
|
45
|
+
var onPlaybackMetadata = _onPlaybackMetadata.asSharedFlow()
|
|
46
|
+
|
|
47
|
+
private var _onPlayerActionTriggeredExternally = MutableSharedFlow<MediaSessionCallback>()
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Use these events to track whenever a player action has been triggered from an outside source.
|
|
51
|
+
*
|
|
52
|
+
* The sources can be: media buttons on headphones, Android Wear, Android Auto, Google Assistant, media notification, etc.
|
|
53
|
+
*
|
|
54
|
+
* For this observable to send events, set [interceptPlayerActionsTriggeredExternally][com.doublesymmetry.kotlinaudio.models.PlayerConfig.interceptPlayerActionsTriggeredExternally] to true.
|
|
55
|
+
*/
|
|
56
|
+
var onPlayerActionTriggeredExternally = _onPlayerActionTriggeredExternally.asSharedFlow()
|
|
57
|
+
|
|
58
|
+
internal fun updateAudioPlayerState(state: AudioPlayerState) {
|
|
59
|
+
coroutineScope.launch {
|
|
60
|
+
_stateChange.emit(state)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
internal fun updatePlaybackEndedReason(reason: PlaybackEndedReason) {
|
|
65
|
+
coroutineScope.launch {
|
|
66
|
+
_playbackEnd.emit(reason)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
internal fun updatePlayWhenReadyChange(playWhenReadyChange: PlayWhenReadyChangeData) {
|
|
71
|
+
coroutineScope.launch {
|
|
72
|
+
_playWhenReadyChange.emit(playWhenReadyChange)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
internal fun updateAudioItemTransition(reason: AudioItemTransitionReason) {
|
|
77
|
+
coroutineScope.launch {
|
|
78
|
+
_audioItemTransition.emit(reason)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
internal fun updatePositionChangedReason(reason: PositionChangedReason) {
|
|
83
|
+
coroutineScope.launch {
|
|
84
|
+
_positionChanged.emit(reason)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
internal fun updateOnAudioFocusChanged(isPaused: Boolean, isPermanent: Boolean) {
|
|
89
|
+
coroutineScope.launch {
|
|
90
|
+
_onAudioFocusChanged.emit(FocusChangeData(isPaused, isPermanent))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
internal fun updateOnPlaybackMetadata(metadata: PlaybackMetadata) {
|
|
95
|
+
coroutineScope.launch {
|
|
96
|
+
_onPlaybackMetadata.emit(metadata)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
internal fun updatePlaybackError(error: PlaybackError) {
|
|
101
|
+
coroutineScope.launch {
|
|
102
|
+
_playbackError.emit(error)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
internal fun updateOnPlayerActionTriggeredExternally(callback: MediaSessionCallback) {
|
|
107
|
+
coroutineScope.launch {
|
|
108
|
+
_onPlayerActionTriggeredExternally.emit(callback)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.models
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle
|
|
4
|
+
|
|
5
|
+
interface AAMediaSessionCallBack {
|
|
6
|
+
fun handlePlayFromMediaId(mediaId: String?, extras: Bundle?)
|
|
7
|
+
fun handlePlayFromSearch(query: String?, extras: Bundle?)
|
|
8
|
+
fun handleSkipToQueueItem(id: Long)
|
|
9
|
+
fun handleCustomActions(action: String?, extras: Bundle?)
|
|
10
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.models
|
|
2
|
+
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
|
|
5
|
+
interface AudioItem {
|
|
6
|
+
var audioUrl: String
|
|
7
|
+
val type: MediaType
|
|
8
|
+
var artist: String?
|
|
9
|
+
var title: String?
|
|
10
|
+
var albumTitle: String?
|
|
11
|
+
val artwork: String?
|
|
12
|
+
val duration: Long
|
|
13
|
+
val options: AudioItemOptions?
|
|
14
|
+
var artworkBitmap: Bitmap?
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
data class AudioItemOptions(
|
|
18
|
+
val headers: MutableMap<String, String>? = null,
|
|
19
|
+
val userAgent: String? = null,
|
|
20
|
+
val resourceId: Int? = null
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
enum class MediaType(val value: String) {
|
|
24
|
+
/**
|
|
25
|
+
* The default media type. Should be used for streams over HTTP or files
|
|
26
|
+
*/
|
|
27
|
+
DEFAULT("default"),
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The DASH media type for adaptive streams. Should be used with DASH manifests.
|
|
31
|
+
*/
|
|
32
|
+
DASH("dash"),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The HLS media type for adaptive streams. Should be used with HLS playlists.
|
|
36
|
+
*/
|
|
37
|
+
HLS("hls"),
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The SmoothStreaming media type for adaptive streams. Should be used with SmoothStreaming manifests.
|
|
41
|
+
*/
|
|
42
|
+
SMOOTH_STREAMING("smoothstreaming");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
data class DefaultAudioItem(
|
|
46
|
+
override var audioUrl: String,
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set to [MediaType.DEFAULT] by default.
|
|
50
|
+
*/
|
|
51
|
+
override val type: MediaType = MediaType.DEFAULT,
|
|
52
|
+
|
|
53
|
+
override var artist: String? = null,
|
|
54
|
+
override var title: String? = null,
|
|
55
|
+
override var albumTitle: String? = null,
|
|
56
|
+
override val artwork: String? = null,
|
|
57
|
+
override val duration: Long = -1,
|
|
58
|
+
override val options: AudioItemOptions? = null,
|
|
59
|
+
override var artworkBitmap: Bitmap? = null
|
|
60
|
+
) : AudioItem
|
|
61
|
+
|
|
62
|
+
class AudioItemHolder(
|
|
63
|
+
var audioItem: AudioItem
|
|
64
|
+
) {
|
|
65
|
+
var artworkBitmap: Bitmap? = null
|
|
66
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.models
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Use these events to track when and why an [AudioItem] transitions to another.
|
|
5
|
+
* Examples of an audio transition include changes to [AudioItem] queue, an [AudioItem] on repeat, skipping an [AudioItem], or simply when the [AudioItem] has finished.
|
|
6
|
+
*/
|
|
7
|
+
sealed class AudioItemTransitionReason(val oldPosition: Long) {
|
|
8
|
+
/**
|
|
9
|
+
* Playback has automatically transitioned to the next [AudioItem].
|
|
10
|
+
*
|
|
11
|
+
* This reason also indicates a transition caused by another player.
|
|
12
|
+
*/
|
|
13
|
+
class AUTO(oldPosition: Long) : AudioItemTransitionReason(oldPosition)
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A seek to another [AudioItem] has occurred. Usually triggered when calling
|
|
17
|
+
* [QueuedAudioPlayer.next][com.doublesymmetry.kotlinaudio.players.QueuedAudioPlayer.next]
|
|
18
|
+
* or [QueuedAudioPlayer.previous][com.doublesymmetry.kotlinaudio.players.QueuedAudioPlayer.previous].
|
|
19
|
+
*/
|
|
20
|
+
class SEEK_TO_ANOTHER_AUDIO_ITEM(oldPosition: Long) : AudioItemTransitionReason(oldPosition)
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The [AudioItem] has been repeated.
|
|
24
|
+
*/
|
|
25
|
+
class REPEAT(oldPosition: Long) : AudioItemTransitionReason(oldPosition)
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The current [AudioItem] has changed because of a change in the queue. This can either be if
|
|
29
|
+
* the [AudioItem] previously being played has been removed, or when the queue becomes non-empty
|
|
30
|
+
* after being empty.
|
|
31
|
+
*/
|
|
32
|
+
class QUEUE_CHANGED(oldPosition: Long) : AudioItemTransitionReason(oldPosition)
|
|
33
|
+
}
|
package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioPlayerState.kt
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package com.guichaguri.trackplayer.kotlinaudio.models
|
|
2
|
+
|
|
3
|
+
enum class AudioPlayerState {
|
|
4
|
+
/** The current [AudioItem] is being loaded for playback. */
|
|
5
|
+
LOADING,
|
|
6
|
+
|
|
7
|
+
/** The current [AudioItem] is loaded, and the player is ready to start playing. */
|
|
8
|
+
READY,
|
|
9
|
+
|
|
10
|
+
/** The current [AudioItem] is currently buffering. */
|
|
11
|
+
BUFFERING,
|
|
12
|
+
|
|
13
|
+
/** The player is paused. */
|
|
14
|
+
PAUSED,
|
|
15
|
+
|
|
16
|
+
/** The player is stopped. */
|
|
17
|
+
STOPPED,
|
|
18
|
+
|
|
19
|
+
/** The player is playing. */
|
|
20
|
+
PLAYING,
|
|
21
|
+
|
|
22
|
+
/** No [AudioItem] is loaded and the player is doing nothing. */
|
|
23
|
+
IDLE,
|
|
24
|
+
|
|
25
|
+
/** The player has finished playing all the [AudioItem]s. TODO: Add additional info */
|
|
26
|
+
ENDED,
|
|
27
|
+
|
|
28
|
+
/** The player stopped playing due to an error. */
|
|
29
|
+
ERROR
|
|
30
|
+
}
|