react-native-nitro-player 0.5.5 → 0.5.7
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 +2 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +43 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/NitroPlayerLogger.kt +8 -2
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +345 -4
- package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadDatabase.kt +43 -10
- package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +76 -7
- package/android/src/main/java/com/margelo/nitro/nitroplayer/storage/NitroPlayerStorage.kt +9 -2
- package/ios/HybridTrackPlayer.swift +54 -1
- package/ios/core/TrackPlayerCore.swift +254 -2
- package/ios/download/DownloadDatabase.swift +79 -2
- package/ios/download/DownloadManagerCore.swift +81 -2
- package/ios/playlist/PlaylistManager.swift +68 -0
- package/lib/specs/TrackPlayer.nitro.d.ts +47 -0
- package/lib/types/PlayerQueue.d.ts +5 -0
- package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double.hpp +104 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +160 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +8 -0
- package/nitrogen/generated/android/c++/JPlayerConfig.hpp +7 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__vector_TrackItem__double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +37 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlayerConfig.kt +6 -3
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +16 -0
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +65 -0
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +62 -0
- package/nitrogen/generated/ios/swift/Func_void_double.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__double.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +8 -0
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +173 -0
- package/nitrogen/generated/ios/swift/PlayerConfig.swift +24 -1
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +8 -0
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +8 -0
- package/nitrogen/generated/shared/c++/PlayerConfig.hpp +6 -2
- package/package.json +1 -1
- package/src/specs/TrackPlayer.nitro.ts +57 -0
- package/src/types/PlayerQueue.ts +5 -0
|
@@ -613,6 +613,12 @@ final class DownloadManagerCore: NSObject {
|
|
|
613
613
|
artworkString = value
|
|
614
614
|
}
|
|
615
615
|
}
|
|
616
|
+
|
|
617
|
+
var extraPayloadDict: [String: Any]? = nil
|
|
618
|
+
if let extraPayload = track.extraPayload {
|
|
619
|
+
extraPayloadDict = extraPayload.toDictionary()
|
|
620
|
+
}
|
|
621
|
+
|
|
616
622
|
return TrackItemRecord(
|
|
617
623
|
id: track.id,
|
|
618
624
|
title: track.title,
|
|
@@ -620,12 +626,30 @@ final class DownloadManagerCore: NSObject {
|
|
|
620
626
|
album: track.album,
|
|
621
627
|
duration: track.duration,
|
|
622
628
|
url: track.url,
|
|
623
|
-
artwork: artworkString
|
|
629
|
+
artwork: artworkString,
|
|
630
|
+
extraPayload: extraPayloadDict
|
|
624
631
|
)
|
|
625
632
|
}
|
|
626
633
|
|
|
627
634
|
private func recordToTrackItem(_ record: TrackItemRecord) -> TrackItem {
|
|
628
635
|
let artwork: Variant_NullType_String? = record.artwork.map { .second($0) }
|
|
636
|
+
|
|
637
|
+
var extraPayload: AnyMap? = nil
|
|
638
|
+
if let extraPayloadDict = record.extraPayload {
|
|
639
|
+
extraPayload = AnyMap()
|
|
640
|
+
for (key, value) in extraPayloadDict {
|
|
641
|
+
if let stringValue = value as? String {
|
|
642
|
+
extraPayload?.setString(key: key, value: stringValue)
|
|
643
|
+
} else if let doubleValue = value as? Double {
|
|
644
|
+
extraPayload?.setDouble(key: key, value: doubleValue)
|
|
645
|
+
} else if let intValue = value as? Int {
|
|
646
|
+
extraPayload?.setDouble(key: key, value: Double(intValue))
|
|
647
|
+
} else if let boolValue = value as? Bool {
|
|
648
|
+
extraPayload?.setBoolean(key: key, value: boolValue)
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
629
653
|
return TrackItem(
|
|
630
654
|
id: record.id,
|
|
631
655
|
title: record.title,
|
|
@@ -634,7 +658,7 @@ final class DownloadManagerCore: NSObject {
|
|
|
634
658
|
duration: record.duration,
|
|
635
659
|
url: record.url,
|
|
636
660
|
artwork: artwork,
|
|
637
|
-
extraPayload:
|
|
661
|
+
extraPayload: extraPayload
|
|
638
662
|
)
|
|
639
663
|
}
|
|
640
664
|
|
|
@@ -963,4 +987,59 @@ private struct TrackItemRecord: Codable {
|
|
|
963
987
|
let duration: Double
|
|
964
988
|
let url: String
|
|
965
989
|
let artwork: String?
|
|
990
|
+
let extraPayload: [String: Any]?
|
|
991
|
+
|
|
992
|
+
enum CodingKeys: String, CodingKey {
|
|
993
|
+
case id, title, artist, album, duration, url, artwork, extraPayload
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Manual encoding to handle [String: Any]
|
|
997
|
+
func encode(to encoder: Encoder) throws {
|
|
998
|
+
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
999
|
+
try container.encode(id, forKey: .id)
|
|
1000
|
+
try container.encode(title, forKey: .title)
|
|
1001
|
+
try container.encode(artist, forKey: .artist)
|
|
1002
|
+
try container.encode(album, forKey: .album)
|
|
1003
|
+
try container.encode(duration, forKey: .duration)
|
|
1004
|
+
try container.encode(url, forKey: .url)
|
|
1005
|
+
try container.encodeIfPresent(artwork, forKey: .artwork)
|
|
1006
|
+
|
|
1007
|
+
if let extraPayload = extraPayload {
|
|
1008
|
+
let jsonData = try JSONSerialization.data(withJSONObject: extraPayload)
|
|
1009
|
+
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
|
1010
|
+
try container.encode(jsonString, forKey: .extraPayload)
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Manual decoding to handle [String: Any]
|
|
1016
|
+
init(from decoder: Decoder) throws {
|
|
1017
|
+
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
1018
|
+
id = try container.decode(String.self, forKey: .id)
|
|
1019
|
+
title = try container.decode(String.self, forKey: .title)
|
|
1020
|
+
artist = try container.decode(String.self, forKey: .artist)
|
|
1021
|
+
album = try container.decode(String.self, forKey: .album)
|
|
1022
|
+
duration = try container.decode(Double.self, forKey: .duration)
|
|
1023
|
+
url = try container.decode(String.self, forKey: .url)
|
|
1024
|
+
artwork = try container.decodeIfPresent(String.self, forKey: .artwork)
|
|
1025
|
+
|
|
1026
|
+
if let jsonString = try? container.decodeIfPresent(String.self, forKey: .extraPayload),
|
|
1027
|
+
let jsonData = jsonString.data(using: .utf8) {
|
|
1028
|
+
extraPayload = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
|
|
1029
|
+
} else {
|
|
1030
|
+
extraPayload = nil
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// Initializer for code creation
|
|
1035
|
+
init(id: String, title: String, artist: String, album: String, duration: Double, url: String, artwork: String?, extraPayload: [String: Any]?) {
|
|
1036
|
+
self.id = id
|
|
1037
|
+
self.title = title
|
|
1038
|
+
self.artist = artist
|
|
1039
|
+
self.album = album
|
|
1040
|
+
self.duration = duration
|
|
1041
|
+
self.url = url
|
|
1042
|
+
self.artwork = artwork
|
|
1043
|
+
self.extraPayload = extraPayload
|
|
1044
|
+
}
|
|
966
1045
|
}
|
|
@@ -274,6 +274,74 @@ class PlaylistManager {
|
|
|
274
274
|
return true
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Update entire track objects across all playlists
|
|
279
|
+
* Matches by track.id and replaces the entire track object
|
|
280
|
+
* @param tracks Array of full TrackItem objects to update
|
|
281
|
+
* @return Dictionary of playlistId -> count of tracks updated
|
|
282
|
+
*/
|
|
283
|
+
func updateTracks(tracks: [TrackItem]) -> [String: Int] {
|
|
284
|
+
let tracksMap = Dictionary(uniqueKeysWithValues: tracks.map { ($0.id, $0) })
|
|
285
|
+
var affectedPlaylists: [String: Int] = [:]
|
|
286
|
+
|
|
287
|
+
queue.sync {
|
|
288
|
+
for (playlistId, playlist) in playlists {
|
|
289
|
+
var updateCount = 0
|
|
290
|
+
let newTracks = playlist.tracks.map { track -> TrackItem in
|
|
291
|
+
if let updatedTrack = tracksMap[track.id] {
|
|
292
|
+
updateCount += 1
|
|
293
|
+
return updatedTrack
|
|
294
|
+
}
|
|
295
|
+
return track
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if updateCount > 0 {
|
|
299
|
+
affectedPlaylists[playlistId] = updateCount
|
|
300
|
+
playlists[playlistId] = PlaylistModel(
|
|
301
|
+
id: playlist.id,
|
|
302
|
+
name: playlist.name,
|
|
303
|
+
description: playlist.description,
|
|
304
|
+
artwork: playlist.artwork,
|
|
305
|
+
tracks: newTracks
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if !affectedPlaylists.isEmpty {
|
|
312
|
+
scheduleSave()
|
|
313
|
+
affectedPlaylists.keys.forEach { playlistId in
|
|
314
|
+
notifyPlaylistChanged(playlistId, .update)
|
|
315
|
+
}
|
|
316
|
+
notifyPlaylistsChanged(.update)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return affectedPlaylists
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get tracks by IDs from all playlists
|
|
324
|
+
* @param trackIds Array of track IDs to fetch
|
|
325
|
+
* @return Array of matching TrackItem objects
|
|
326
|
+
*/
|
|
327
|
+
func getTracksById(trackIds: [String]) -> [TrackItem] {
|
|
328
|
+
let trackIdSet = Set(trackIds)
|
|
329
|
+
var foundTracks: [String: TrackItem] = [:]
|
|
330
|
+
|
|
331
|
+
queue.sync {
|
|
332
|
+
for playlist in playlists.values {
|
|
333
|
+
for track in playlist.tracks {
|
|
334
|
+
if trackIdSet.contains(track.id) && foundTracks[track.id] == nil {
|
|
335
|
+
foundTracks[track.id] = track
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Return in same order as requested
|
|
342
|
+
return trackIds.compactMap { foundTracks[$0] }
|
|
343
|
+
}
|
|
344
|
+
|
|
277
345
|
/**
|
|
278
346
|
* Get the current playlist ID
|
|
279
347
|
*/
|
|
@@ -44,4 +44,51 @@ export interface TrackPlayer extends HybridObject<{
|
|
|
44
44
|
onAndroidAutoConnectionChange(callback: (connected: boolean) => void): void;
|
|
45
45
|
isAndroidAutoConnected(): boolean;
|
|
46
46
|
setVolume(volume: number): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Update entire track objects across all playlists
|
|
49
|
+
* Matches by track.id and updates all properties (url, artwork, title, etc.)
|
|
50
|
+
* Note: Empty string "" is valid for TrackItem.url to support lazy loading
|
|
51
|
+
* @param tracks Array of full TrackItem objects to update
|
|
52
|
+
* @returns Promise that resolves when updates complete
|
|
53
|
+
*/
|
|
54
|
+
updateTracks(tracks: TrackItem[]): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Get tracks by IDs from all playlists
|
|
57
|
+
* @param trackIds Array of track IDs to fetch
|
|
58
|
+
* @returns Promise resolving to array of matching tracks
|
|
59
|
+
*/
|
|
60
|
+
getTracksById(trackIds: string[]): Promise<TrackItem[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Get tracks with missing/empty URLs from current playlist
|
|
63
|
+
* @returns Promise resolving to array of tracks needing URLs
|
|
64
|
+
*/
|
|
65
|
+
getTracksNeedingUrls(): Promise<TrackItem[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Get next N tracks from current position in playlist
|
|
68
|
+
* Useful for preloading URLs before they're needed
|
|
69
|
+
* @param count Number of upcoming tracks to return
|
|
70
|
+
* @returns Promise resolving to array of next tracks
|
|
71
|
+
*/
|
|
72
|
+
getNextTracks(count: number): Promise<TrackItem[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Get current track index in the active playlist
|
|
75
|
+
* @returns Promise resolving to 0-based index, or -1 if no track playing
|
|
76
|
+
*/
|
|
77
|
+
getCurrentTrackIndex(): Promise<number>;
|
|
78
|
+
/**
|
|
79
|
+
* Register callback that fires when tracks will be needed soon
|
|
80
|
+
* Useful for proactive URL resolution in Android Auto/CarPlay
|
|
81
|
+
* @param callback Function called with tracks needing URLs and lookahead count
|
|
82
|
+
*/
|
|
83
|
+
onTracksNeedUpdate(callback: (tracks: TrackItem[], lookahead: number) => void): void;
|
|
84
|
+
/**
|
|
85
|
+
* Get the current track index in the active playlist
|
|
86
|
+
* @returns Promise resolving to 0-based index, or -1 if no track playing
|
|
87
|
+
*/
|
|
88
|
+
setPlaybackSpeed(speed: number): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Get the current playback speed
|
|
91
|
+
* @returns Promise resolving to playback speed
|
|
92
|
+
*/
|
|
93
|
+
getPlaybackSpeed(): Promise<number>;
|
|
47
94
|
}
|
|
@@ -33,4 +33,9 @@ export interface PlayerConfig {
|
|
|
33
33
|
androidAutoEnabled?: boolean;
|
|
34
34
|
carPlayEnabled?: boolean;
|
|
35
35
|
showInNotification?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Number of upcoming tracks to preload URLs for (default: 5)
|
|
38
|
+
* Higher values = more proactive loading, but more network requests
|
|
39
|
+
*/
|
|
40
|
+
lookaheadCount?: number;
|
|
36
41
|
}
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#include "JFunc_void_TrackPlayerState_std__optional_Reason_.hpp"
|
|
34
34
|
#include "JFunc_void_double_double.hpp"
|
|
35
35
|
#include "JFunc_void_double_double_std__optional_bool_.hpp"
|
|
36
|
+
#include "JFunc_void_std__vector_TrackItem__double.hpp"
|
|
36
37
|
#include <NitroModules/DefaultConstructableObject.hpp>
|
|
37
38
|
|
|
38
39
|
namespace margelo::nitro::nitroplayer {
|
|
@@ -62,6 +63,7 @@ int initialize(JavaVM* vm) {
|
|
|
62
63
|
margelo::nitro::nitroplayer::JFunc_void_TrackPlayerState_std__optional_Reason__cxx::registerNatives();
|
|
63
64
|
margelo::nitro::nitroplayer::JFunc_void_double_double_cxx::registerNatives();
|
|
64
65
|
margelo::nitro::nitroplayer::JFunc_void_double_double_std__optional_bool__cxx::registerNatives();
|
|
66
|
+
margelo::nitro::nitroplayer::JFunc_void_std__vector_TrackItem__double_cxx::registerNatives();
|
|
65
67
|
|
|
66
68
|
// Register Nitro Hybrid Objects
|
|
67
69
|
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JFunc_void_std__vector_TrackItem__double.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include <functional>
|
|
12
|
+
|
|
13
|
+
#include "TrackItem.hpp"
|
|
14
|
+
#include <vector>
|
|
15
|
+
#include <functional>
|
|
16
|
+
#include <NitroModules/JNICallable.hpp>
|
|
17
|
+
#include "JTrackItem.hpp"
|
|
18
|
+
#include <string>
|
|
19
|
+
#include <NitroModules/Null.hpp>
|
|
20
|
+
#include <variant>
|
|
21
|
+
#include <optional>
|
|
22
|
+
#include "JVariant_NullType_String.hpp"
|
|
23
|
+
#include <NitroModules/JNull.hpp>
|
|
24
|
+
#include <NitroModules/AnyMap.hpp>
|
|
25
|
+
#include <NitroModules/JAnyMap.hpp>
|
|
26
|
+
|
|
27
|
+
namespace margelo::nitro::nitroplayer {
|
|
28
|
+
|
|
29
|
+
using namespace facebook;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Represents the Java/Kotlin callback `(tracks: Array<TrackItem>, lookahead: Double) -> Unit`.
|
|
33
|
+
* This can be passed around between C++ and Java/Kotlin.
|
|
34
|
+
*/
|
|
35
|
+
struct JFunc_void_std__vector_TrackItem__double: public jni::JavaClass<JFunc_void_std__vector_TrackItem__double> {
|
|
36
|
+
public:
|
|
37
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitroplayer/Func_void_std__vector_TrackItem__double;";
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
/**
|
|
41
|
+
* Invokes the function this `JFunc_void_std__vector_TrackItem__double` instance holds through JNI.
|
|
42
|
+
*/
|
|
43
|
+
void invoke(const std::vector<TrackItem>& tracks, double lookahead) const {
|
|
44
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JTrackItem>> /* tracks */, double /* lookahead */)>("invoke");
|
|
45
|
+
method(self(), [&]() {
|
|
46
|
+
size_t __size = tracks.size();
|
|
47
|
+
jni::local_ref<jni::JArrayClass<JTrackItem>> __array = jni::JArrayClass<JTrackItem>::newArray(__size);
|
|
48
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
49
|
+
const auto& __element = tracks[__i];
|
|
50
|
+
auto __elementJni = JTrackItem::fromCpp(__element);
|
|
51
|
+
__array->setElement(__i, *__elementJni);
|
|
52
|
+
}
|
|
53
|
+
return __array;
|
|
54
|
+
}(), lookahead);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* An implementation of Func_void_std__vector_TrackItem__double that is backed by a C++ implementation (using `std::function<...>`)
|
|
60
|
+
*/
|
|
61
|
+
class JFunc_void_std__vector_TrackItem__double_cxx final: public jni::HybridClass<JFunc_void_std__vector_TrackItem__double_cxx, JFunc_void_std__vector_TrackItem__double> {
|
|
62
|
+
public:
|
|
63
|
+
static jni::local_ref<JFunc_void_std__vector_TrackItem__double::javaobject> fromCpp(const std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>& func) {
|
|
64
|
+
return JFunc_void_std__vector_TrackItem__double_cxx::newObjectCxxArgs(func);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public:
|
|
68
|
+
/**
|
|
69
|
+
* Invokes the C++ `std::function<...>` this `JFunc_void_std__vector_TrackItem__double_cxx` instance holds.
|
|
70
|
+
*/
|
|
71
|
+
void invoke_cxx(jni::alias_ref<jni::JArrayClass<JTrackItem>> tracks, double lookahead) {
|
|
72
|
+
_func([&]() {
|
|
73
|
+
size_t __size = tracks->size();
|
|
74
|
+
std::vector<TrackItem> __vector;
|
|
75
|
+
__vector.reserve(__size);
|
|
76
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
77
|
+
auto __element = tracks->getElement(__i);
|
|
78
|
+
__vector.push_back(__element->toCpp());
|
|
79
|
+
}
|
|
80
|
+
return __vector;
|
|
81
|
+
}(), lookahead);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public:
|
|
85
|
+
[[nodiscard]]
|
|
86
|
+
inline const std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>& getFunction() const {
|
|
87
|
+
return _func;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public:
|
|
91
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitroplayer/Func_void_std__vector_TrackItem__double_cxx;";
|
|
92
|
+
static void registerNatives() {
|
|
93
|
+
registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_std__vector_TrackItem__double_cxx::invoke_cxx)});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private:
|
|
97
|
+
explicit JFunc_void_std__vector_TrackItem__double_cxx(const std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>& func): _func(func) { }
|
|
98
|
+
|
|
99
|
+
private:
|
|
100
|
+
friend HybridBase;
|
|
101
|
+
std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)> _func;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
} // namespace margelo::nitro::nitroplayer
|
|
@@ -55,6 +55,7 @@ namespace margelo::nitro::nitroplayer { enum class Reason; }
|
|
|
55
55
|
#include "JFunc_void_double_double.hpp"
|
|
56
56
|
#include "JFunc_void_double_double_std__optional_bool_.hpp"
|
|
57
57
|
#include "JFunc_void_bool.hpp"
|
|
58
|
+
#include "JFunc_void_std__vector_TrackItem__double.hpp"
|
|
58
59
|
|
|
59
60
|
namespace margelo::nitro::nitroplayer {
|
|
60
61
|
|
|
@@ -254,5 +255,164 @@ namespace margelo::nitro::nitroplayer {
|
|
|
254
255
|
auto __result = method(_javaPart, volume);
|
|
255
256
|
return static_cast<bool>(__result);
|
|
256
257
|
}
|
|
258
|
+
std::shared_ptr<Promise<void>> JHybridTrackPlayerSpec::updateTracks(const std::vector<TrackItem>& tracks) {
|
|
259
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JArrayClass<JTrackItem>> /* tracks */)>("updateTracks");
|
|
260
|
+
auto __result = method(_javaPart, [&]() {
|
|
261
|
+
size_t __size = tracks.size();
|
|
262
|
+
jni::local_ref<jni::JArrayClass<JTrackItem>> __array = jni::JArrayClass<JTrackItem>::newArray(__size);
|
|
263
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
264
|
+
const auto& __element = tracks[__i];
|
|
265
|
+
auto __elementJni = JTrackItem::fromCpp(__element);
|
|
266
|
+
__array->setElement(__i, *__elementJni);
|
|
267
|
+
}
|
|
268
|
+
return __array;
|
|
269
|
+
}());
|
|
270
|
+
return [&]() {
|
|
271
|
+
auto __promise = Promise<void>::create();
|
|
272
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
273
|
+
__promise->resolve();
|
|
274
|
+
});
|
|
275
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
276
|
+
jni::JniException __jniError(__throwable);
|
|
277
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
278
|
+
});
|
|
279
|
+
return __promise;
|
|
280
|
+
}();
|
|
281
|
+
}
|
|
282
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> JHybridTrackPlayerSpec::getTracksById(const std::vector<std::string>& trackIds) {
|
|
283
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JArrayClass<jni::JString>> /* trackIds */)>("getTracksById");
|
|
284
|
+
auto __result = method(_javaPart, [&]() {
|
|
285
|
+
size_t __size = trackIds.size();
|
|
286
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> __array = jni::JArrayClass<jni::JString>::newArray(__size);
|
|
287
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
288
|
+
const auto& __element = trackIds[__i];
|
|
289
|
+
auto __elementJni = jni::make_jstring(__element);
|
|
290
|
+
__array->setElement(__i, *__elementJni);
|
|
291
|
+
}
|
|
292
|
+
return __array;
|
|
293
|
+
}());
|
|
294
|
+
return [&]() {
|
|
295
|
+
auto __promise = Promise<std::vector<TrackItem>>::create();
|
|
296
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
297
|
+
auto __result = jni::static_ref_cast<jni::JArrayClass<JTrackItem>>(__boxedResult);
|
|
298
|
+
__promise->resolve([&]() {
|
|
299
|
+
size_t __size = __result->size();
|
|
300
|
+
std::vector<TrackItem> __vector;
|
|
301
|
+
__vector.reserve(__size);
|
|
302
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
303
|
+
auto __element = __result->getElement(__i);
|
|
304
|
+
__vector.push_back(__element->toCpp());
|
|
305
|
+
}
|
|
306
|
+
return __vector;
|
|
307
|
+
}());
|
|
308
|
+
});
|
|
309
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
310
|
+
jni::JniException __jniError(__throwable);
|
|
311
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
312
|
+
});
|
|
313
|
+
return __promise;
|
|
314
|
+
}();
|
|
315
|
+
}
|
|
316
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> JHybridTrackPlayerSpec::getTracksNeedingUrls() {
|
|
317
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getTracksNeedingUrls");
|
|
318
|
+
auto __result = method(_javaPart);
|
|
319
|
+
return [&]() {
|
|
320
|
+
auto __promise = Promise<std::vector<TrackItem>>::create();
|
|
321
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
322
|
+
auto __result = jni::static_ref_cast<jni::JArrayClass<JTrackItem>>(__boxedResult);
|
|
323
|
+
__promise->resolve([&]() {
|
|
324
|
+
size_t __size = __result->size();
|
|
325
|
+
std::vector<TrackItem> __vector;
|
|
326
|
+
__vector.reserve(__size);
|
|
327
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
328
|
+
auto __element = __result->getElement(__i);
|
|
329
|
+
__vector.push_back(__element->toCpp());
|
|
330
|
+
}
|
|
331
|
+
return __vector;
|
|
332
|
+
}());
|
|
333
|
+
});
|
|
334
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
335
|
+
jni::JniException __jniError(__throwable);
|
|
336
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
337
|
+
});
|
|
338
|
+
return __promise;
|
|
339
|
+
}();
|
|
340
|
+
}
|
|
341
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> JHybridTrackPlayerSpec::getNextTracks(double count) {
|
|
342
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(double /* count */)>("getNextTracks");
|
|
343
|
+
auto __result = method(_javaPart, count);
|
|
344
|
+
return [&]() {
|
|
345
|
+
auto __promise = Promise<std::vector<TrackItem>>::create();
|
|
346
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
347
|
+
auto __result = jni::static_ref_cast<jni::JArrayClass<JTrackItem>>(__boxedResult);
|
|
348
|
+
__promise->resolve([&]() {
|
|
349
|
+
size_t __size = __result->size();
|
|
350
|
+
std::vector<TrackItem> __vector;
|
|
351
|
+
__vector.reserve(__size);
|
|
352
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
353
|
+
auto __element = __result->getElement(__i);
|
|
354
|
+
__vector.push_back(__element->toCpp());
|
|
355
|
+
}
|
|
356
|
+
return __vector;
|
|
357
|
+
}());
|
|
358
|
+
});
|
|
359
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
360
|
+
jni::JniException __jniError(__throwable);
|
|
361
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
362
|
+
});
|
|
363
|
+
return __promise;
|
|
364
|
+
}();
|
|
365
|
+
}
|
|
366
|
+
std::shared_ptr<Promise<double>> JHybridTrackPlayerSpec::getCurrentTrackIndex() {
|
|
367
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getCurrentTrackIndex");
|
|
368
|
+
auto __result = method(_javaPart);
|
|
369
|
+
return [&]() {
|
|
370
|
+
auto __promise = Promise<double>::create();
|
|
371
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
372
|
+
auto __result = jni::static_ref_cast<jni::JDouble>(__boxedResult);
|
|
373
|
+
__promise->resolve(__result->value());
|
|
374
|
+
});
|
|
375
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
376
|
+
jni::JniException __jniError(__throwable);
|
|
377
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
378
|
+
});
|
|
379
|
+
return __promise;
|
|
380
|
+
}();
|
|
381
|
+
}
|
|
382
|
+
void JHybridTrackPlayerSpec::onTracksNeedUpdate(const std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>& callback) {
|
|
383
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_std__vector_TrackItem__double::javaobject> /* callback */)>("onTracksNeedUpdate_cxx");
|
|
384
|
+
method(_javaPart, JFunc_void_std__vector_TrackItem__double_cxx::fromCpp(callback));
|
|
385
|
+
}
|
|
386
|
+
std::shared_ptr<Promise<void>> JHybridTrackPlayerSpec::setPlaybackSpeed(double speed) {
|
|
387
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(double /* speed */)>("setPlaybackSpeed");
|
|
388
|
+
auto __result = method(_javaPart, speed);
|
|
389
|
+
return [&]() {
|
|
390
|
+
auto __promise = Promise<void>::create();
|
|
391
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
|
|
392
|
+
__promise->resolve();
|
|
393
|
+
});
|
|
394
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
395
|
+
jni::JniException __jniError(__throwable);
|
|
396
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
397
|
+
});
|
|
398
|
+
return __promise;
|
|
399
|
+
}();
|
|
400
|
+
}
|
|
401
|
+
std::shared_ptr<Promise<double>> JHybridTrackPlayerSpec::getPlaybackSpeed() {
|
|
402
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getPlaybackSpeed");
|
|
403
|
+
auto __result = method(_javaPart);
|
|
404
|
+
return [&]() {
|
|
405
|
+
auto __promise = Promise<double>::create();
|
|
406
|
+
__result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
|
|
407
|
+
auto __result = jni::static_ref_cast<jni::JDouble>(__boxedResult);
|
|
408
|
+
__promise->resolve(__result->value());
|
|
409
|
+
});
|
|
410
|
+
__result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
|
|
411
|
+
jni::JniException __jniError(__throwable);
|
|
412
|
+
__promise->reject(std::make_exception_ptr(__jniError));
|
|
413
|
+
});
|
|
414
|
+
return __promise;
|
|
415
|
+
}();
|
|
416
|
+
}
|
|
257
417
|
|
|
258
418
|
} // namespace margelo::nitro::nitroplayer
|
|
@@ -75,6 +75,14 @@ namespace margelo::nitro::nitroplayer {
|
|
|
75
75
|
void onAndroidAutoConnectionChange(const std::function<void(bool /* connected */)>& callback) override;
|
|
76
76
|
bool isAndroidAutoConnected() override;
|
|
77
77
|
bool setVolume(double volume) override;
|
|
78
|
+
std::shared_ptr<Promise<void>> updateTracks(const std::vector<TrackItem>& tracks) override;
|
|
79
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> getTracksById(const std::vector<std::string>& trackIds) override;
|
|
80
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> getTracksNeedingUrls() override;
|
|
81
|
+
std::shared_ptr<Promise<std::vector<TrackItem>>> getNextTracks(double count) override;
|
|
82
|
+
std::shared_ptr<Promise<double>> getCurrentTrackIndex() override;
|
|
83
|
+
void onTracksNeedUpdate(const std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>& callback) override;
|
|
84
|
+
std::shared_ptr<Promise<void>> setPlaybackSpeed(double speed) override;
|
|
85
|
+
std::shared_ptr<Promise<double>> getPlaybackSpeed() override;
|
|
78
86
|
|
|
79
87
|
private:
|
|
80
88
|
friend HybridBase;
|
|
@@ -37,10 +37,13 @@ namespace margelo::nitro::nitroplayer {
|
|
|
37
37
|
jni::local_ref<jni::JBoolean> carPlayEnabled = this->getFieldValue(fieldCarPlayEnabled);
|
|
38
38
|
static const auto fieldShowInNotification = clazz->getField<jni::JBoolean>("showInNotification");
|
|
39
39
|
jni::local_ref<jni::JBoolean> showInNotification = this->getFieldValue(fieldShowInNotification);
|
|
40
|
+
static const auto fieldLookaheadCount = clazz->getField<jni::JDouble>("lookaheadCount");
|
|
41
|
+
jni::local_ref<jni::JDouble> lookaheadCount = this->getFieldValue(fieldLookaheadCount);
|
|
40
42
|
return PlayerConfig(
|
|
41
43
|
androidAutoEnabled != nullptr ? std::make_optional(static_cast<bool>(androidAutoEnabled->value())) : std::nullopt,
|
|
42
44
|
carPlayEnabled != nullptr ? std::make_optional(static_cast<bool>(carPlayEnabled->value())) : std::nullopt,
|
|
43
|
-
showInNotification != nullptr ? std::make_optional(static_cast<bool>(showInNotification->value())) : std::nullopt
|
|
45
|
+
showInNotification != nullptr ? std::make_optional(static_cast<bool>(showInNotification->value())) : std::nullopt,
|
|
46
|
+
lookaheadCount != nullptr ? std::make_optional(lookaheadCount->value()) : std::nullopt
|
|
44
47
|
);
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -50,14 +53,15 @@ namespace margelo::nitro::nitroplayer {
|
|
|
50
53
|
*/
|
|
51
54
|
[[maybe_unused]]
|
|
52
55
|
static jni::local_ref<JPlayerConfig::javaobject> fromCpp(const PlayerConfig& value) {
|
|
53
|
-
using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>);
|
|
56
|
+
using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>);
|
|
54
57
|
static const auto clazz = javaClassStatic();
|
|
55
58
|
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
56
59
|
return create(
|
|
57
60
|
clazz,
|
|
58
61
|
value.androidAutoEnabled.has_value() ? jni::JBoolean::valueOf(value.androidAutoEnabled.value()) : nullptr,
|
|
59
62
|
value.carPlayEnabled.has_value() ? jni::JBoolean::valueOf(value.carPlayEnabled.value()) : nullptr,
|
|
60
|
-
value.showInNotification.has_value() ? jni::JBoolean::valueOf(value.showInNotification.value()) : nullptr
|
|
63
|
+
value.showInNotification.has_value() ? jni::JBoolean::valueOf(value.showInNotification.value()) : nullptr,
|
|
64
|
+
value.lookaheadCount.has_value() ? jni::JDouble::valueOf(value.lookaheadCount.value()) : nullptr
|
|
61
65
|
);
|
|
62
66
|
}
|
|
63
67
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Func_void_std__vector_TrackItem__double.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.nitroplayer
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.jni.HybridData
|
|
12
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
13
|
+
import dalvik.annotation.optimization.FastNative
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Represents the JavaScript callback `(tracks: array, lookahead: number) => void`.
|
|
18
|
+
* This can be either implemented in C++ (in which case it might be a callback coming from JS),
|
|
19
|
+
* or in Kotlin/Java (in which case it is a native callback).
|
|
20
|
+
*/
|
|
21
|
+
@DoNotStrip
|
|
22
|
+
@Keep
|
|
23
|
+
@Suppress("ClassName", "RedundantUnitReturnType")
|
|
24
|
+
fun interface Func_void_std__vector_TrackItem__double: (Array<TrackItem>, Double) -> Unit {
|
|
25
|
+
/**
|
|
26
|
+
* Call the given JS callback.
|
|
27
|
+
* @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
|
|
28
|
+
*/
|
|
29
|
+
@DoNotStrip
|
|
30
|
+
@Keep
|
|
31
|
+
override fun invoke(tracks: Array<TrackItem>, lookahead: Double): Unit
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Represents the JavaScript callback `(tracks: array, lookahead: number) => void`.
|
|
36
|
+
* This is implemented in C++, via a `std::function<...>`.
|
|
37
|
+
* The callback might be coming from JS.
|
|
38
|
+
*/
|
|
39
|
+
@DoNotStrip
|
|
40
|
+
@Keep
|
|
41
|
+
@Suppress(
|
|
42
|
+
"KotlinJniMissingFunction", "unused",
|
|
43
|
+
"RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
|
|
44
|
+
"ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
|
|
45
|
+
)
|
|
46
|
+
class Func_void_std__vector_TrackItem__double_cxx: Func_void_std__vector_TrackItem__double {
|
|
47
|
+
@DoNotStrip
|
|
48
|
+
@Keep
|
|
49
|
+
private val mHybridData: HybridData
|
|
50
|
+
|
|
51
|
+
@DoNotStrip
|
|
52
|
+
@Keep
|
|
53
|
+
private constructor(hybridData: HybridData) {
|
|
54
|
+
mHybridData = hybridData
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@DoNotStrip
|
|
58
|
+
@Keep
|
|
59
|
+
override fun invoke(tracks: Array<TrackItem>, lookahead: Double): Unit
|
|
60
|
+
= invoke_cxx(tracks,lookahead)
|
|
61
|
+
|
|
62
|
+
@FastNative
|
|
63
|
+
private external fun invoke_cxx(tracks: Array<TrackItem>, lookahead: Double): Unit
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Represents the JavaScript callback `(tracks: array, lookahead: number) => void`.
|
|
68
|
+
* This is implemented in Java/Kotlin, via a `(Array<TrackItem>, Double) -> Unit`.
|
|
69
|
+
* The callback is always coming from native.
|
|
70
|
+
*/
|
|
71
|
+
@DoNotStrip
|
|
72
|
+
@Keep
|
|
73
|
+
@Suppress("ClassName", "RedundantUnitReturnType", "unused")
|
|
74
|
+
class Func_void_std__vector_TrackItem__double_java(private val function: (Array<TrackItem>, Double) -> Unit): Func_void_std__vector_TrackItem__double {
|
|
75
|
+
@DoNotStrip
|
|
76
|
+
@Keep
|
|
77
|
+
override fun invoke(tracks: Array<TrackItem>, lookahead: Double): Unit {
|
|
78
|
+
return this.function(tracks, lookahead)
|
|
79
|
+
}
|
|
80
|
+
}
|