react-native-nitro-player 0.0.1 → 0.3.0-alpha.10
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 +282 -2
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAudioDevices.kt +37 -29
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +24 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +408 -16
- package/ios/HybridAudioRoutePicker.swift +47 -46
- package/ios/HybridTrackPlayer.swift +22 -0
- package/ios/core/TrackPlayerCore.swift +538 -48
- package/lib/hooks/callbackManager.d.ts +28 -0
- package/lib/hooks/callbackManager.js +76 -0
- package/lib/hooks/index.d.ts +7 -0
- package/lib/hooks/index.js +3 -0
- package/lib/hooks/useActualQueue.d.ts +48 -0
- package/lib/hooks/useActualQueue.js +98 -0
- package/lib/hooks/useNowPlaying.d.ts +36 -0
- package/lib/hooks/useNowPlaying.js +87 -0
- package/lib/hooks/useOnChangeTrack.d.ts +33 -6
- package/lib/hooks/useOnChangeTrack.js +65 -9
- package/lib/hooks/useOnPlaybackStateChange.d.ts +32 -6
- package/lib/hooks/useOnPlaybackStateChange.js +65 -9
- package/lib/hooks/usePlaylist.d.ts +48 -0
- package/lib/hooks/usePlaylist.js +136 -0
- package/lib/index.d.ts +1 -0
- package/lib/specs/TrackPlayer.nitro.d.ts +6 -0
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +46 -9
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +5 -0
- package/nitrogen/generated/android/c++/JRepeatMode.hpp +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +20 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/RepeatMode.kt +22 -0
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +9 -0
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +44 -4
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +5 -0
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +64 -0
- package/nitrogen/generated/ios/swift/RepeatMode.swift +44 -0
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +5 -0
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +12 -3
- package/nitrogen/generated/shared/c++/RepeatMode.hpp +80 -0
- package/package.json +13 -12
- package/src/hooks/callbackManager.ts +96 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/useActualQueue.ts +116 -0
- package/src/hooks/useNowPlaying.ts +97 -0
- package/src/hooks/useOnChangeTrack.ts +77 -13
- package/src/hooks/useOnPlaybackStateChange.ts +83 -13
- package/src/hooks/usePlaylist.ts +161 -0
- package/src/index.ts +1 -1
- package/src/specs/TrackPlayer.nitro.ts +7 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Playlist, TrackItem } from '../types/PlayerQueue';
|
|
2
|
+
export interface UsePlaylistResult {
|
|
3
|
+
/** The currently loaded playlist */
|
|
4
|
+
currentPlaylist: Playlist | null;
|
|
5
|
+
/** ID of the currently loaded playlist */
|
|
6
|
+
currentPlaylistId: string | null;
|
|
7
|
+
/** All available playlists */
|
|
8
|
+
allPlaylists: Playlist[];
|
|
9
|
+
/** All tracks from all playlists (flattened) */
|
|
10
|
+
allTracks: TrackItem[];
|
|
11
|
+
/** Whether the playlists are currently loading */
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
/** Manually refresh playlist data */
|
|
14
|
+
refreshPlaylists: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Hook to manage playlist state
|
|
18
|
+
*
|
|
19
|
+
* Provides current playlist, all playlists, and all tracks across playlists.
|
|
20
|
+
* Automatically refreshes when:
|
|
21
|
+
* - Component mounts
|
|
22
|
+
* - Track changes (to update currentPlaylistId)
|
|
23
|
+
* - Playlists are modified via PlayerQueue methods
|
|
24
|
+
*
|
|
25
|
+
* Call `refreshPlaylists()` after creating/deleting playlists to update the state.
|
|
26
|
+
*
|
|
27
|
+
* @returns Object containing playlist state and refresh function
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* function MyComponent() {
|
|
32
|
+
* const { currentPlaylist, allTracks, refreshPlaylists } = usePlaylist();
|
|
33
|
+
*
|
|
34
|
+
* const handleCreatePlaylist = () => {
|
|
35
|
+
* PlayerQueue.createPlaylist('New Playlist');
|
|
36
|
+
* refreshPlaylists(); // Refresh to see the new playlist
|
|
37
|
+
* };
|
|
38
|
+
*
|
|
39
|
+
* return (
|
|
40
|
+
* <View>
|
|
41
|
+
* <Text>{currentPlaylist?.name}</Text>
|
|
42
|
+
* <Text>Total tracks: {allTracks.length}</Text>
|
|
43
|
+
* </View>
|
|
44
|
+
* );
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function usePlaylist(): UsePlaylistResult;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { useEffect, useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { PlayerQueue } from '../index';
|
|
3
|
+
import { callbackManager } from './callbackManager';
|
|
4
|
+
/**
|
|
5
|
+
* Hook to manage playlist state
|
|
6
|
+
*
|
|
7
|
+
* Provides current playlist, all playlists, and all tracks across playlists.
|
|
8
|
+
* Automatically refreshes when:
|
|
9
|
+
* - Component mounts
|
|
10
|
+
* - Track changes (to update currentPlaylistId)
|
|
11
|
+
* - Playlists are modified via PlayerQueue methods
|
|
12
|
+
*
|
|
13
|
+
* Call `refreshPlaylists()` after creating/deleting playlists to update the state.
|
|
14
|
+
*
|
|
15
|
+
* @returns Object containing playlist state and refresh function
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* function MyComponent() {
|
|
20
|
+
* const { currentPlaylist, allTracks, refreshPlaylists } = usePlaylist();
|
|
21
|
+
*
|
|
22
|
+
* const handleCreatePlaylist = () => {
|
|
23
|
+
* PlayerQueue.createPlaylist('New Playlist');
|
|
24
|
+
* refreshPlaylists(); // Refresh to see the new playlist
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* return (
|
|
28
|
+
* <View>
|
|
29
|
+
* <Text>{currentPlaylist?.name}</Text>
|
|
30
|
+
* <Text>Total tracks: {allTracks.length}</Text>
|
|
31
|
+
* </View>
|
|
32
|
+
* );
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function usePlaylist() {
|
|
37
|
+
const [currentPlaylist, setCurrentPlaylist] = useState(null);
|
|
38
|
+
const [currentPlaylistId, setCurrentPlaylistId] = useState(null);
|
|
39
|
+
const [allPlaylists, setAllPlaylists] = useState([]);
|
|
40
|
+
const [allTracks, setAllTracks] = useState([]);
|
|
41
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
42
|
+
const isMounted = useRef(true);
|
|
43
|
+
const hasSubscribed = useRef(false);
|
|
44
|
+
const refreshPlaylists = useCallback(() => {
|
|
45
|
+
if (!isMounted.current)
|
|
46
|
+
return;
|
|
47
|
+
try {
|
|
48
|
+
// Get current playlist ID
|
|
49
|
+
const playlistId = PlayerQueue.getCurrentPlaylistId();
|
|
50
|
+
if (!isMounted.current)
|
|
51
|
+
return;
|
|
52
|
+
setCurrentPlaylistId(playlistId);
|
|
53
|
+
// Get current playlist details
|
|
54
|
+
if (playlistId) {
|
|
55
|
+
const playlist = PlayerQueue.getPlaylist(playlistId);
|
|
56
|
+
if (isMounted.current) {
|
|
57
|
+
setCurrentPlaylist(playlist);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (isMounted.current) {
|
|
62
|
+
setCurrentPlaylist(null);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Get all playlists
|
|
66
|
+
const playlists = PlayerQueue.getAllPlaylists();
|
|
67
|
+
if (!isMounted.current)
|
|
68
|
+
return;
|
|
69
|
+
setAllPlaylists(playlists);
|
|
70
|
+
// Get all tracks from all playlists (deduplicated by id)
|
|
71
|
+
const trackMap = new Map();
|
|
72
|
+
playlists.forEach((playlist) => {
|
|
73
|
+
playlist.tracks.forEach((track) => {
|
|
74
|
+
if (!trackMap.has(track.id)) {
|
|
75
|
+
trackMap.set(track.id, track);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
if (isMounted.current) {
|
|
80
|
+
setAllTracks(Array.from(trackMap.values()));
|
|
81
|
+
setIsLoading(false);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error('[usePlaylist] Error refreshing playlists:', error);
|
|
86
|
+
if (isMounted.current) {
|
|
87
|
+
setIsLoading(false);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}, []);
|
|
91
|
+
// Initialize and setup mounted ref
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
isMounted.current = true;
|
|
94
|
+
// Initial load
|
|
95
|
+
refreshPlaylists();
|
|
96
|
+
return () => {
|
|
97
|
+
isMounted.current = false;
|
|
98
|
+
};
|
|
99
|
+
}, [refreshPlaylists]);
|
|
100
|
+
// Subscribe to native playlist changes (only once)
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (hasSubscribed.current)
|
|
103
|
+
return;
|
|
104
|
+
hasSubscribed.current = true;
|
|
105
|
+
try {
|
|
106
|
+
PlayerQueue.onPlaylistsChanged(() => {
|
|
107
|
+
if (isMounted.current) {
|
|
108
|
+
refreshPlaylists();
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('[usePlaylist] Error setting up playlist listener:', error);
|
|
114
|
+
}
|
|
115
|
+
}, [refreshPlaylists]);
|
|
116
|
+
// Also refresh when track changes (as it might indicate playlist loaded)
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
const unsubscribe = callbackManager.subscribeToTrackChange(() => {
|
|
119
|
+
// Refresh to update currentPlaylistId when track changes
|
|
120
|
+
if (isMounted.current) {
|
|
121
|
+
refreshPlaylists();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return () => {
|
|
125
|
+
unsubscribe();
|
|
126
|
+
};
|
|
127
|
+
}, [refreshPlaylists]);
|
|
128
|
+
return {
|
|
129
|
+
currentPlaylist,
|
|
130
|
+
currentPlaylistId,
|
|
131
|
+
allPlaylists,
|
|
132
|
+
allTracks,
|
|
133
|
+
isLoading,
|
|
134
|
+
refreshPlaylists,
|
|
135
|
+
};
|
|
136
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -11,4 +11,5 @@ export * from './hooks';
|
|
|
11
11
|
export * from './types/PlayerQueue';
|
|
12
12
|
export * from './types/AndroidAutoMediaLibrary';
|
|
13
13
|
export type { TAudioDevice } from './specs/AudioDevices.nitro';
|
|
14
|
+
export type { RepeatMode } from './specs/TrackPlayer.nitro';
|
|
14
15
|
export { AndroidAutoMediaLibraryHelper } from './utils/androidAutoMediaLibrary';
|
|
@@ -18,6 +18,7 @@ export interface PlayerQueue extends HybridObject<{
|
|
|
18
18
|
onPlaylistsChanged(callback: (playlists: Playlist[], operation?: QueueOperation) => void): void;
|
|
19
19
|
onPlaylistChanged(callback: (playlistId: string, playlist: Playlist, operation?: QueueOperation) => void): void;
|
|
20
20
|
}
|
|
21
|
+
export type RepeatMode = 'off' | 'Playlist' | 'track';
|
|
21
22
|
export interface TrackPlayer extends HybridObject<{
|
|
22
23
|
android: 'kotlin';
|
|
23
24
|
ios: 'swift';
|
|
@@ -28,7 +29,11 @@ export interface TrackPlayer extends HybridObject<{
|
|
|
28
29
|
skipToNext(): void;
|
|
29
30
|
skipToPrevious(): void;
|
|
30
31
|
seek(position: number): void;
|
|
32
|
+
addToUpNext(trackId: string): void;
|
|
33
|
+
playNext(trackId: string): void;
|
|
34
|
+
getActualQueue(): TrackItem[];
|
|
31
35
|
getState(): PlayerState;
|
|
36
|
+
setRepeatMode(mode: RepeatMode): boolean;
|
|
32
37
|
configure(config: PlayerConfig): void;
|
|
33
38
|
onChangeTrack(callback: (track: TrackItem, reason?: Reason) => void): void;
|
|
34
39
|
onPlaybackStateChange(callback: (state: TrackPlayerState, reason?: Reason) => void): void;
|
|
@@ -36,4 +41,5 @@ export interface TrackPlayer extends HybridObject<{
|
|
|
36
41
|
onPlaybackProgressChange(callback: (position: number, totalDuration: number, isManuallySeeked?: boolean) => void): void;
|
|
37
42
|
onAndroidAutoConnectionChange(callback: (connected: boolean) => void): void;
|
|
38
43
|
isAndroidAutoConnected(): boolean;
|
|
44
|
+
setVolume(volume: number): boolean;
|
|
39
45
|
}
|
|
@@ -7,30 +7,35 @@
|
|
|
7
7
|
|
|
8
8
|
#include "JHybridTrackPlayerSpec.hpp"
|
|
9
9
|
|
|
10
|
-
// Forward declaration of `PlayerState` to properly resolve imports.
|
|
11
|
-
namespace margelo::nitro::nitroplayer { struct PlayerState; }
|
|
12
10
|
// Forward declaration of `TrackItem` to properly resolve imports.
|
|
13
11
|
namespace margelo::nitro::nitroplayer { struct TrackItem; }
|
|
12
|
+
// Forward declaration of `PlayerState` to properly resolve imports.
|
|
13
|
+
namespace margelo::nitro::nitroplayer { struct PlayerState; }
|
|
14
14
|
// Forward declaration of `TrackPlayerState` to properly resolve imports.
|
|
15
15
|
namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
|
|
16
|
+
// Forward declaration of `RepeatMode` to properly resolve imports.
|
|
17
|
+
namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
|
|
16
18
|
// Forward declaration of `PlayerConfig` to properly resolve imports.
|
|
17
19
|
namespace margelo::nitro::nitroplayer { struct PlayerConfig; }
|
|
18
20
|
// Forward declaration of `Reason` to properly resolve imports.
|
|
19
21
|
namespace margelo::nitro::nitroplayer { enum class Reason; }
|
|
20
22
|
|
|
21
|
-
#include "PlayerState.hpp"
|
|
22
|
-
#include "JPlayerState.hpp"
|
|
23
|
-
#include <NitroModules/Null.hpp>
|
|
24
23
|
#include "TrackItem.hpp"
|
|
25
|
-
#include <
|
|
26
|
-
#include <optional>
|
|
27
|
-
#include "JVariant_NullType_TrackItem.hpp"
|
|
28
|
-
#include <NitroModules/JNull.hpp>
|
|
24
|
+
#include <vector>
|
|
29
25
|
#include "JTrackItem.hpp"
|
|
30
26
|
#include <string>
|
|
27
|
+
#include <NitroModules/Null.hpp>
|
|
28
|
+
#include <variant>
|
|
29
|
+
#include <optional>
|
|
31
30
|
#include "JVariant_NullType_String.hpp"
|
|
31
|
+
#include <NitroModules/JNull.hpp>
|
|
32
|
+
#include "PlayerState.hpp"
|
|
33
|
+
#include "JPlayerState.hpp"
|
|
34
|
+
#include "JVariant_NullType_TrackItem.hpp"
|
|
32
35
|
#include "TrackPlayerState.hpp"
|
|
33
36
|
#include "JTrackPlayerState.hpp"
|
|
37
|
+
#include "RepeatMode.hpp"
|
|
38
|
+
#include "JRepeatMode.hpp"
|
|
34
39
|
#include "PlayerConfig.hpp"
|
|
35
40
|
#include "JPlayerConfig.hpp"
|
|
36
41
|
#include "Reason.hpp"
|
|
@@ -99,11 +104,38 @@ namespace margelo::nitro::nitroplayer {
|
|
|
99
104
|
static const auto method = javaClassStatic()->getMethod<void(double /* position */)>("seek");
|
|
100
105
|
method(_javaPart, position);
|
|
101
106
|
}
|
|
107
|
+
void JHybridTrackPlayerSpec::addToUpNext(const std::string& trackId) {
|
|
108
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* trackId */)>("addToUpNext");
|
|
109
|
+
method(_javaPart, jni::make_jstring(trackId));
|
|
110
|
+
}
|
|
111
|
+
void JHybridTrackPlayerSpec::playNext(const std::string& trackId) {
|
|
112
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* trackId */)>("playNext");
|
|
113
|
+
method(_javaPart, jni::make_jstring(trackId));
|
|
114
|
+
}
|
|
115
|
+
std::vector<TrackItem> JHybridTrackPlayerSpec::getActualQueue() {
|
|
116
|
+
static const auto method = javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JTrackItem>>()>("getActualQueue");
|
|
117
|
+
auto __result = method(_javaPart);
|
|
118
|
+
return [&]() {
|
|
119
|
+
size_t __size = __result->size();
|
|
120
|
+
std::vector<TrackItem> __vector;
|
|
121
|
+
__vector.reserve(__size);
|
|
122
|
+
for (size_t __i = 0; __i < __size; __i++) {
|
|
123
|
+
auto __element = __result->getElement(__i);
|
|
124
|
+
__vector.push_back(__element->toCpp());
|
|
125
|
+
}
|
|
126
|
+
return __vector;
|
|
127
|
+
}();
|
|
128
|
+
}
|
|
102
129
|
PlayerState JHybridTrackPlayerSpec::getState() {
|
|
103
130
|
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPlayerState>()>("getState");
|
|
104
131
|
auto __result = method(_javaPart);
|
|
105
132
|
return __result->toCpp();
|
|
106
133
|
}
|
|
134
|
+
bool JHybridTrackPlayerSpec::setRepeatMode(RepeatMode mode) {
|
|
135
|
+
static const auto method = javaClassStatic()->getMethod<jboolean(jni::alias_ref<JRepeatMode> /* mode */)>("setRepeatMode");
|
|
136
|
+
auto __result = method(_javaPart, JRepeatMode::fromCpp(mode));
|
|
137
|
+
return static_cast<bool>(__result);
|
|
138
|
+
}
|
|
107
139
|
void JHybridTrackPlayerSpec::configure(const PlayerConfig& config) {
|
|
108
140
|
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JPlayerConfig> /* config */)>("configure");
|
|
109
141
|
method(_javaPart, JPlayerConfig::fromCpp(config));
|
|
@@ -133,5 +165,10 @@ namespace margelo::nitro::nitroplayer {
|
|
|
133
165
|
auto __result = method(_javaPart);
|
|
134
166
|
return static_cast<bool>(__result);
|
|
135
167
|
}
|
|
168
|
+
bool JHybridTrackPlayerSpec::setVolume(double volume) {
|
|
169
|
+
static const auto method = javaClassStatic()->getMethod<jboolean(double /* volume */)>("setVolume");
|
|
170
|
+
auto __result = method(_javaPart, volume);
|
|
171
|
+
return static_cast<bool>(__result);
|
|
172
|
+
}
|
|
136
173
|
|
|
137
174
|
} // namespace margelo::nitro::nitroplayer
|
|
@@ -60,7 +60,11 @@ namespace margelo::nitro::nitroplayer {
|
|
|
60
60
|
void skipToNext() override;
|
|
61
61
|
void skipToPrevious() override;
|
|
62
62
|
void seek(double position) override;
|
|
63
|
+
void addToUpNext(const std::string& trackId) override;
|
|
64
|
+
void playNext(const std::string& trackId) override;
|
|
65
|
+
std::vector<TrackItem> getActualQueue() override;
|
|
63
66
|
PlayerState getState() override;
|
|
67
|
+
bool setRepeatMode(RepeatMode mode) override;
|
|
64
68
|
void configure(const PlayerConfig& config) override;
|
|
65
69
|
void onChangeTrack(const std::function<void(const TrackItem& /* track */, std::optional<Reason> /* reason */)>& callback) override;
|
|
66
70
|
void onPlaybackStateChange(const std::function<void(TrackPlayerState /* state */, std::optional<Reason> /* reason */)>& callback) override;
|
|
@@ -68,6 +72,7 @@ namespace margelo::nitro::nitroplayer {
|
|
|
68
72
|
void onPlaybackProgressChange(const std::function<void(double /* position */, double /* totalDuration */, std::optional<bool> /* isManuallySeeked */)>& callback) override;
|
|
69
73
|
void onAndroidAutoConnectionChange(const std::function<void(bool /* connected */)>& callback) override;
|
|
70
74
|
bool isAndroidAutoConnected() override;
|
|
75
|
+
bool setVolume(double volume) override;
|
|
71
76
|
|
|
72
77
|
private:
|
|
73
78
|
friend HybridBase;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JRepeatMode.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 "RepeatMode.hpp"
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro::nitroplayer {
|
|
14
|
+
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The C++ JNI bridge between the C++ enum "RepeatMode" and the the Kotlin enum "RepeatMode".
|
|
19
|
+
*/
|
|
20
|
+
struct JRepeatMode final: public jni::JavaClass<JRepeatMode> {
|
|
21
|
+
public:
|
|
22
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/nitroplayer/RepeatMode;";
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
/**
|
|
26
|
+
* Convert this Java/Kotlin-based enum to the C++ enum RepeatMode.
|
|
27
|
+
*/
|
|
28
|
+
[[maybe_unused]]
|
|
29
|
+
[[nodiscard]]
|
|
30
|
+
RepeatMode 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<RepeatMode>(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<JRepeatMode> fromCpp(RepeatMode value) {
|
|
43
|
+
static const auto clazz = javaClassStatic();
|
|
44
|
+
static const auto fieldOFF = clazz->getStaticField<JRepeatMode>("OFF");
|
|
45
|
+
static const auto fieldPLAYLIST = clazz->getStaticField<JRepeatMode>("PLAYLIST");
|
|
46
|
+
static const auto fieldTRACK = clazz->getStaticField<JRepeatMode>("TRACK");
|
|
47
|
+
|
|
48
|
+
switch (value) {
|
|
49
|
+
case RepeatMode::OFF:
|
|
50
|
+
return clazz->getStaticFieldValue(fieldOFF);
|
|
51
|
+
case RepeatMode::PLAYLIST:
|
|
52
|
+
return clazz->getStaticFieldValue(fieldPLAYLIST);
|
|
53
|
+
case RepeatMode::TRACK:
|
|
54
|
+
return clazz->getStaticFieldValue(fieldTRACK);
|
|
55
|
+
default:
|
|
56
|
+
std::string stringValue = std::to_string(static_cast<int>(value));
|
|
57
|
+
throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace margelo::nitro::nitroplayer
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt
CHANGED
|
@@ -69,10 +69,26 @@ abstract class HybridTrackPlayerSpec: HybridObject() {
|
|
|
69
69
|
@Keep
|
|
70
70
|
abstract fun seek(position: Double): Unit
|
|
71
71
|
|
|
72
|
+
@DoNotStrip
|
|
73
|
+
@Keep
|
|
74
|
+
abstract fun addToUpNext(trackId: String): Unit
|
|
75
|
+
|
|
76
|
+
@DoNotStrip
|
|
77
|
+
@Keep
|
|
78
|
+
abstract fun playNext(trackId: String): Unit
|
|
79
|
+
|
|
80
|
+
@DoNotStrip
|
|
81
|
+
@Keep
|
|
82
|
+
abstract fun getActualQueue(): Array<TrackItem>
|
|
83
|
+
|
|
72
84
|
@DoNotStrip
|
|
73
85
|
@Keep
|
|
74
86
|
abstract fun getState(): PlayerState
|
|
75
87
|
|
|
88
|
+
@DoNotStrip
|
|
89
|
+
@Keep
|
|
90
|
+
abstract fun setRepeatMode(mode: RepeatMode): Boolean
|
|
91
|
+
|
|
76
92
|
@DoNotStrip
|
|
77
93
|
@Keep
|
|
78
94
|
abstract fun configure(config: PlayerConfig): Unit
|
|
@@ -125,6 +141,10 @@ abstract class HybridTrackPlayerSpec: HybridObject() {
|
|
|
125
141
|
@DoNotStrip
|
|
126
142
|
@Keep
|
|
127
143
|
abstract fun isAndroidAutoConnected(): Boolean
|
|
144
|
+
|
|
145
|
+
@DoNotStrip
|
|
146
|
+
@Keep
|
|
147
|
+
abstract fun setVolume(volume: Double): Boolean
|
|
128
148
|
|
|
129
149
|
private external fun initHybrid(): HybridData
|
|
130
150
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// RepeatMode.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.proguard.annotations.DoNotStrip
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents the JavaScript enum/union "RepeatMode".
|
|
15
|
+
*/
|
|
16
|
+
@DoNotStrip
|
|
17
|
+
@Keep
|
|
18
|
+
enum class RepeatMode(@DoNotStrip @Keep val value: Int) {
|
|
19
|
+
OFF(0),
|
|
20
|
+
PLAYLIST(1),
|
|
21
|
+
TRACK(2);
|
|
22
|
+
}
|
|
@@ -510,6 +510,15 @@ namespace margelo::nitro::nitroplayer::bridge::swift {
|
|
|
510
510
|
using std__weak_ptr_HybridTrackPlayerSpec_ = std::weak_ptr<HybridTrackPlayerSpec>;
|
|
511
511
|
inline std__weak_ptr_HybridTrackPlayerSpec_ weakify_std__shared_ptr_HybridTrackPlayerSpec_(const std::shared_ptr<HybridTrackPlayerSpec>& strong) noexcept { return strong; }
|
|
512
512
|
|
|
513
|
+
// pragma MARK: Result<std::vector<TrackItem>>
|
|
514
|
+
using Result_std__vector_TrackItem__ = Result<std::vector<TrackItem>>;
|
|
515
|
+
inline Result_std__vector_TrackItem__ create_Result_std__vector_TrackItem__(const std::vector<TrackItem>& value) noexcept {
|
|
516
|
+
return Result<std::vector<TrackItem>>::withValue(value);
|
|
517
|
+
}
|
|
518
|
+
inline Result_std__vector_TrackItem__ create_Result_std__vector_TrackItem__(const std::exception_ptr& error) noexcept {
|
|
519
|
+
return Result<std::vector<TrackItem>>::withError(error);
|
|
520
|
+
}
|
|
521
|
+
|
|
513
522
|
// pragma MARK: Result<PlayerState>
|
|
514
523
|
using Result_PlayerState_ = Result<PlayerState>;
|
|
515
524
|
inline Result_PlayerState_ create_Result_PlayerState_(const PlayerState& value) noexcept {
|
|
@@ -24,6 +24,8 @@ namespace margelo::nitro::nitroplayer { struct Playlist; }
|
|
|
24
24
|
namespace margelo::nitro::nitroplayer { enum class QueueOperation; }
|
|
25
25
|
// Forward declaration of `Reason` to properly resolve imports.
|
|
26
26
|
namespace margelo::nitro::nitroplayer { enum class Reason; }
|
|
27
|
+
// Forward declaration of `RepeatMode` to properly resolve imports.
|
|
28
|
+
namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
|
|
27
29
|
// Forward declaration of `TrackItem` to properly resolve imports.
|
|
28
30
|
namespace margelo::nitro::nitroplayer { struct TrackItem; }
|
|
29
31
|
// Forward declaration of `TrackPlayerState` to properly resolve imports.
|
|
@@ -38,6 +40,7 @@ namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
|
|
|
38
40
|
#include "Playlist.hpp"
|
|
39
41
|
#include "QueueOperation.hpp"
|
|
40
42
|
#include "Reason.hpp"
|
|
43
|
+
#include "RepeatMode.hpp"
|
|
41
44
|
#include "TrackItem.hpp"
|
|
42
45
|
#include "TrackPlayerState.hpp"
|
|
43
46
|
#include <NitroModules/Null.hpp>
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
// Forward declaration of `HybridTrackPlayerSpec_cxx` to properly resolve imports.
|
|
13
13
|
namespace NitroPlayer { class HybridTrackPlayerSpec_cxx; }
|
|
14
14
|
|
|
15
|
-
// Forward declaration of `PlayerState` to properly resolve imports.
|
|
16
|
-
namespace margelo::nitro::nitroplayer { struct PlayerState; }
|
|
17
15
|
// Forward declaration of `TrackItem` to properly resolve imports.
|
|
18
16
|
namespace margelo::nitro::nitroplayer { struct TrackItem; }
|
|
17
|
+
// Forward declaration of `PlayerState` to properly resolve imports.
|
|
18
|
+
namespace margelo::nitro::nitroplayer { struct PlayerState; }
|
|
19
19
|
// Forward declaration of `TrackPlayerState` to properly resolve imports.
|
|
20
20
|
namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
|
|
21
|
+
// Forward declaration of `RepeatMode` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
|
|
21
23
|
// Forward declaration of `PlayerConfig` to properly resolve imports.
|
|
22
24
|
namespace margelo::nitro::nitroplayer { struct PlayerConfig; }
|
|
23
25
|
// Forward declaration of `Reason` to properly resolve imports.
|
|
@@ -25,11 +27,13 @@ namespace margelo::nitro::nitroplayer { enum class Reason; }
|
|
|
25
27
|
|
|
26
28
|
#include <string>
|
|
27
29
|
#include <optional>
|
|
28
|
-
#include "PlayerState.hpp"
|
|
29
|
-
#include <NitroModules/Null.hpp>
|
|
30
30
|
#include "TrackItem.hpp"
|
|
31
|
+
#include <vector>
|
|
32
|
+
#include <NitroModules/Null.hpp>
|
|
31
33
|
#include <variant>
|
|
34
|
+
#include "PlayerState.hpp"
|
|
32
35
|
#include "TrackPlayerState.hpp"
|
|
36
|
+
#include "RepeatMode.hpp"
|
|
33
37
|
#include "PlayerConfig.hpp"
|
|
34
38
|
#include "Reason.hpp"
|
|
35
39
|
#include <functional>
|
|
@@ -114,6 +118,26 @@ namespace margelo::nitro::nitroplayer {
|
|
|
114
118
|
std::rethrow_exception(__result.error());
|
|
115
119
|
}
|
|
116
120
|
}
|
|
121
|
+
inline void addToUpNext(const std::string& trackId) override {
|
|
122
|
+
auto __result = _swiftPart.addToUpNext(trackId);
|
|
123
|
+
if (__result.hasError()) [[unlikely]] {
|
|
124
|
+
std::rethrow_exception(__result.error());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
inline void playNext(const std::string& trackId) override {
|
|
128
|
+
auto __result = _swiftPart.playNext(trackId);
|
|
129
|
+
if (__result.hasError()) [[unlikely]] {
|
|
130
|
+
std::rethrow_exception(__result.error());
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
inline std::vector<TrackItem> getActualQueue() override {
|
|
134
|
+
auto __result = _swiftPart.getActualQueue();
|
|
135
|
+
if (__result.hasError()) [[unlikely]] {
|
|
136
|
+
std::rethrow_exception(__result.error());
|
|
137
|
+
}
|
|
138
|
+
auto __value = std::move(__result.value());
|
|
139
|
+
return __value;
|
|
140
|
+
}
|
|
117
141
|
inline PlayerState getState() override {
|
|
118
142
|
auto __result = _swiftPart.getState();
|
|
119
143
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -122,6 +146,14 @@ namespace margelo::nitro::nitroplayer {
|
|
|
122
146
|
auto __value = std::move(__result.value());
|
|
123
147
|
return __value;
|
|
124
148
|
}
|
|
149
|
+
inline bool setRepeatMode(RepeatMode mode) override {
|
|
150
|
+
auto __result = _swiftPart.setRepeatMode(static_cast<int>(mode));
|
|
151
|
+
if (__result.hasError()) [[unlikely]] {
|
|
152
|
+
std::rethrow_exception(__result.error());
|
|
153
|
+
}
|
|
154
|
+
auto __value = std::move(__result.value());
|
|
155
|
+
return __value;
|
|
156
|
+
}
|
|
125
157
|
inline void configure(const PlayerConfig& config) override {
|
|
126
158
|
auto __result = _swiftPart.configure(std::forward<decltype(config)>(config));
|
|
127
159
|
if (__result.hasError()) [[unlikely]] {
|
|
@@ -166,6 +198,14 @@ namespace margelo::nitro::nitroplayer {
|
|
|
166
198
|
auto __value = std::move(__result.value());
|
|
167
199
|
return __value;
|
|
168
200
|
}
|
|
201
|
+
inline bool setVolume(double volume) override {
|
|
202
|
+
auto __result = _swiftPart.setVolume(std::forward<decltype(volume)>(volume));
|
|
203
|
+
if (__result.hasError()) [[unlikely]] {
|
|
204
|
+
std::rethrow_exception(__result.error());
|
|
205
|
+
}
|
|
206
|
+
auto __value = std::move(__result.value());
|
|
207
|
+
return __value;
|
|
208
|
+
}
|
|
169
209
|
|
|
170
210
|
private:
|
|
171
211
|
NitroPlayer::HybridTrackPlayerSpec_cxx _swiftPart;
|
|
@@ -20,7 +20,11 @@ public protocol HybridTrackPlayerSpec_protocol: HybridObject {
|
|
|
20
20
|
func skipToNext() throws -> Void
|
|
21
21
|
func skipToPrevious() throws -> Void
|
|
22
22
|
func seek(position: Double) throws -> Void
|
|
23
|
+
func addToUpNext(trackId: String) throws -> Void
|
|
24
|
+
func playNext(trackId: String) throws -> Void
|
|
25
|
+
func getActualQueue() throws -> [TrackItem]
|
|
23
26
|
func getState() throws -> PlayerState
|
|
27
|
+
func setRepeatMode(mode: RepeatMode) throws -> Bool
|
|
24
28
|
func configure(config: PlayerConfig) throws -> Void
|
|
25
29
|
func onChangeTrack(callback: @escaping (_ track: TrackItem, _ reason: Reason?) -> Void) throws -> Void
|
|
26
30
|
func onPlaybackStateChange(callback: @escaping (_ state: TrackPlayerState, _ reason: Reason?) -> Void) throws -> Void
|
|
@@ -28,6 +32,7 @@ public protocol HybridTrackPlayerSpec_protocol: HybridObject {
|
|
|
28
32
|
func onPlaybackProgressChange(callback: @escaping (_ position: Double, _ totalDuration: Double, _ isManuallySeeked: Bool?) -> Void) throws -> Void
|
|
29
33
|
func onAndroidAutoConnectionChange(callback: @escaping (_ connected: Bool) -> Void) throws -> Void
|
|
30
34
|
func isAndroidAutoConnected() throws -> Bool
|
|
35
|
+
func setVolume(volume: Double) throws -> Bool
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
public extension HybridTrackPlayerSpec_protocol {
|