react-native-nitro-player 0.0.1

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.
Files changed (191) hide show
  1. package/NitroPlayer.podspec +31 -0
  2. package/README.md +610 -0
  3. package/android/CMakeLists.txt +29 -0
  4. package/android/build.gradle +147 -0
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/cpp/cpp-adapter.cpp +7 -0
  9. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrary.kt +29 -0
  10. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAudioDevices.kt +116 -0
  11. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridPlayerQueue.kt +167 -0
  12. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +93 -0
  13. package/android/src/main/java/com/margelo/nitro/nitroplayer/NitroPlayerPackage.kt +21 -0
  14. package/android/src/main/java/com/margelo/nitro/nitroplayer/connection/AndroidAutoConnectionDetector.kt +171 -0
  15. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +639 -0
  16. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaBrowserService.kt +352 -0
  17. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaLibrary.kt +58 -0
  18. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaLibraryManager.kt +77 -0
  19. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaLibraryParser.kt +73 -0
  20. package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaSessionManager.kt +506 -0
  21. package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/Playlist.kt +21 -0
  22. package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +454 -0
  23. package/android/src/main/java/com/margelo/nitro/nitroplayer/queue/Queue.kt +94 -0
  24. package/android/src/main/java/com/margelo/nitro/nitroplayer/queue/QueueManager.kt +143 -0
  25. package/ios/HybridAudioRoutePicker.swift +53 -0
  26. package/ios/HybridTrackPlayer.swift +100 -0
  27. package/ios/core/TrackPlayerCore.swift +1040 -0
  28. package/ios/media/MediaSessionManager.swift +230 -0
  29. package/ios/playlist/PlaylistManager.swift +446 -0
  30. package/ios/playlist/PlaylistModel.swift +49 -0
  31. package/ios/queue/HybridPlayerQueue.swift +95 -0
  32. package/ios/queue/Queue.swift +126 -0
  33. package/ios/queue/QueueManager.swift +157 -0
  34. package/lib/hooks/index.d.ts +6 -0
  35. package/lib/hooks/index.js +6 -0
  36. package/lib/hooks/useAndroidAutoConnection.d.ts +13 -0
  37. package/lib/hooks/useAndroidAutoConnection.js +26 -0
  38. package/lib/hooks/useAudioDevices.d.ts +26 -0
  39. package/lib/hooks/useAudioDevices.js +55 -0
  40. package/lib/hooks/useOnChangeTrack.d.ts +9 -0
  41. package/lib/hooks/useOnChangeTrack.js +17 -0
  42. package/lib/hooks/useOnPlaybackProgressChange.d.ts +9 -0
  43. package/lib/hooks/useOnPlaybackProgressChange.js +19 -0
  44. package/lib/hooks/useOnPlaybackStateChange.d.ts +9 -0
  45. package/lib/hooks/useOnPlaybackStateChange.js +17 -0
  46. package/lib/hooks/useOnSeek.d.ts +8 -0
  47. package/lib/hooks/useOnSeek.js +17 -0
  48. package/lib/index.d.ts +14 -0
  49. package/lib/index.js +24 -0
  50. package/lib/specs/AndroidAutoMediaLibrary.nitro.d.ts +21 -0
  51. package/lib/specs/AndroidAutoMediaLibrary.nitro.js +1 -0
  52. package/lib/specs/AudioDevices.nitro.d.ts +24 -0
  53. package/lib/specs/AudioDevices.nitro.js +1 -0
  54. package/lib/specs/AudioRoutePicker.nitro.d.ts +10 -0
  55. package/lib/specs/AudioRoutePicker.nitro.js +1 -0
  56. package/lib/specs/TrackPlayer.nitro.d.ts +39 -0
  57. package/lib/specs/TrackPlayer.nitro.js +1 -0
  58. package/lib/types/AndroidAutoMediaLibrary.d.ts +44 -0
  59. package/lib/types/AndroidAutoMediaLibrary.js +1 -0
  60. package/lib/types/PlayerQueue.d.ts +32 -0
  61. package/lib/types/PlayerQueue.js +1 -0
  62. package/lib/utils/androidAutoMediaLibrary.d.ts +47 -0
  63. package/lib/utils/androidAutoMediaLibrary.js +62 -0
  64. package/nitro.json +31 -0
  65. package/nitrogen/generated/.gitattributes +1 -0
  66. package/nitrogen/generated/android/NitroPlayer+autolinking.cmake +91 -0
  67. package/nitrogen/generated/android/NitroPlayer+autolinking.gradle +27 -0
  68. package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +88 -0
  69. package/nitrogen/generated/android/NitroPlayerOnLoad.hpp +25 -0
  70. package/nitrogen/generated/android/c++/JFunc_void_TrackItem_std__optional_Reason_.hpp +85 -0
  71. package/nitrogen/generated/android/c++/JFunc_void_TrackPlayerState_std__optional_Reason_.hpp +80 -0
  72. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  73. package/nitrogen/generated/android/c++/JFunc_void_double_double.hpp +75 -0
  74. package/nitrogen/generated/android/c++/JFunc_void_double_double_std__optional_bool_.hpp +76 -0
  75. package/nitrogen/generated/android/c++/JFunc_void_std__string_Playlist_std__optional_QueueOperation_.hpp +88 -0
  76. package/nitrogen/generated/android/c++/JFunc_void_std__vector_Playlist__std__optional_QueueOperation_.hpp +106 -0
  77. package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.cpp +55 -0
  78. package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.hpp +66 -0
  79. package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.cpp +70 -0
  80. package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.hpp +66 -0
  81. package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +143 -0
  82. package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.hpp +77 -0
  83. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +137 -0
  84. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +78 -0
  85. package/nitrogen/generated/android/c++/JPlayerConfig.hpp +65 -0
  86. package/nitrogen/generated/android/c++/JPlayerState.hpp +87 -0
  87. package/nitrogen/generated/android/c++/JPlaylist.hpp +99 -0
  88. package/nitrogen/generated/android/c++/JQueueOperation.hpp +65 -0
  89. package/nitrogen/generated/android/c++/JReason.hpp +65 -0
  90. package/nitrogen/generated/android/c++/JTAudioDevice.hpp +69 -0
  91. package/nitrogen/generated/android/c++/JTrackItem.hpp +86 -0
  92. package/nitrogen/generated/android/c++/JTrackPlayerState.hpp +62 -0
  93. package/nitrogen/generated/android/c++/JVariant_NullType_Playlist.cpp +26 -0
  94. package/nitrogen/generated/android/c++/JVariant_NullType_Playlist.hpp +77 -0
  95. package/nitrogen/generated/android/c++/JVariant_NullType_String.cpp +26 -0
  96. package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +70 -0
  97. package/nitrogen/generated/android/c++/JVariant_NullType_TrackItem.cpp +26 -0
  98. package/nitrogen/generated/android/c++/JVariant_NullType_TrackItem.hpp +74 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_TrackItem_std__optional_Reason_.kt +80 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_TrackPlayerState_std__optional_Reason_.kt +80 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_bool.kt +80 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_double_double.kt +80 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_double_double_std__optional_bool_.kt +80 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__string_Playlist_std__optional_QueueOperation_.kt +80 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__vector_Playlist__std__optional_QueueOperation_.kt +80 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrarySpec.kt +61 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAudioDevicesSpec.kt +61 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt +116 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +134 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/NitroPlayerOnLoad.kt +35 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlayerConfig.kt +44 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/PlayerState.kt +53 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Playlist.kt +50 -0
  114. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/QueueOperation.kt +23 -0
  115. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Reason.kt +23 -0
  116. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TAudioDevice.kt +47 -0
  117. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TrackItem.kt +56 -0
  118. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TrackPlayerState.kt +22 -0
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Playlist.kt +59 -0
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_String.kt +59 -0
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_TrackItem.kt +59 -0
  122. package/nitrogen/generated/ios/NitroPlayer+autolinking.rb +60 -0
  123. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +123 -0
  124. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +531 -0
  125. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Umbrella.hpp +80 -0
  126. package/nitrogen/generated/ios/NitroPlayerAutolinking.mm +49 -0
  127. package/nitrogen/generated/ios/NitroPlayerAutolinking.swift +55 -0
  128. package/nitrogen/generated/ios/c++/HybridAudioRoutePickerSpecSwift.cpp +11 -0
  129. package/nitrogen/generated/ios/c++/HybridAudioRoutePickerSpecSwift.hpp +74 -0
  130. package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.cpp +11 -0
  131. package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.hpp +167 -0
  132. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.cpp +11 -0
  133. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +174 -0
  134. package/nitrogen/generated/ios/swift/Func_void_TrackItem_std__optional_Reason_.swift +47 -0
  135. package/nitrogen/generated/ios/swift/Func_void_TrackPlayerState_std__optional_Reason_.swift +47 -0
  136. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  137. package/nitrogen/generated/ios/swift/Func_void_double_double.swift +47 -0
  138. package/nitrogen/generated/ios/swift/Func_void_double_double_std__optional_bool_.swift +54 -0
  139. package/nitrogen/generated/ios/swift/Func_void_std__string_Playlist_std__optional_QueueOperation_.swift +47 -0
  140. package/nitrogen/generated/ios/swift/Func_void_std__vector_Playlist__std__optional_QueueOperation_.swift +47 -0
  141. package/nitrogen/generated/ios/swift/HybridAudioRoutePickerSpec.swift +56 -0
  142. package/nitrogen/generated/ios/swift/HybridAudioRoutePickerSpec_cxx.swift +130 -0
  143. package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec.swift +68 -0
  144. package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec_cxx.swift +349 -0
  145. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +69 -0
  146. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +325 -0
  147. package/nitrogen/generated/ios/swift/PlayerConfig.swift +115 -0
  148. package/nitrogen/generated/ios/swift/PlayerState.swift +181 -0
  149. package/nitrogen/generated/ios/swift/Playlist.swift +182 -0
  150. package/nitrogen/generated/ios/swift/QueueOperation.swift +48 -0
  151. package/nitrogen/generated/ios/swift/Reason.swift +48 -0
  152. package/nitrogen/generated/ios/swift/TrackItem.swift +147 -0
  153. package/nitrogen/generated/ios/swift/TrackPlayerState.swift +44 -0
  154. package/nitrogen/generated/ios/swift/Variant_NullType_Playlist.swift +18 -0
  155. package/nitrogen/generated/ios/swift/Variant_NullType_String.swift +18 -0
  156. package/nitrogen/generated/ios/swift/Variant_NullType_TrackItem.swift +18 -0
  157. package/nitrogen/generated/shared/c++/HybridAndroidAutoMediaLibrarySpec.cpp +22 -0
  158. package/nitrogen/generated/shared/c++/HybridAndroidAutoMediaLibrarySpec.hpp +63 -0
  159. package/nitrogen/generated/shared/c++/HybridAudioDevicesSpec.cpp +22 -0
  160. package/nitrogen/generated/shared/c++/HybridAudioDevicesSpec.hpp +65 -0
  161. package/nitrogen/generated/shared/c++/HybridAudioRoutePickerSpec.cpp +21 -0
  162. package/nitrogen/generated/shared/c++/HybridAudioRoutePickerSpec.hpp +62 -0
  163. package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.cpp +33 -0
  164. package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.hpp +87 -0
  165. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +34 -0
  166. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +91 -0
  167. package/nitrogen/generated/shared/c++/PlayerConfig.hpp +83 -0
  168. package/nitrogen/generated/shared/c++/PlayerState.hpp +103 -0
  169. package/nitrogen/generated/shared/c++/Playlist.hpp +97 -0
  170. package/nitrogen/generated/shared/c++/QueueOperation.hpp +84 -0
  171. package/nitrogen/generated/shared/c++/Reason.hpp +84 -0
  172. package/nitrogen/generated/shared/c++/TAudioDevice.hpp +87 -0
  173. package/nitrogen/generated/shared/c++/TrackItem.hpp +102 -0
  174. package/nitrogen/generated/shared/c++/TrackPlayerState.hpp +80 -0
  175. package/package.json +172 -0
  176. package/react-native.config.js +16 -0
  177. package/src/hooks/index.ts +6 -0
  178. package/src/hooks/useAndroidAutoConnection.ts +30 -0
  179. package/src/hooks/useAudioDevices.ts +64 -0
  180. package/src/hooks/useOnChangeTrack.ts +24 -0
  181. package/src/hooks/useOnPlaybackProgressChange.ts +30 -0
  182. package/src/hooks/useOnPlaybackStateChange.ts +24 -0
  183. package/src/hooks/useOnSeek.ts +25 -0
  184. package/src/index.ts +47 -0
  185. package/src/specs/AndroidAutoMediaLibrary.nitro.ts +22 -0
  186. package/src/specs/AudioDevices.nitro.ts +25 -0
  187. package/src/specs/AudioRoutePicker.nitro.ts +9 -0
  188. package/src/specs/TrackPlayer.nitro.ts +81 -0
  189. package/src/types/AndroidAutoMediaLibrary.ts +58 -0
  190. package/src/types/PlayerQueue.ts +38 -0
  191. package/src/utils/androidAutoMediaLibrary.ts +66 -0
