react-native-nitro-player 1.7.0-alpha.2 → 1.7.0-alpha.4
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/README.md +9 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridPlayerQueue.kt +45 -7
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerAudioFocus.kt +65 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +46 -14
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerListener.kt +2 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerPlayback.kt +36 -12
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueue.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueueBuild.kt +16 -6
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerUrlLoader.kt +7 -3
- package/android/src/main/java/com/margelo/nitro/nitroplayer/media/AudioFocusController.kt +87 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/media/ExoPlayerBuilder.kt +3 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaSessionManager.kt +8 -2
- package/android/src/main/java/com/margelo/nitro/nitroplayer/media/PlaybackService.kt +26 -1
- package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +60 -0
- package/ios/cast/CastQueueDiff.swift +58 -0
- package/ios/cast/CastQueueReconciler.swift +228 -0
- package/ios/core/CastSessionManager.swift +215 -31
- package/ios/core/TrackPlayerCast.swift +96 -65
- package/ios/core/TrackPlayerCore.swift +31 -0
- package/ios/core/TrackPlayerListener.swift +19 -3
- package/ios/core/TrackPlayerPlayback.swift +12 -10
- package/ios/core/TrackPlayerQueue.swift +10 -2
- package/ios/core/TrackPlayerQueueBuild.swift +21 -9
- package/ios/core/TrackPlayerTempQueue.swift +27 -15
- package/ios/core/TrackPlayerUrlLoader.swift +6 -2
- package/ios/playlist/PlaylistManager.swift +60 -1
- package/ios/queue/HybridPlayerQueue.swift +40 -13
- package/lib/hooks/callbackManager.d.ts +2 -0
- package/lib/hooks/callbackManager.js +23 -8
- package/lib/specs/TrackPlayer.nitro.d.ts +5 -1
- package/lib/types/PlayerQueue.d.ts +14 -0
- package/nitrogen/generated/android/c++/JAndroidAudioFocusMode.hpp +61 -0
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +43 -0
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.hpp +2 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +4 -0
- package/nitrogen/generated/android/c++/JPlayerConfig.hpp +9 -3
- package/nitrogen/generated/android/c++/JShufflePlaylistOptions.hpp +57 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/AndroidAudioFocusMode.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt +8 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlayerConfig.kt +6 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/ShufflePlaylistOptions.kt +38 -0
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +36 -0
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Umbrella.hpp +6 -0
- package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.hpp +19 -0
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/swift/AndroidAudioFocusMode.swift +44 -0
- package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec_cxx.swift +38 -0
- package/nitrogen/generated/ios/swift/PlayerConfig.swift +12 -1
- package/nitrogen/generated/ios/swift/ShufflePlaylistOptions.swift +42 -0
- package/nitrogen/generated/shared/c++/AndroidAudioFocusMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.hpp +5 -0
- package/nitrogen/generated/shared/c++/PlayerConfig.hpp +9 -3
- package/nitrogen/generated/shared/c++/ShufflePlaylistOptions.hpp +83 -0
- package/package.json +1 -1
- package/src/hooks/callbackManager.ts +25 -10
- package/src/specs/TrackPlayer.nitro.ts +11 -0
- package/src/types/PlayerQueue.ts +17 -0
|
@@ -14,6 +14,7 @@ class PlaylistManager {
|
|
|
14
14
|
private var listeners: [(String, ([PlaylistModel], QueueOperation?) -> Void)] = []
|
|
15
15
|
private var playlistListeners: [String: [(String, (PlaylistModel, QueueOperation?) -> Void)]] =
|
|
16
16
|
[:]
|
|
17
|
+
private var anyPlaylistListeners: [(String, (PlaylistModel, QueueOperation?) -> Void)] = []
|
|
17
18
|
// Backing store must only be touched inside `queue`; every current use of the
|
|
18
19
|
// computed property is outside a queue.sync block, so the accessors can sync.
|
|
19
20
|
private var _currentPlaylistId: String?
|
|
@@ -257,6 +258,48 @@ class PlaylistManager {
|
|
|
257
258
|
return true
|
|
258
259
|
}
|
|
259
260
|
|
|
261
|
+
/// Removed count; nil when the playlist does not exist. Unknown ids are ignored.
|
|
262
|
+
func removeTracksFromPlaylist(playlistId: String, trackIds: [String]) -> Int? {
|
|
263
|
+
let ids = Set(trackIds)
|
|
264
|
+
let removed: Int? = queue.sync {
|
|
265
|
+
guard let playlist = playlists[playlistId] else { return nil }
|
|
266
|
+
let tracks = playlist.tracks.filter { !ids.contains($0.id) }
|
|
267
|
+
let count = playlist.tracks.count - tracks.count
|
|
268
|
+
if count > 0 {
|
|
269
|
+
playlists[playlistId] = PlaylistModel(
|
|
270
|
+
id: playlist.id, name: playlist.name, description: playlist.description,
|
|
271
|
+
artwork: playlist.artwork, tracks: tracks)
|
|
272
|
+
}
|
|
273
|
+
return count
|
|
274
|
+
}
|
|
275
|
+
if let removed, removed > 0 {
|
|
276
|
+
scheduleSave()
|
|
277
|
+
notifyPlaylistChanged(playlistId, .remove)
|
|
278
|
+
}
|
|
279
|
+
return removed
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/// Fisher-Yates; `firstTrackId` is pinned at index 0. Nil when the playlist does not exist.
|
|
283
|
+
func shufflePlaylist(playlistId: String, firstTrackId: String?) -> Bool? {
|
|
284
|
+
let changed: Bool? = queue.sync {
|
|
285
|
+
guard let playlist = playlists[playlistId] else { return nil }
|
|
286
|
+
var tracks = playlist.tracks
|
|
287
|
+
let pinned = tracks.firstIndex { $0.id == firstTrackId }.map { tracks.remove(at: $0) }
|
|
288
|
+
tracks.shuffle()
|
|
289
|
+
if let pinned { tracks.insert(pinned, at: 0) }
|
|
290
|
+
guard tracks.map(\.id) != playlist.tracks.map(\.id) else { return false }
|
|
291
|
+
playlists[playlistId] = PlaylistModel(
|
|
292
|
+
id: playlist.id, name: playlist.name, description: playlist.description,
|
|
293
|
+
artwork: playlist.artwork, tracks: tracks)
|
|
294
|
+
return true
|
|
295
|
+
}
|
|
296
|
+
if changed == true {
|
|
297
|
+
scheduleSave()
|
|
298
|
+
notifyPlaylistChanged(playlistId, .update)
|
|
299
|
+
}
|
|
300
|
+
return changed
|
|
301
|
+
}
|
|
302
|
+
|
|
260
303
|
/**
|
|
261
304
|
* Load a playlist for playback (sets it as current)
|
|
262
305
|
*/
|
|
@@ -343,6 +386,11 @@ class PlaylistManager {
|
|
|
343
386
|
return trackIds.compactMap { foundTracks[$0] }
|
|
344
387
|
}
|
|
345
388
|
|
|
389
|
+
/// Mirrors the core's current playlist; playSong bypasses loadPlaylist.
|
|
390
|
+
func setCurrentPlaylistId(_ playlistId: String?) {
|
|
391
|
+
currentPlaylistId = playlistId
|
|
392
|
+
}
|
|
393
|
+
|
|
346
394
|
/**
|
|
347
395
|
* Get the current playlist ID
|
|
348
396
|
*/
|
|
@@ -403,11 +451,22 @@ class PlaylistManager {
|
|
|
403
451
|
currentListeners.forEach { $0.1(allPlaylists, operation) }
|
|
404
452
|
}
|
|
405
453
|
|
|
454
|
+
/// Fires for ANY playlist, including ones created after registration.
|
|
455
|
+
func addAnyPlaylistChangeListener(
|
|
456
|
+
listener: @escaping (PlaylistModel, QueueOperation?) -> Void
|
|
457
|
+
) -> () -> Void {
|
|
458
|
+
let listenerId = UUID().uuidString
|
|
459
|
+
queue.sync { anyPlaylistListeners.append((listenerId, listener)) }
|
|
460
|
+
return {
|
|
461
|
+
self.queue.sync { self.anyPlaylistListeners.removeAll { $0.0 == listenerId } }
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
406
465
|
private func notifyPlaylistChanged(_ playlistId: String, _ operation: QueueOperation?) {
|
|
407
466
|
let result: (PlaylistModel, [(String, (PlaylistModel, QueueOperation?) -> Void)])? = queue.sync
|
|
408
467
|
{
|
|
409
468
|
guard let p = playlists[playlistId] else { return nil }
|
|
410
|
-
return (p, playlistListeners[playlistId] ?? [])
|
|
469
|
+
return (p, (playlistListeners[playlistId] ?? []) + anyPlaylistListeners)
|
|
411
470
|
}
|
|
412
471
|
|
|
413
472
|
guard let (playlist, currentListeners) = result else { return }
|
|
@@ -73,14 +73,9 @@ final class HybridPlayerQueue: HybridPlayerQueueSpec {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/// Same semantics as the batch form: unknown ids are skipped, only a missing playlist rejects.
|
|
76
77
|
func removeTrackFromPlaylist(playlistId: String, trackId: String) throws -> Promise<Void> {
|
|
77
|
-
|
|
78
|
-
guard self.playlistManager.removeTrackFromPlaylist(playlistId: playlistId, trackId: trackId)
|
|
79
|
-
else {
|
|
80
|
-
throw RuntimeError.error(withMessage: "Track \(trackId) not found in playlist \(playlistId)")
|
|
81
|
-
}
|
|
82
|
-
self.core.updatePlaylist(playlistId: playlistId)
|
|
83
|
-
}
|
|
78
|
+
try removeTracksFromPlaylist(playlistId: playlistId, trackIds: [trackId])
|
|
84
79
|
}
|
|
85
80
|
|
|
86
81
|
func reorderTrackInPlaylist(playlistId: String, trackId: String, newIndex: Double) throws -> Promise<Void> {
|
|
@@ -94,6 +89,40 @@ final class HybridPlayerQueue: HybridPlayerQueueSpec {
|
|
|
94
89
|
}
|
|
95
90
|
}
|
|
96
91
|
|
|
92
|
+
/// On the player queue: the live queue must reflect the removal before the promise resolves.
|
|
93
|
+
func removeTracksFromPlaylist(playlistId: String, trackIds: [String]) throws -> Promise<Void> {
|
|
94
|
+
let promise = Promise<Void>()
|
|
95
|
+
core.playerQueue.async {
|
|
96
|
+
guard let removed = self.playlistManager.removeTracksFromPlaylist(playlistId: playlistId, trackIds: trackIds) else {
|
|
97
|
+
promise.reject(withError: RuntimeError.error(withMessage: "Playlist not found: \(playlistId)"))
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
if removed > 0, self.core.currentPlaylistId == playlistId {
|
|
101
|
+
self.core.syncCurrentPlaylistOnQueue(playlistId: playlistId)
|
|
102
|
+
}
|
|
103
|
+
promise.resolve(withResult: ())
|
|
104
|
+
}
|
|
105
|
+
return promise
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/// On the player queue: the anchor id is player-queue state.
|
|
109
|
+
func shufflePlaylist(playlistId: String, options: ShufflePlaylistOptions?) throws -> Promise<Void> {
|
|
110
|
+
let promise = Promise<Void>()
|
|
111
|
+
core.playerQueue.async {
|
|
112
|
+
let isCurrent = self.core.currentPlaylistId == playlistId
|
|
113
|
+
let pin: String? =
|
|
114
|
+
(isCurrent && options?.keepCurrentTrackFirst != false)
|
|
115
|
+
? self.core.currentTracks[safe: self.core.currentTrackIndex]?.id : nil
|
|
116
|
+
guard let changed = self.playlistManager.shufflePlaylist(playlistId: playlistId, firstTrackId: pin) else {
|
|
117
|
+
promise.reject(withError: RuntimeError.error(withMessage: "Playlist not found: \(playlistId)"))
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
if changed, isCurrent { self.core.syncCurrentPlaylistOnQueue(playlistId: playlistId) }
|
|
121
|
+
promise.resolve(withResult: ())
|
|
122
|
+
}
|
|
123
|
+
return promise
|
|
124
|
+
}
|
|
125
|
+
|
|
97
126
|
// MARK: - Playback control
|
|
98
127
|
|
|
99
128
|
/// Enqueued synchronously on the player queue so a `loadPlaylist()` followed by
|
|
@@ -130,13 +159,11 @@ final class HybridPlayerQueue: HybridPlayerQueueSpec {
|
|
|
130
159
|
}
|
|
131
160
|
|
|
132
161
|
func onPlaylistChanged(callback: @escaping (_ playlistId: String, _ playlist: Playlist, _ operation: QueueOperation?) -> Void) throws {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
callback(updated.id, updated.toGeneratedPlaylist(), operation)
|
|
137
|
-
}
|
|
138
|
-
playlistChangeRemovers.append(remover)
|
|
162
|
+
// Manager-level listener: covers playlists created after registration.
|
|
163
|
+
let remover = playlistManager.addAnyPlaylistChangeListener { updated, operation in
|
|
164
|
+
callback(updated.id, updated.toGeneratedPlaylist(), operation)
|
|
139
165
|
}
|
|
166
|
+
playlistChangeRemovers.append(remover)
|
|
140
167
|
}
|
|
141
168
|
|
|
142
169
|
// MARK: - Cleanup
|
|
@@ -21,6 +21,7 @@ declare class CallbackSubscriptionManager {
|
|
|
21
21
|
private playlistsChangedSubscribers;
|
|
22
22
|
private androidAutoConnectionSubscribers;
|
|
23
23
|
private isPlaylistsChangedRegistered;
|
|
24
|
+
private playlistsChangedFanOutScheduled;
|
|
24
25
|
private isAndroidAutoConnectionRegistered;
|
|
25
26
|
private isPlaybackStateRegistered;
|
|
26
27
|
private isTrackChangeRegistered;
|
|
@@ -61,6 +62,7 @@ declare class CallbackSubscriptionManager {
|
|
|
61
62
|
* @returns Unsubscribe function
|
|
62
63
|
*/
|
|
63
64
|
subscribeToPlaylistsChanged(callback: () => void): () => void;
|
|
65
|
+
private schedulePlaylistsChangedFanOut;
|
|
64
66
|
private ensurePlaylistsChangedRegistered;
|
|
65
67
|
private ensureTemporaryQueueRegistered;
|
|
66
68
|
private ensureSeekRegistered;
|
|
@@ -14,6 +14,7 @@ class CallbackSubscriptionManager {
|
|
|
14
14
|
playlistsChangedSubscribers = new Set();
|
|
15
15
|
androidAutoConnectionSubscribers = new Set();
|
|
16
16
|
isPlaylistsChangedRegistered = false;
|
|
17
|
+
playlistsChangedFanOutScheduled = false;
|
|
17
18
|
isAndroidAutoConnectionRegistered = false;
|
|
18
19
|
isPlaybackStateRegistered = false;
|
|
19
20
|
isTrackChangeRegistered = false;
|
|
@@ -147,19 +148,33 @@ class CallbackSubscriptionManager {
|
|
|
147
148
|
this.playlistsChangedSubscribers.delete(callback);
|
|
148
149
|
};
|
|
149
150
|
}
|
|
151
|
+
// Task-level, not a microtask: native callbacks arrive as separate JS tasks.
|
|
152
|
+
schedulePlaylistsChangedFanOut() {
|
|
153
|
+
if (this.playlistsChangedFanOutScheduled)
|
|
154
|
+
return;
|
|
155
|
+
this.playlistsChangedFanOutScheduled = true;
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
this.playlistsChangedFanOutScheduled = false;
|
|
158
|
+
this.playlistsChangedSubscribers.forEach((subscriber) => {
|
|
159
|
+
try {
|
|
160
|
+
subscriber();
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error('[CallbackManager] Error in playlists changed subscriber:', error);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}, 0);
|
|
167
|
+
}
|
|
150
168
|
ensurePlaylistsChangedRegistered() {
|
|
151
169
|
if (this.isPlaylistsChangedRegistered)
|
|
152
170
|
return;
|
|
153
171
|
try {
|
|
154
172
|
PlayerQueue.onPlaylistsChanged(() => {
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
console.error('[CallbackManager] Error in playlists changed subscriber:', error);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
173
|
+
this.schedulePlaylistsChangedFanOut();
|
|
174
|
+
});
|
|
175
|
+
// Track-level mutations only fire the per-playlist event.
|
|
176
|
+
PlayerQueue.onPlaylistChanged(() => {
|
|
177
|
+
this.schedulePlaylistsChangedFanOut();
|
|
163
178
|
});
|
|
164
179
|
this.isPlaylistsChangedRegistered = true;
|
|
165
180
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
import type { QueueOperation, Reason, TrackItem, TrackPlayerState, PlayerState, PlayerConfig, Playlist, TimedMetadata } from '../types/PlayerQueue';
|
|
2
|
+
import type { QueueOperation, Reason, TrackItem, TrackPlayerState, PlayerState, PlayerConfig, Playlist, TimedMetadata, ShufflePlaylistOptions } from '../types/PlayerQueue';
|
|
3
3
|
export interface PlayerQueue extends HybridObject<{
|
|
4
4
|
android: 'kotlin';
|
|
5
5
|
ios: 'swift';
|
|
@@ -13,6 +13,10 @@ export interface PlayerQueue extends HybridObject<{
|
|
|
13
13
|
addTracksToPlaylist(playlistId: string, tracks: TrackItem[], index?: number): Promise<void>;
|
|
14
14
|
removeTrackFromPlaylist(playlistId: string, trackId: string): Promise<void>;
|
|
15
15
|
reorderTrackInPlaylist(playlistId: string, trackId: string, newIndex: number): Promise<void>;
|
|
16
|
+
/** One native pass. Unknown ids are skipped; rejects only if the playlist does not exist. */
|
|
17
|
+
removeTracksFromPlaylist(playlistId: string, trackIds: string[]): Promise<void>;
|
|
18
|
+
/** Fisher-Yates shuffle of the stored playlist, persisted. Never interrupts the playing item. */
|
|
19
|
+
shufflePlaylist(playlistId: string, options?: ShufflePlaylistOptions): Promise<void>;
|
|
16
20
|
loadPlaylist(playlistId: string, index?: number): Promise<void>;
|
|
17
21
|
getCurrentPlaylistId(): string | null;
|
|
18
22
|
onPlaylistsChanged(callback: (playlists: Playlist[], operation?: QueueOperation) => void): void;
|
|
@@ -18,6 +18,10 @@ export interface Playlist {
|
|
|
18
18
|
tracks: TrackItem[];
|
|
19
19
|
}
|
|
20
20
|
export type QueueOperation = 'add' | 'remove' | 'clear' | 'update';
|
|
21
|
+
export interface ShufflePlaylistOptions {
|
|
22
|
+
/** Move the playing track to index 0 and shuffle the rest behind it (default: true). */
|
|
23
|
+
keepCurrentTrackFirst?: boolean;
|
|
24
|
+
}
|
|
21
25
|
export type TrackPlayerState = 'playing' | 'paused' | 'stopped' | 'buffering';
|
|
22
26
|
export type Reason = 'user_action' | 'skip' | 'end' | 'error' | 'repeat';
|
|
23
27
|
export interface PlayerState {
|
|
@@ -44,6 +48,14 @@ export interface TimedMetadata {
|
|
|
44
48
|
/** Artwork URL the stream tagged as artwork, when it sends one explicitly */
|
|
45
49
|
artworkUrl?: string;
|
|
46
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* How Android reacts when another app takes audio focus.
|
|
53
|
+
* - 'pause': pause for any interruption and resume after it (default, today's behaviour)
|
|
54
|
+
* - 'duck': keep playing at a reduced volume through transient interruptions
|
|
55
|
+
* - 'ignore': never react to audio focus at all
|
|
56
|
+
* iOS ignores this option.
|
|
57
|
+
*/
|
|
58
|
+
export type AndroidAudioFocusMode = 'pause' | 'duck' | 'ignore';
|
|
47
59
|
export interface PlayerConfig {
|
|
48
60
|
androidAutoEnabled?: boolean;
|
|
49
61
|
carPlayEnabled?: boolean;
|
|
@@ -62,4 +74,6 @@ export interface PlayerConfig {
|
|
|
62
74
|
*/
|
|
63
75
|
lookaheadCount?: number;
|
|
64
76
|
androidNotificationIcon?: string;
|
|
77
|
+
/** How Android reacts when another app takes audio focus (default: 'pause'). */
|
|
78
|
+
androidAudioFocus?: AndroidAudioFocusMode;
|
|
65
79
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JAndroidAudioFocusMode.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "AndroidAudioFocusMode.hpp"
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro::nitroplayer {
|
|
14
|
+
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The C++ JNI bridge between the C++ enum "AndroidAudioFocusMode" and the the Kotlin enum "AndroidAudioFocusMode".
|
|
19
|
+
*/
|
|
20
|
+
struct JAndroidAudioFocusMode final: public jni::JavaClass<JAndroidAudioFocusMode> {
|
|
21
|
+
public:
|
|
22
|
+
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/nitroplayer/AndroidAudioFocusMode;";
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
/**
|
|
26
|
+
* Convert this Java/Kotlin-based enum to the C++ enum AndroidAudioFocusMode.
|
|
27
|
+
*/
|
|
28
|
+
[[maybe_unused]]
|
|
29
|
+
[[nodiscard]]
|
|
30
|
+
AndroidAudioFocusMode toCpp() const {
|
|
31
|
+
static const auto clazz = javaClassStatic();
|
|
32
|
+
static const auto fieldOrdinal = clazz->getField<int>("value");
|
|
33
|
+
int ordinal = this->getFieldValue(fieldOrdinal);
|
|
34
|
+
return static_cast<AndroidAudioFocusMode>(ordinal);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public:
|
|
38
|
+
/**
|
|
39
|
+
* Create a Java/Kotlin-based enum with the given C++ enum's value.
|
|
40
|
+
*/
|
|
41
|
+
[[maybe_unused]]
|
|
42
|
+
static jni::alias_ref<JAndroidAudioFocusMode> fromCpp(AndroidAudioFocusMode value) {
|
|
43
|
+
static const auto clazz = javaClassStatic();
|
|
44
|
+
switch (value) {
|
|
45
|
+
case AndroidAudioFocusMode::PAUSE:
|
|
46
|
+
static const auto fieldPAUSE = clazz->getStaticField<JAndroidAudioFocusMode>("PAUSE");
|
|
47
|
+
return clazz->getStaticFieldValue(fieldPAUSE);
|
|
48
|
+
case AndroidAudioFocusMode::DUCK:
|
|
49
|
+
static const auto fieldDUCK = clazz->getStaticField<JAndroidAudioFocusMode>("DUCK");
|
|
50
|
+
return clazz->getStaticFieldValue(fieldDUCK);
|
|
51
|
+
case AndroidAudioFocusMode::IGNORE:
|
|
52
|
+
static const auto fieldIGNORE = clazz->getStaticField<JAndroidAudioFocusMode>("IGNORE");
|
|
53
|
+
return clazz->getStaticFieldValue(fieldIGNORE);
|
|
54
|
+
default:
|
|
55
|
+
std::string stringValue = std::to_string(static_cast<int>(value));
|
|
56
|
+
throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
} // namespace margelo::nitro::nitroplayer
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
namespace margelo::nitro::nitroplayer { struct Playlist; }
|
|
12
12
|
// Forward declaration of `TrackItem` to properly resolve imports.
|
|
13
13
|
namespace margelo::nitro::nitroplayer { struct TrackItem; }
|
|
14
|
+
// Forward declaration of `ShufflePlaylistOptions` to properly resolve imports.
|
|
15
|
+
namespace margelo::nitro::nitroplayer { struct ShufflePlaylistOptions; }
|
|
14
16
|
// Forward declaration of `QueueOperation` to properly resolve imports.
|
|
15
17
|
namespace margelo::nitro::nitroplayer { enum class QueueOperation; }
|
|
16
18
|
|
|
@@ -31,6 +33,8 @@ namespace margelo::nitro::nitroplayer { enum class QueueOperation; }
|
|
|
31
33
|
#include "JTrackItem.hpp"
|
|
32
34
|
#include <NitroModules/AnyMap.hpp>
|
|
33
35
|
#include <NitroModules/JAnyMap.hpp>
|
|
36
|
+
#include "ShufflePlaylistOptions.hpp"
|
|
37
|
+
#include "JShufflePlaylistOptions.hpp"
|
|
34
38
|
#include "QueueOperation.hpp"
|
|
35
39
|
#include <functional>
|
|
36
40
|
#include "JFunc_void_std__vector_Playlist__std__optional_QueueOperation_.hpp"
|
|
@@ -205,6 +209,45 @@ namespace margelo::nitro::nitroplayer {
|
|
|
205
209
|
return __promise;
|
|
206
210
|
}();
|
|
207
211
|
}
|
|
212
|
+
std::shared_ptr<Promise<void>> JHybridPlayerQueueSpec::removeTracksFromPlaylist(const std::string& playlistId, const std::vector<std::string>& trackIds) {
|
|
213
|
+
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* playlistId */, jni::alias_ref<jni::JArrayClass<jni::JString>> /* trackIds */)>("removeTracksFromPlaylist");
|
|
214
|
+
auto __result = method(_javaPart, jni::make_jstring(playlistId), [&]() {
|
|
215
|
+
size_t __size = trackIds.size();
|
|
216
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> __array = jni::JArrayClass<jni::JString>::newArray(__size);
|
|
217
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
218
|
+
const auto& __element = trackIds[__i];
|
|
219
|
+
auto __elementJni = jni::make_jstring(__element);
|
|
220
|
+
__array->setElement(__i, *__elementJni);
|
|
221
|
+
}
|
|
222
|
+
return __array;
|
|
223
|
+
}());
|
|
224
|
+
return [&]() {
|
|
225
|
+
auto __promise = Promise<void>::create();
|
|
226
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
227
|
+
__promise->resolve();
|
|
228
|
+
});
|
|
229
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
230
|
+
jni::JniException __jniError(__throwable);
|
|
231
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
232
|
+
});
|
|
233
|
+
return __promise;
|
|
234
|
+
}();
|
|
235
|
+
}
|
|
236
|
+
std::shared_ptr<Promise<void>> JHybridPlayerQueueSpec::shufflePlaylist(const std::string& playlistId, const std::optional<ShufflePlaylistOptions>& options) {
|
|
237
|
+
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* playlistId */, jni::alias_ref<JShufflePlaylistOptions> /* options */)>("shufflePlaylist");
|
|
238
|
+
auto __result = method(_javaPart, jni::make_jstring(playlistId), options.has_value() ? JShufflePlaylistOptions::fromCpp(options.value()) : nullptr);
|
|
239
|
+
return [&]() {
|
|
240
|
+
auto __promise = Promise<void>::create();
|
|
241
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
242
|
+
__promise->resolve();
|
|
243
|
+
});
|
|
244
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
245
|
+
jni::JniException __jniError(__throwable);
|
|
246
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
247
|
+
});
|
|
248
|
+
return __promise;
|
|
249
|
+
}();
|
|
250
|
+
}
|
|
208
251
|
std::shared_ptr<Promise<void>> JHybridPlayerQueueSpec::loadPlaylist(const std::string& playlistId, std::optional<double> index) {
|
|
209
252
|
static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* playlistId */, jni::alias_ref<jni::JDouble> /* index */)>("loadPlaylist");
|
|
210
253
|
auto __result = method(_javaPart, jni::make_jstring(playlistId), index.has_value() ? jni::JDouble::valueOf(index.value()) : nullptr);
|
|
@@ -63,6 +63,8 @@ namespace margelo::nitro::nitroplayer {
|
|
|
63
63
|
std::shared_ptr<Promise<void>> addTracksToPlaylist(const std::string& playlistId, const std::vector<TrackItem>& tracks, std::optional<double> index) override;
|
|
64
64
|
std::shared_ptr<Promise<void>> removeTrackFromPlaylist(const std::string& playlistId, const std::string& trackId) override;
|
|
65
65
|
std::shared_ptr<Promise<void>> reorderTrackInPlaylist(const std::string& playlistId, const std::string& trackId, double newIndex) override;
|
|
66
|
+
std::shared_ptr<Promise<void>> removeTracksFromPlaylist(const std::string& playlistId, const std::vector<std::string>& trackIds) override;
|
|
67
|
+
std::shared_ptr<Promise<void>> shufflePlaylist(const std::string& playlistId, const std::optional<ShufflePlaylistOptions>& options) override;
|
|
66
68
|
std::shared_ptr<Promise<void>> loadPlaylist(const std::string& playlistId, std::optional<double> index) override;
|
|
67
69
|
std::variant<nitro::NullType, std::string> getCurrentPlaylistId() override;
|
|
68
70
|
void onPlaylistsChanged(const std::function<void(const std::vector<Playlist>& /* playlists */, std::optional<QueueOperation> /* operation */)>& callback) override;
|
|
@@ -19,6 +19,8 @@ namespace margelo::nitro::nitroplayer { enum class CurrentPlayingType; }
|
|
|
19
19
|
namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
|
|
20
20
|
// Forward declaration of `PlayerConfig` to properly resolve imports.
|
|
21
21
|
namespace margelo::nitro::nitroplayer { struct PlayerConfig; }
|
|
22
|
+
// Forward declaration of `AndroidAudioFocusMode` to properly resolve imports.
|
|
23
|
+
namespace margelo::nitro::nitroplayer { enum class AndroidAudioFocusMode; }
|
|
22
24
|
// Forward declaration of `Reason` to properly resolve imports.
|
|
23
25
|
namespace margelo::nitro::nitroplayer { enum class Reason; }
|
|
24
26
|
// Forward declaration of `TimedMetadata` to properly resolve imports.
|
|
@@ -49,6 +51,8 @@ namespace margelo::nitro::nitroplayer { struct TimedMetadata; }
|
|
|
49
51
|
#include "JRepeatMode.hpp"
|
|
50
52
|
#include "PlayerConfig.hpp"
|
|
51
53
|
#include "JPlayerConfig.hpp"
|
|
54
|
+
#include "AndroidAudioFocusMode.hpp"
|
|
55
|
+
#include "JAndroidAudioFocusMode.hpp"
|
|
52
56
|
#include "Reason.hpp"
|
|
53
57
|
#include <functional>
|
|
54
58
|
#include "JFunc_void_TrackItem_std__optional_Reason_.hpp"
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
#include <fbjni/fbjni.h>
|
|
11
11
|
#include "PlayerConfig.hpp"
|
|
12
12
|
|
|
13
|
+
#include "AndroidAudioFocusMode.hpp"
|
|
14
|
+
#include "JAndroidAudioFocusMode.hpp"
|
|
13
15
|
#include <optional>
|
|
14
16
|
#include <string>
|
|
15
17
|
|
|
@@ -46,6 +48,8 @@ namespace margelo::nitro::nitroplayer {
|
|
|
46
48
|
jni::local_ref<jni::JDouble> lookaheadCount = this->getFieldValue(fieldLookaheadCount);
|
|
47
49
|
static const auto fieldAndroidNotificationIcon = clazz->getField<jni::JString>("androidNotificationIcon");
|
|
48
50
|
jni::local_ref<jni::JString> androidNotificationIcon = this->getFieldValue(fieldAndroidNotificationIcon);
|
|
51
|
+
static const auto fieldAndroidAudioFocus = clazz->getField<JAndroidAudioFocusMode>("androidAudioFocus");
|
|
52
|
+
jni::local_ref<JAndroidAudioFocusMode> androidAudioFocus = this->getFieldValue(fieldAndroidAudioFocus);
|
|
49
53
|
return PlayerConfig(
|
|
50
54
|
androidAutoEnabled != nullptr ? std::make_optional(static_cast<bool>(androidAutoEnabled->value())) : std::nullopt,
|
|
51
55
|
carPlayEnabled != nullptr ? std::make_optional(static_cast<bool>(carPlayEnabled->value())) : std::nullopt,
|
|
@@ -53,7 +57,8 @@ namespace margelo::nitro::nitroplayer {
|
|
|
53
57
|
remoteSkipForwardInterval != nullptr ? std::make_optional(remoteSkipForwardInterval->value()) : std::nullopt,
|
|
54
58
|
remoteSkipBackwardInterval != nullptr ? std::make_optional(remoteSkipBackwardInterval->value()) : std::nullopt,
|
|
55
59
|
lookaheadCount != nullptr ? std::make_optional(lookaheadCount->value()) : std::nullopt,
|
|
56
|
-
androidNotificationIcon != nullptr ? std::make_optional(androidNotificationIcon->toStdString()) : std::nullopt
|
|
60
|
+
androidNotificationIcon != nullptr ? std::make_optional(androidNotificationIcon->toStdString()) : std::nullopt,
|
|
61
|
+
androidAudioFocus != nullptr ? std::make_optional(androidAudioFocus->toCpp()) : std::nullopt
|
|
57
62
|
);
|
|
58
63
|
}
|
|
59
64
|
|
|
@@ -63,7 +68,7 @@ namespace margelo::nitro::nitroplayer {
|
|
|
63
68
|
*/
|
|
64
69
|
[[maybe_unused]]
|
|
65
70
|
static jni::local_ref<JPlayerConfig::javaobject> fromCpp(const PlayerConfig& value) {
|
|
66
|
-
using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JString>);
|
|
71
|
+
using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JString>, jni::alias_ref<JAndroidAudioFocusMode>);
|
|
67
72
|
static const auto clazz = javaClassStatic();
|
|
68
73
|
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
69
74
|
return create(
|
|
@@ -74,7 +79,8 @@ namespace margelo::nitro::nitroplayer {
|
|
|
74
79
|
value.remoteSkipForwardInterval.has_value() ? jni::JDouble::valueOf(value.remoteSkipForwardInterval.value()) : nullptr,
|
|
75
80
|
value.remoteSkipBackwardInterval.has_value() ? jni::JDouble::valueOf(value.remoteSkipBackwardInterval.value()) : nullptr,
|
|
76
81
|
value.lookaheadCount.has_value() ? jni::JDouble::valueOf(value.lookaheadCount.value()) : nullptr,
|
|
77
|
-
value.androidNotificationIcon.has_value() ? jni::make_jstring(value.androidNotificationIcon.value()) : nullptr
|
|
82
|
+
value.androidNotificationIcon.has_value() ? jni::make_jstring(value.androidNotificationIcon.value()) : nullptr,
|
|
83
|
+
value.androidAudioFocus.has_value() ? JAndroidAudioFocusMode::fromCpp(value.androidAudioFocus.value()) : nullptr
|
|
78
84
|
);
|
|
79
85
|
}
|
|
80
86
|
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JShufflePlaylistOptions.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "ShufflePlaylistOptions.hpp"
|
|
12
|
+
|
|
13
|
+
#include <optional>
|
|
14
|
+
|
|
15
|
+
namespace margelo::nitro::nitroplayer {
|
|
16
|
+
|
|
17
|
+
using namespace facebook;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The C++ JNI bridge between the C++ struct "ShufflePlaylistOptions" and the the Kotlin data class "ShufflePlaylistOptions".
|
|
21
|
+
*/
|
|
22
|
+
struct JShufflePlaylistOptions final: public jni::JavaClass<JShufflePlaylistOptions> {
|
|
23
|
+
public:
|
|
24
|
+
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/nitroplayer/ShufflePlaylistOptions;";
|
|
25
|
+
|
|
26
|
+
public:
|
|
27
|
+
/**
|
|
28
|
+
* Convert this Java/Kotlin-based struct to the C++ struct ShufflePlaylistOptions by copying all values to C++.
|
|
29
|
+
*/
|
|
30
|
+
[[maybe_unused]]
|
|
31
|
+
[[nodiscard]]
|
|
32
|
+
ShufflePlaylistOptions toCpp() const {
|
|
33
|
+
static const auto clazz = javaClassStatic();
|
|
34
|
+
static const auto fieldKeepCurrentTrackFirst = clazz->getField<jni::JBoolean>("keepCurrentTrackFirst");
|
|
35
|
+
jni::local_ref<jni::JBoolean> keepCurrentTrackFirst = this->getFieldValue(fieldKeepCurrentTrackFirst);
|
|
36
|
+
return ShufflePlaylistOptions(
|
|
37
|
+
keepCurrentTrackFirst != nullptr ? std::make_optional(static_cast<bool>(keepCurrentTrackFirst->value())) : std::nullopt
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public:
|
|
42
|
+
/**
|
|
43
|
+
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
|
|
44
|
+
*/
|
|
45
|
+
[[maybe_unused]]
|
|
46
|
+
static jni::local_ref<JShufflePlaylistOptions::javaobject> fromCpp(const ShufflePlaylistOptions& value) {
|
|
47
|
+
using JSignature = JShufflePlaylistOptions(jni::alias_ref<jni::JBoolean>);
|
|
48
|
+
static const auto clazz = javaClassStatic();
|
|
49
|
+
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
50
|
+
return create(
|
|
51
|
+
clazz,
|
|
52
|
+
value.keepCurrentTrackFirst.has_value() ? jni::JBoolean::valueOf(value.keepCurrentTrackFirst.value()) : nullptr
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
} // namespace margelo::nitro::nitroplayer
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/AndroidAudioFocusMode.kt
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// AndroidAudioFocusMode.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.nitroplayer
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents the JavaScript enum/union "AndroidAudioFocusMode".
|
|
15
|
+
*/
|
|
16
|
+
@DoNotStrip
|
|
17
|
+
@Keep
|
|
18
|
+
enum class AndroidAudioFocusMode(@DoNotStrip @Keep val value: Int) {
|
|
19
|
+
PAUSE(0),
|
|
20
|
+
DUCK(1),
|
|
21
|
+
IGNORE(2);
|
|
22
|
+
|
|
23
|
+
companion object
|
|
24
|
+
}
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt
CHANGED
|
@@ -66,6 +66,14 @@ abstract class HybridPlayerQueueSpec: HybridObject() {
|
|
|
66
66
|
@Keep
|
|
67
67
|
abstract fun reorderTrackInPlaylist(playlistId: String, trackId: String, newIndex: Double): Promise<Unit>
|
|
68
68
|
|
|
69
|
+
@DoNotStrip
|
|
70
|
+
@Keep
|
|
71
|
+
abstract fun removeTracksFromPlaylist(playlistId: String, trackIds: Array<String>): Promise<Unit>
|
|
72
|
+
|
|
73
|
+
@DoNotStrip
|
|
74
|
+
@Keep
|
|
75
|
+
abstract fun shufflePlaylist(playlistId: String, options: ShufflePlaylistOptions?): Promise<Unit>
|
|
76
|
+
|
|
69
77
|
@DoNotStrip
|
|
70
78
|
@Keep
|
|
71
79
|
abstract fun loadPlaylist(playlistId: String, index: Double?): Promise<Unit>
|
|
@@ -37,7 +37,10 @@ data class PlayerConfig(
|
|
|
37
37
|
val lookaheadCount: Double?,
|
|
38
38
|
@DoNotStrip
|
|
39
39
|
@Keep
|
|
40
|
-
val androidNotificationIcon: String
|
|
40
|
+
val androidNotificationIcon: String?,
|
|
41
|
+
@DoNotStrip
|
|
42
|
+
@Keep
|
|
43
|
+
val androidAudioFocus: AndroidAudioFocusMode?
|
|
41
44
|
) {
|
|
42
45
|
/* primary constructor */
|
|
43
46
|
|
|
@@ -49,8 +52,8 @@ data class PlayerConfig(
|
|
|
49
52
|
@Keep
|
|
50
53
|
@Suppress("unused")
|
|
51
54
|
@JvmStatic
|
|
52
|
-
private fun fromCpp(androidAutoEnabled: Boolean?, carPlayEnabled: Boolean?, showInNotification: Boolean?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, lookaheadCount: Double?, androidNotificationIcon: String?): PlayerConfig {
|
|
53
|
-
return PlayerConfig(androidAutoEnabled, carPlayEnabled, showInNotification, remoteSkipForwardInterval, remoteSkipBackwardInterval, lookaheadCount, androidNotificationIcon)
|
|
55
|
+
private fun fromCpp(androidAutoEnabled: Boolean?, carPlayEnabled: Boolean?, showInNotification: Boolean?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, lookaheadCount: Double?, androidNotificationIcon: String?, androidAudioFocus: AndroidAudioFocusMode?): PlayerConfig {
|
|
56
|
+
return PlayerConfig(androidAutoEnabled, carPlayEnabled, showInNotification, remoteSkipForwardInterval, remoteSkipBackwardInterval, lookaheadCount, androidNotificationIcon, androidAudioFocus)
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
}
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/ShufflePlaylistOptions.kt
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ShufflePlaylistOptions.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.nitroplayer
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Represents the JavaScript object/struct "ShufflePlaylistOptions".
|
|
16
|
+
*/
|
|
17
|
+
@DoNotStrip
|
|
18
|
+
@Keep
|
|
19
|
+
data class ShufflePlaylistOptions(
|
|
20
|
+
@DoNotStrip
|
|
21
|
+
@Keep
|
|
22
|
+
val keepCurrentTrackFirst: Boolean?
|
|
23
|
+
) {
|
|
24
|
+
/* primary constructor */
|
|
25
|
+
|
|
26
|
+
companion object {
|
|
27
|
+
/**
|
|
28
|
+
* Constructor called from C++
|
|
29
|
+
*/
|
|
30
|
+
@DoNotStrip
|
|
31
|
+
@Keep
|
|
32
|
+
@Suppress("unused")
|
|
33
|
+
@JvmStatic
|
|
34
|
+
private fun fromCpp(keepCurrentTrackFirst: Boolean?): ShufflePlaylistOptions {
|
|
35
|
+
return ShufflePlaylistOptions(keepCurrentTrackFirst)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|