@@ -0,0 +1,147 @@
1
+ buildscript {
2
+ repositories {
3
+ google()
4
+ mavenCentral()
5
+ }
6
+
7
+ dependencies {
8
+ classpath "com.android.tools.build:gradle:8.13.0"
9
+ }
10
+ }
11
+
12
+ def reactNativeArchitectures() {
13
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
14
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
15
+ }
16
+
17
+ def isNewArchitectureEnabled() {
18
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19
+ }
20
+
21
+ apply plugin: "com.android.library"
22
+ apply plugin: 'org.jetbrains.kotlin.android'
23
+ apply from: '../nitrogen/generated/android/NitroPlayer+autolinking.gradle'
24
+ apply from: "./fix-prefab.gradle"
25
+
26
+ if (isNewArchitectureEnabled()) {
27
+ apply plugin: "com.facebook.react"
28
+ }
29
+
30
+ def getExtOrDefault(name) {
31
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["NitroPlayer_" + name]
32
+ }
33
+
34
+ def getExtOrIntegerDefault(name) {
35
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroPlayer_" + name]).toInteger()
36
+ }
37
+
38
+ android {
39
+ namespace "com.margelo.nitro.nitroplayer"
40
+
41
+ ndkVersion getExtOrDefault("ndkVersion")
42
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
43
+
44
+ defaultConfig {
45
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
46
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
47
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
48
+
49
+ externalNativeBuild {
50
+ cmake {
51
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
52
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
53
+ abiFilters (*reactNativeArchitectures())
54
+
55
+ buildTypes {
56
+ debug {
57
+ cppFlags "-O1 -g"
58
+ }
59
+ release {
60
+ cppFlags "-O2"
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ externalNativeBuild {
68
+ cmake {
69
+ path "CMakeLists.txt"
70
+ }
71
+ }
72
+
73
+ packagingOptions {
74
+ excludes = [
75
+ "META-INF",
76
+ "META-INF/**",
77
+ "**/libc++_shared.so",
78
+ "**/libfbjni.so",
79
+ "**/libjsi.so",
80
+ "**/libfolly_json.so",
81
+ "**/libfolly_runtime.so",
82
+ "**/libglog.so",
83
+ "**/libhermes.so",
84
+ "**/libhermes-executor-debug.so",
85
+ "**/libhermes_executor.so",
86
+ "**/libreactnative.so",
87
+ "**/libreactnativejni.so",
88
+ "**/libturbomodulejsijni.so",
89
+ "**/libreact_nativemodule_core.so",
90
+ "**/libjscexecutor.so"
91
+ ]
92
+ }
93
+
94
+ buildFeatures {
95
+ buildConfig true
96
+ prefab true
97
+ }
98
+
99
+ buildTypes {
100
+ release {
101
+ minifyEnabled false
102
+ }
103
+ }
104
+
105
+ lintOptions {
106
+ disable "GradleCompatible"
107
+ }
108
+
109
+ compileOptions {
110
+ sourceCompatibility JavaVersion.VERSION_1_8
111
+ targetCompatibility JavaVersion.VERSION_1_8
112
+ }
113
+
114
+ sourceSets {
115
+ main {
116
+ if (isNewArchitectureEnabled()) {
117
+ java.srcDirs += [
118
+ // React Codegen files
119
+ "${project.buildDir}/generated/source/codegen/java"
120
+ ]
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ repositories {
127
+ mavenCentral()
128
+ google()
129
+ }
130
+
131
+
132
+ def media3_version = "1.3.0"
133
+ dependencies {
134
+ // For < 0.71, this will be from the local maven repo
135
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
136
+ //noinspection GradleDynamicVersion
137
+ implementation "com.facebook.react:react-native:+"
138
+
139
+ // Add a dependency on NitroModules
140
+ implementation project(":react-native-nitro-modules")
141
+
142
+ implementation "androidx.media3:media3-exoplayer:$media3_version"
143
+ implementation "androidx.media3:media3-session:$media3_version"
144
+ implementation "androidx.media3:media3-common:$media3_version"
145
+ implementation "androidx.media:media:1.7.0"
146
+ }
147
+
@@ -0,0 +1,51 @@
1
+ tasks.configureEach { task ->
2
+ // Make sure that we generate our prefab publication file only after having built the native library
3
+ // so that not a header publication file, but a full configuration publication will be generated, which
4
+ // will include the .so file
5
+
6
+ def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
7
+ def matcher = task.name =~ prefabConfigurePattern
8
+ if (matcher.matches()) {
9
+ def variantName = matcher[0][1]
10
+ task.outputs.upToDateWhen { false }
11
+ task.dependsOn("externalNativeBuild${variantName}")
12
+ }
13
+ }
14
+
15
+ afterEvaluate {
16
+ def abis = reactNativeArchitectures()
17
+ rootProject.allprojects.each { proj ->
18
+ if (proj === rootProject) return
19
+
20
+ def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
21
+ config.dependencies.any { dep ->
22
+ dep.group == project.group && dep.name == project.name
23
+ }
24
+ }
25
+ if (!dependsOnThisLib && proj != project) return
26
+
27
+ if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
28
+ return
29
+ }
30
+
31
+ def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
32
+ // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
33
+ // generate a libnameConfig.cmake file that will contain our native library (.so).
34
+ // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
35
+ variants.all { variant ->
36
+ def variantName = variant.name
37
+ abis.each { abi ->
38
+ def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
39
+ if (!searchDir.exists()) return
40
+ def matches = []
41
+ searchDir.eachDir { randomDir ->
42
+ def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
43
+ if (prefabFile.exists()) matches << prefabFile
44
+ }
45
+ matches.each { prefabConfig ->
46
+ prefabConfig.setLastModified(System.currentTimeMillis())
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,5 @@
1
+ NitroPlayer_kotlinVersion=2.1.20
2
+ NitroPlayer_minSdkVersion=23
3
+ NitroPlayer_targetSdkVersion=36
4
+ NitroPlayer_compileSdkVersion=36
5
+ NitroPlayer_ndkVersion=27.1.12297006
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,7 @@
1
+ #include "NitroPlayerOnLoad.hpp"
2
+
3
+ #include <jni.h>
4
+
5
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
6
+ return margelo::nitro::nitroplayer::initialize(vm);
7
+ }
@@ -0,0 +1,29 @@
1
+ package com.margelo.nitro.nitroplayer
2
+
3
+ import androidx.annotation.Keep
4
+ import com.facebook.proguard.annotations.DoNotStrip
5
+ import com.margelo.nitro.NitroModules
6
+ import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
7
+
8
+ class HybridAndroidAutoMediaLibrary : HybridAndroidAutoMediaLibrarySpec() {
9
+ private val core: TrackPlayerCore
10
+
11
+ init {
12
+ val context =
13
+ NitroModules.applicationContext
14
+ ?: throw IllegalStateException("React Context is not initialized")
15
+ core = TrackPlayerCore.getInstance(context)
16
+ }
17
+
18
+ @DoNotStrip
19
+ @Keep
20
+ override fun setMediaLibrary(libraryJson: String) {
21
+ core.setAndroidAutoMediaLibrary(libraryJson)
22
+ }
23
+
24
+ @DoNotStrip
25
+ @Keep
26
+ override fun clearMediaLibrary() {
27
+ core.clearAndroidAutoMediaLibrary()
28
+ }
29
+ }
@@ -0,0 +1,116 @@
1
+ package com.margelo.nitro.nitroplayer
2
+
3
+ import android.content.Context
4
+ import android.media.AudioDeviceInfo
5
+ import android.media.AudioManager
6
+ import android.os.Build
7
+ import com.margelo.nitro.NitroModules
8
+
9
+ class HybridAudioDevices : HybridAudioDevicesSpec() {
10
+
11
+ val applicationContext = NitroModules.applicationContext;
12
+ private val audioManager = applicationContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
13
+
14
+ // Device types that can be set as communication devices
15
+ private val validCommunicationDeviceTypes: Set<Int> by lazy {
16
+ val types = mutableSetOf(
17
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
18
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
19
+ AudioDeviceInfo.TYPE_WIRED_HEADSET,
20
+ AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
21
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
22
+ AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
23
+ AudioDeviceInfo.TYPE_USB_HEADSET
24
+ )
25
+ // BLE types are only available on Android S (API 31) and above
26
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
27
+ types.add(AudioDeviceInfo.TYPE_BLE_HEADSET)
28
+ types.add(AudioDeviceInfo.TYPE_BLE_SPEAKER)
29
+ }
30
+ types
31
+ }
32
+
33
+ override fun getAudioDevices(): Array<TAudioDevice> {
34
+ val devices = audioManager.getDevices(android.media.AudioManager.GET_DEVICES_OUTPUTS)
35
+ var activeDevice: AudioDeviceInfo? = null
36
+
37
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
38
+ activeDevice = audioManager.communicationDevice
39
+ }
40
+
41
+ // Filter to only include valid communication devices
42
+ return devices.filter { device ->
43
+ validCommunicationDeviceTypes.contains(device.type)
44
+ }.map { device -> TAudioDevice(
45
+ id = device.id.toDouble(),
46
+ name = device.productName?.toString() ?: getDeviceTypeName(device.type),
47
+ type = device.type.toDouble(),
48
+ isActive = device == activeDevice
49
+ ) }.toTypedArray()
50
+ }
51
+
52
+ private fun getDeviceTypeName(type: Int): String {
53
+ return when (type) {
54
+ AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> "Built-in Earpiece"
55
+ AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> "Built-in Speaker"
56
+ AudioDeviceInfo.TYPE_WIRED_HEADSET -> "Wired Headset"
57
+ AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "Wired Headphones"
58
+ AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "Bluetooth SCO"
59
+ AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "Bluetooth"
60
+ AudioDeviceInfo.TYPE_USB_HEADSET -> "USB Headset"
61
+ 26 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Headset" else "Type 26"
62
+ 27 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Speaker" else "Type 27"
63
+ else -> "Type $type"
64
+ }
65
+ }
66
+
67
+ override fun setAudioDevice(deviceId: Double): Boolean {
68
+ val device =
69
+ audioManager.getDevices(android.media.AudioManager.GET_DEVICES_OUTPUTS)
70
+ .firstOrNull { it.id == deviceId.toInt() }
71
+ ?: return false
72
+
73
+ // Check if device type is valid for communication
74
+ if (!validCommunicationDeviceTypes.contains(device.type)) {
75
+ android.util.Log.w(TAG, "Device type ${device.type} is not a valid communication device")
76
+ return false
77
+ }
78
+
79
+ return try {
80
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
81
+ audioManager.setCommunicationDevice(device)
82
+ } else {
83
+ // Pre-Android 12 fallback (best-effort)
84
+ when (device.type) {
85
+ android.media.AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
86
+ android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> {
87
+ audioManager.startBluetoothSco()
88
+ audioManager.isBluetoothScoOn = true
89
+ true
90
+ }
91
+ android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> {
92
+ audioManager.isSpeakerphoneOn = true
93
+ true
94
+ }
95
+ android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET,
96
+ android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> {
97
+ audioManager.isSpeakerphoneOn = false
98
+ audioManager.isBluetoothScoOn = false
99
+ true
100
+ }
101
+ else -> {
102
+ android.util.Log.w(TAG, "Unsupported device type for pre-Android 12: ${device.type}")
103
+ false
104
+ }
105
+ }
106
+ }
107
+ } catch (e: Exception) {
108
+ android.util.Log.e(TAG, "Error setting audio device: ${e.message}", e)
109
+ false
110
+ }
111
+ }
112
+
113
+ companion object {
114
+ private const val TAG = "HybridAudioDevices"
115
+ }
116
+ }
@@ -0,0 +1,167 @@
1
+ package com.margelo.nitro.nitroplayer
2
+
3
+ import androidx.annotation.Keep
4
+ import com.facebook.jni.HybridData
5
+ import com.facebook.proguard.annotations.DoNotStrip
6
+ import com.margelo.nitro.NitroModules
7
+ import com.margelo.nitro.core.NullType
8
+ import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
9
+ import com.margelo.nitro.nitroplayer.playlist.PlaylistManager
10
+ import java.util.UUID
11
+ import com.margelo.nitro.nitroplayer.playlist.Playlist as InternalPlaylist
12
+
13
+ class HybridPlayerQueue : HybridPlayerQueueSpec() {
14
+ private val core: TrackPlayerCore
15
+ private val playlistManager: PlaylistManager
16
+
17
+ init {
18
+ val context = NitroModules.applicationContext ?: throw IllegalStateException("React Context is not initialized")
19
+ core = TrackPlayerCore.getInstance(context)
20
+ playlistManager = core.getPlaylistManager()
21
+ }
22
+
23
+ private var playlistsChangeListener: (() -> Unit)? = null
24
+ private val playlistChangeListeners = mutableMapOf<String, () -> Unit>()
25
+
26
+ @DoNotStrip
27
+ @Keep
28
+ override fun createPlaylist(
29
+ name: String,
30
+ description: String?,
31
+ artwork: String?,
32
+ ): String = playlistManager.createPlaylist(name, description, artwork)
33
+
34
+ @DoNotStrip
35
+ @Keep
36
+ override fun deletePlaylist(playlistId: String) {
37
+ playlistManager.deletePlaylist(playlistId)
38
+ }
39
+
40
+ @DoNotStrip
41
+ @Keep
42
+ override fun updatePlaylist(
43
+ playlistId: String,
44
+ name: String?,
45
+ description: String?,
46
+ artwork: String?,
47
+ ) {
48
+ playlistManager.updatePlaylist(playlistId, name, description, artwork)
49
+ }
50
+
51
+ @DoNotStrip
52
+ @Keep
53
+ override fun getPlaylist(playlistId: String): Variant_NullType_Playlist {
54
+ val playlist = playlistManager.getPlaylist(playlistId)
55
+ return if (playlist != null) {
56
+ Variant_NullType_Playlist.create(playlist.toPlaylist())
57
+ } else {
58
+ Variant_NullType_Playlist.create(NullType.NULL)
59
+ }
60
+ }
61
+
62
+ @DoNotStrip
63
+ @Keep
64
+ override fun getAllPlaylists(): Array<Playlist> =
65
+ playlistManager
66
+ .getAllPlaylists()
67
+ .map {
68
+ it.toPlaylist()
69
+ }.toTypedArray()
70
+
71
+ @DoNotStrip
72
+ @Keep
73
+ override fun addTrackToPlaylist(
74
+ playlistId: String,
75
+ track: TrackItem,
76
+ index: Double?,
77
+ ) {
78
+ val insertIndex = index?.toInt()
79
+ playlistManager.addTrackToPlaylist(playlistId, track, insertIndex)
80
+ }
81
+
82
+ @DoNotStrip
83
+ @Keep
84
+ override fun addTracksToPlaylist(
85
+ playlistId: String,
86
+ tracks: Array<TrackItem>,
87
+ index: Double?,
88
+ ) {
89
+ val insertIndex = index?.toInt()
90
+ playlistManager.addTracksToPlaylist(playlistId, tracks.toList(), insertIndex)
91
+ }
92
+
93
+ @DoNotStrip
94
+ @Keep
95
+ override fun removeTrackFromPlaylist(
96
+ playlistId: String,
97
+ trackId: String,
98
+ ) {
99
+ playlistManager.removeTrackFromPlaylist(playlistId, trackId)
100
+ }
101
+
102
+ @DoNotStrip
103
+ @Keep
104
+ override fun reorderTrackInPlaylist(
105
+ playlistId: String,
106
+ trackId: String,
107
+ newIndex: Double,
108
+ ) {
109
+ playlistManager.reorderTrackInPlaylist(playlistId, trackId, newIndex.toInt())
110
+ }
111
+
112
+ @DoNotStrip
113
+ @Keep
114
+ override fun loadPlaylist(playlistId: String) {
115
+ playlistManager.loadPlaylist(playlistId)
116
+ }
117
+
118
+ @DoNotStrip
119
+ @Keep
120
+ override fun getCurrentPlaylistId(): Variant_NullType_String {
121
+ val playlistId = playlistManager.getCurrentPlaylistId()
122
+ return if (playlistId != null) {
123
+ Variant_NullType_String.create(playlistId)
124
+ } else {
125
+ Variant_NullType_String.create(NullType.NULL)
126
+ }
127
+ }
128
+
129
+ @DoNotStrip
130
+ @Keep
131
+ override fun onPlaylistsChanged(callback: (playlists: Array<Playlist>, operation: QueueOperation?) -> Unit) {
132
+ // Remove previous listener if exists
133
+ playlistsChangeListener?.invoke()
134
+
135
+ // Add new listener
136
+ playlistsChangeListener =
137
+ playlistManager.addPlaylistsChangeListener { playlists, operation ->
138
+ callback(playlists.map { it.toPlaylist() }.toTypedArray(), operation)
139
+ }
140
+ }
141
+
142
+ @DoNotStrip
143
+ @Keep
144
+ override fun onPlaylistChanged(callback: (playlistId: String, playlist: Playlist, operation: QueueOperation?) -> Unit) {
145
+ // Listen to all playlists and filter by playlistId
146
+ val listenerId = UUID.randomUUID().toString()
147
+
148
+ // For each playlist, add a listener
149
+ playlistManager.getAllPlaylists().forEach { internalPlaylist ->
150
+ val removeListener =
151
+ playlistManager.addPlaylistChangeListener(internalPlaylist.id) { playlist, operation ->
152
+ callback(playlist.id, playlist.toPlaylist(), operation)
153
+ }
154
+ playlistChangeListeners[listenerId] = removeListener
155
+ }
156
+ }
157
+
158
+ // Helper to convert internal Playlist to generated Playlist type
159
+ private fun InternalPlaylist.toPlaylist(): Playlist =
160
+ Playlist(
161
+ id = this.id,
162
+ name = this.name,
163
+ description = this.description?.let { Variant_NullType_String.create(it) },
164
+ artwork = this.artwork?.let { Variant_NullType_String.create(it) },
165
+ tracks = this.tracks.toTypedArray(),
166
+ )
167
+ }
@@ -0,0 +1,93 @@
1
+ package com.margelo.nitro.nitroplayer
2
+
3
+ import androidx.annotation.Keep
4
+ import com.facebook.proguard.annotations.DoNotStrip
5
+ import com.margelo.nitro.NitroModules
6
+ import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
7
+
8
+ class HybridTrackPlayer : HybridTrackPlayerSpec() {
9
+ private val core: TrackPlayerCore
10
+
11
+ init {
12
+ val context =
13
+ NitroModules.applicationContext ?: throw IllegalStateException("React Context is not initialized")
14
+ core = TrackPlayerCore.getInstance(context)
15
+ }
16
+
17
+ @DoNotStrip
18
+ @Keep
19
+ override fun play() {
20
+ core.play()
21
+ }
22
+
23
+ @DoNotStrip
24
+ @Keep
25
+ override fun pause() {
26
+ core.pause()
27
+ }
28
+
29
+ @DoNotStrip
30
+ @Keep
31
+ override fun playSong(
32
+ songId: String,
33
+ fromPlaylist: String?,
34
+ ) {
35
+ core.playSong(songId, fromPlaylist)
36
+ }
37
+
38
+ @DoNotStrip
39
+ @Keep
40
+ override fun skipToNext() {
41
+ core.skipToNext()
42
+ }
43
+
44
+ @DoNotStrip
45
+ @Keep
46
+ override fun skipToPrevious() {
47
+ core.skipToPrevious()
48
+ }
49
+
50
+ @DoNotStrip
51
+ @Keep
52
+ override fun seek(position: Double) {
53
+ core.seek(position)
54
+ }
55
+
56
+ @DoNotStrip
57
+ @Keep
58
+ override fun getState(): PlayerState = core.getState()
59
+
60
+ override fun onChangeTrack(callback: (track: TrackItem, reason: Reason?) -> Unit) {
61
+ core.onChangeTrack = callback
62
+ }
63
+
64
+ override fun onPlaybackStateChange(callback: (state: TrackPlayerState, reason: Reason?) -> Unit) {
65
+ core.onPlaybackStateChange = callback
66
+ }
67
+
68
+ override fun onSeek(callback: (position: Double, totalDuration: Double) -> Unit) {
69
+ core.onSeek = callback
70
+ }
71
+
72
+ override fun onPlaybackProgressChange(callback: (position: Double, totalDuration: Double, isManuallySeeked: Boolean?) -> Unit) {
73
+ core.onPlaybackProgressChange = callback
74
+ }
75
+
76
+ @DoNotStrip
77
+ @Keep
78
+ override fun configure(config: PlayerConfig) {
79
+ core.configure(
80
+ androidAutoEnabled = config.androidAutoEnabled,
81
+ carPlayEnabled = config.carPlayEnabled,
82
+ showInNotification = config.showInNotification,
83
+ )
84
+ }
85
+
86
+ @Keep
87
+ override fun onAndroidAutoConnectionChange(callback: (Boolean) -> Unit) {
88
+ core.onAndroidAutoConnectionChange = callback
89
+ }
90
+
91
+ @Keep
92
+ override fun isAndroidAutoConnected(): Boolean = core.isAndroidAutoConnected()
93
+ }
@@ -0,0 +1,21 @@
1
+ package com.margelo.nitro.nitroplayer
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfoProvider
7
+
8
+ class NitroPlayerPackage : BaseReactPackage() {
9
+ override fun getModule(
10
+ name: String,
11
+ reactContext: ReactApplicationContext,
12
+ ): NativeModule? = null
13
+
14
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider { HashMap() }
15
+
16
+ companion object {
17
+ init {
18
+ NitroPlayerOnLoad.initializeNative()
19
+ }
20
+ }
21
+ }