@javascriptcommon/react-native-track-player 1.2.23 → 4.1.5

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 (507) hide show
  1. package/LICENSE +201 -21
  2. package/README.md +8 -0
  3. package/android/build.gradle +80 -63
  4. package/android/proguard-rules.txt +0 -3
  5. package/android/src/main/AndroidManifest.xml +10 -11
  6. package/android/src/main/java/com/doublesymmetry/trackplayer/HeadlessJsMediaService.kt +199 -0
  7. package/android/src/main/java/com/doublesymmetry/trackplayer/TrackPlayer.kt +33 -0
  8. package/android/src/main/java/com/{guichaguri → doublesymmetry}/trackplayer/extensions/AudioPlayerStateExt.kt +3 -3
  9. package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/EnumExtensions.kt +5 -0
  10. package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/NumberExt.kt +13 -0
  11. package/android/src/main/java/com/{guichaguri → doublesymmetry}/trackplayer/model/MetadataAdapter.kt +20 -17
  12. package/android/src/main/java/com/doublesymmetry/trackplayer/model/NowPlayingMetadata.kt +16 -0
  13. package/android/src/main/java/com/{guichaguri/trackplayer/kotlinaudio/models → doublesymmetry/trackplayer/model}/PlaybackMetadata.kt +31 -28
  14. package/android/src/main/java/com/{guichaguri → doublesymmetry}/trackplayer/model/State.kt +1 -1
  15. package/android/src/main/java/com/doublesymmetry/trackplayer/model/Track.kt +67 -0
  16. package/android/src/main/java/com/doublesymmetry/trackplayer/model/TrackAudioItem.kt +18 -0
  17. package/android/src/main/java/com/doublesymmetry/trackplayer/model/TrackMetadata.kt +38 -0
  18. package/android/src/main/java/com/{guichaguri → doublesymmetry}/trackplayer/module/MusicEvents.kt +10 -9
  19. package/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt +778 -0
  20. package/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt +1286 -0
  21. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/AppForegroundTracker.kt +35 -0
  22. package/android/src/main/java/com/{guichaguri/trackplayer/service → doublesymmetry/trackplayer/utils}/BundleUtils.kt +50 -20
  23. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/CoilBitmapLoader.kt +65 -0
  24. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/MediaItemBuilder.kt +41 -0
  25. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/RejectionException.kt +11 -0
  26. package/android/src/main/java/com/doublesymmetry/trackplayer/video/TrackPlayerVideoView.kt +42 -0
  27. package/android/src/main/java/com/doublesymmetry/trackplayer/video/TrackPlayerVideoViewManager.kt +18 -0
  28. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/event/EventHolder.kt +7 -7
  29. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/event/PlayerEventHolder.kt +22 -9
  30. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioContentType.kt +1 -1
  31. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItem.kt +118 -0
  32. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioItemTransitionReason.kt +3 -3
  33. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioPlayerState.kt +2 -2
  34. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/BufferConfig.kt +1 -1
  35. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/CacheConfig.kt +1 -1
  36. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/Capability.kt +1 -1
  37. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CustomButton.kt +19 -0
  38. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/FocusChangeData.kt +1 -1
  39. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/MediaSessionCallback.kt +1 -1
  40. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlayWhenReadyChangeData.kt +1 -3
  41. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlaybackEndedReason.kt +1 -1
  42. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlaybackError.kt +1 -1
  43. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlayerConfig.kt +8 -5
  44. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerOptions.kt +40 -0
  45. package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PositionChangedReason.kt +1 -1
  46. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/RepeatMode.kt +16 -0
  47. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/WakeMode.kt +7 -0
  48. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/AudioPlayer.kt +756 -0
  49. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/ForwardingPlayer.java +1124 -0
  50. package/android/src/main/java/com/{guichaguri/trackplayer/kotlinaudio/players → lovegaoshi/kotlinaudio/player}/QueuedAudioPlayer.kt +68 -58
  51. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/APMRenderersFactory.kt +33 -0
  52. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Buffer.kt +34 -0
  53. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Cache.kt +27 -0
  54. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/FocusManager.kt +59 -0
  55. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/MediaFactory.kt +130 -0
  56. package/android/src/main/java/com/lovegaoshi/kotlinaudio/processors/TeeListener.kt +171 -0
  57. package/android/src/main/java/com/lovegaoshi/kotlinaudio/service/MusicService.kt +127 -0
  58. package/android/src/main/java/com/lovegaoshi/kotlinaudio/utils/FFT.java +99 -0
  59. package/android/src/main/java/com/lovegaoshi/kotlinaudio/utils/Utils.kt +113 -0
  60. package/android/src/main/res/drawable/baseline_repeat_24.xml +5 -0
  61. package/android/src/main/res/drawable/baseline_repeat_one_24.xml +5 -0
  62. package/android/src/main/res/drawable/forward.xml +5 -0
  63. package/android/src/main/res/drawable/heart_24px.xml +5 -0
  64. package/android/src/main/res/drawable/hearte_24px.xml +5 -0
  65. package/android/src/main/res/drawable/ifl_24px.xml +5 -0
  66. package/android/src/main/res/drawable/rewind.xml +5 -0
  67. package/android/src/main/res/drawable/shuffle_24px.xml +5 -0
  68. package/android/src/main/res/values/strings.xml +3 -4
  69. package/android/src/main/res/xml/automotive_app_desc.xml +3 -0
  70. package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/22AMillion.jpg +0 -0
  71. package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/Contents.json +21 -0
  72. package/ios/Example/SwiftAudio/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  73. package/ios/Example/SwiftAudio/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
  74. package/ios/Example/SwiftAudio/Assets.xcassets/Contents.json +6 -0
  75. package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/Contents.json +21 -0
  76. package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/cover.jpg +0 -0
  77. package/ios/Example/SwiftAudio/AudioController.swift +46 -0
  78. package/ios/Example/SwiftAudio/Extensions.swift +22 -0
  79. package/ios/Example/SwiftAudio/PlayerView.swift +172 -0
  80. package/ios/Example/SwiftAudio/PlayerViewModel.swift +120 -0
  81. package/ios/Example/SwiftAudio/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
  82. package/ios/Example/SwiftAudio/QueueView.swift +65 -0
  83. package/ios/{TrackPlayer.xcodeproj/xcuserdata/marco.xcuserdatad/xcschemes/xcschememanagement.plist → Example/SwiftAudio/SwiftAudio.entitlements} +6 -8
  84. package/ios/Example/SwiftAudio/SwiftAudioApp.swift +17 -0
  85. package/ios/Example/SwiftAudio.xcodeproj/project.pbxproj +412 -0
  86. package/ios/{TrackPlayer.xcodeproj → Example/SwiftAudio.xcodeproj}/project.xcworkspace/contents.xcworkspacedata +1 -1
  87. package/ios/RNTrackPlayer/Models/Capabilities.swift +39 -4
  88. package/ios/RNTrackPlayer/Models/MediaURL.swift +12 -6
  89. package/ios/RNTrackPlayer/Models/MetadataAdapter.swift +147 -0
  90. package/ios/RNTrackPlayer/Models/PitchAlgorithms.swift +13 -0
  91. package/ios/RNTrackPlayer/Models/SessionCategories.swift +106 -0
  92. package/ios/RNTrackPlayer/Models/State.swift +26 -0
  93. package/ios/RNTrackPlayer/Models/Track.swift +74 -54
  94. package/ios/RNTrackPlayer/RNTrackPlayer.swift +867 -406
  95. package/ios/RNTrackPlayer/Support/RNTrackPlayer-Bridging-Header.h +1 -0
  96. package/ios/RNTrackPlayer/TrackPlayer.h +14 -0
  97. package/ios/RNTrackPlayer/TrackPlayer.mm +249 -0
  98. package/ios/RNTrackPlayer/Utils/EventType.swift +45 -0
  99. package/ios/RNTrackPlayer/Utils/Metadata.swift +60 -0
  100. package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoView.swift +83 -0
  101. package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoViewManager.m +5 -0
  102. package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoViewManager.swift +17 -0
  103. package/ios/SwiftAudioEx/Package.swift +20 -0
  104. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapper.swift +531 -0
  105. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperDelegate.swift +27 -0
  106. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperProtocol.swift +69 -0
  107. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperState.swift +43 -0
  108. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioItem.swift +158 -0
  109. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayer.swift +459 -0
  110. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayerError.swift +26 -0
  111. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSession.swift +33 -0
  112. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSessionController.swift +135 -0
  113. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioTap.swift +96 -0
  114. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Event.swift +155 -0
  115. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/MediaItemProperty.swift +95 -0
  116. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoCenter.swift +17 -0
  117. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoController.swift +73 -0
  118. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoControllerProtocol.swift +26 -0
  119. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoKeyValue.swift +14 -0
  120. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoProperty.swift +234 -0
  121. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemNotificationObserver.swift +102 -0
  122. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemObserver.swift +136 -0
  123. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerObserver.swift +120 -0
  124. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerTimeObserver.swift +112 -0
  125. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueueManager.swift +356 -0
  126. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueuedAudioPlayer.swift +236 -0
  127. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommand.swift +170 -0
  128. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommandController.swift +206 -0
  129. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RepeatMode.swift +15 -0
  130. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/TimeEventFrequency.swift +26 -0
  131. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Utils/DispatchQueueType.swift +18 -0
  132. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/WaveformAudioTap.swift +159 -0
  133. package/lib/specs/NativeTrackPlayer.d.ts +134 -0
  134. package/lib/specs/NativeTrackPlayer.js +4 -0
  135. package/lib/src/TrackPlayerModule.web.d.ts +2 -0
  136. package/lib/src/TrackPlayerModule.web.js +2 -0
  137. package/lib/src/VideoView.d.ts +16 -0
  138. package/lib/src/VideoView.js +25 -0
  139. package/lib/src/constants/AndroidAudioContentType.d.ts +35 -0
  140. package/lib/src/constants/AndroidAudioContentType.js +36 -0
  141. package/lib/src/constants/AndroidAutoContentStyle.d.ts +10 -0
  142. package/lib/src/constants/AndroidAutoContentStyle.js +11 -0
  143. package/lib/src/constants/AppKilledPlaybackBehavior.d.ts +17 -0
  144. package/lib/src/constants/AppKilledPlaybackBehavior.js +18 -0
  145. package/lib/src/constants/Capability.d.ts +17 -0
  146. package/lib/src/constants/Capability.js +19 -0
  147. package/lib/src/constants/Event.d.ts +172 -0
  148. package/lib/src/constants/Event.js +173 -0
  149. package/lib/src/constants/IOSCategory.d.ts +36 -0
  150. package/lib/src/constants/IOSCategory.js +37 -0
  151. package/lib/src/constants/IOSCategoryMode.d.ts +47 -0
  152. package/lib/src/constants/IOSCategoryMode.js +48 -0
  153. package/lib/src/constants/IOSCategoryOptions.d.ts +44 -0
  154. package/lib/src/constants/IOSCategoryOptions.js +45 -0
  155. package/lib/src/constants/MediaItemPlayable.d.ts +4 -0
  156. package/lib/src/constants/MediaItemPlayable.js +5 -0
  157. package/lib/src/constants/PitchAlgorithm.d.ts +14 -0
  158. package/lib/src/constants/PitchAlgorithm.js +16 -0
  159. package/lib/src/constants/RatingType.d.ts +8 -0
  160. package/lib/src/constants/RatingType.js +10 -0
  161. package/lib/src/constants/RepeatMode.d.ts +8 -0
  162. package/lib/src/constants/RepeatMode.js +10 -0
  163. package/lib/src/constants/State.d.ts +34 -0
  164. package/lib/src/constants/State.js +35 -0
  165. package/lib/src/constants/TrackType.d.ts +6 -0
  166. package/lib/src/constants/TrackType.js +7 -0
  167. package/lib/src/constants/index.d.ts +14 -0
  168. package/lib/src/constants/index.js +14 -0
  169. package/lib/src/hooks/index.d.ts +6 -0
  170. package/lib/src/hooks/index.js +6 -0
  171. package/lib/src/hooks/useActiveTrack.d.ts +2 -0
  172. package/lib/src/hooks/useActiveTrack.js +28 -0
  173. package/lib/src/hooks/useAppIsInBackground.d.ts +1 -0
  174. package/lib/src/hooks/useAppIsInBackground.js +16 -0
  175. package/lib/src/hooks/useIsPlaying.d.ts +35 -0
  176. package/lib/src/hooks/useIsPlaying.js +50 -0
  177. package/lib/src/hooks/usePlayWhenReady.d.ts +1 -0
  178. package/lib/src/hooks/usePlayWhenReady.js +27 -0
  179. package/lib/src/hooks/usePlaybackState.d.ts +10 -0
  180. package/lib/src/hooks/usePlaybackState.js +35 -0
  181. package/lib/src/hooks/useProgress.d.ts +7 -0
  182. package/lib/src/hooks/useProgress.js +55 -0
  183. package/lib/src/hooks/useTrackPlayerEvents.d.ts +8 -0
  184. package/lib/src/hooks/useTrackPlayerEvents.js +30 -0
  185. package/lib/src/index.d.ts +6 -0
  186. package/lib/src/index.js +6 -0
  187. package/lib/src/interfaces/AndroidAutoBrowseTree.d.ts +5 -0
  188. package/lib/src/interfaces/AndroidAutoBrowseTree.js +1 -0
  189. package/lib/src/interfaces/AndroidOptions.d.ts +41 -0
  190. package/lib/src/interfaces/AndroidOptions.js +1 -0
  191. package/lib/src/interfaces/CustomButtons.d.ts +5 -0
  192. package/lib/src/interfaces/CustomButtons.js +1 -0
  193. package/lib/src/interfaces/FeedbackOptions.d.ts +6 -0
  194. package/lib/src/interfaces/FeedbackOptions.js +1 -0
  195. package/lib/src/interfaces/MediaItem.d.ts +18 -0
  196. package/lib/src/interfaces/MediaItem.js +1 -0
  197. package/lib/src/interfaces/MetadataOptions.d.ts +3 -0
  198. package/lib/src/interfaces/MetadataOptions.js +1 -0
  199. package/lib/src/interfaces/NowPlayingMetadata.d.ts +4 -0
  200. package/lib/src/interfaces/NowPlayingMetadata.js +1 -0
  201. package/lib/src/interfaces/PlaybackState.d.ts +8 -0
  202. package/lib/src/interfaces/PlaybackState.js +1 -0
  203. package/lib/src/interfaces/PlayerOptions.d.ts +132 -0
  204. package/lib/src/interfaces/PlayerOptions.js +1 -0
  205. package/lib/src/interfaces/Progress.d.ts +15 -0
  206. package/lib/src/interfaces/Progress.js +1 -0
  207. package/lib/src/interfaces/ResourceObject.d.ts +1 -0
  208. package/lib/src/interfaces/ResourceObject.js +1 -0
  209. package/lib/src/interfaces/ServiceHandler.d.ts +1 -0
  210. package/lib/src/interfaces/ServiceHandler.js +1 -0
  211. package/lib/src/interfaces/Track.d.ts +21 -0
  212. package/lib/src/interfaces/Track.js +1 -0
  213. package/lib/src/interfaces/TrackMetadataBase.d.ts +28 -0
  214. package/lib/src/interfaces/TrackMetadataBase.js +1 -0
  215. package/lib/src/interfaces/UpdateOptions.d.ts +52 -0
  216. package/lib/src/interfaces/UpdateOptions.js +1 -0
  217. package/lib/src/interfaces/events/AudioMetadataReceivedEvent.d.ts +33 -0
  218. package/lib/src/interfaces/events/AudioMetadataReceivedEvent.js +1 -0
  219. package/lib/src/interfaces/events/ControllerConnectedEvent.d.ts +8 -0
  220. package/lib/src/interfaces/events/ControllerConnectedEvent.js +1 -0
  221. package/lib/src/interfaces/events/EventPayloadByEvent.d.ts +77 -0
  222. package/lib/src/interfaces/events/EventPayloadByEvent.js +1 -0
  223. package/lib/src/interfaces/events/FFTUpdateEvent.d.ts +7 -0
  224. package/lib/src/interfaces/events/FFTUpdateEvent.js +1 -0
  225. package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.d.ts +24 -0
  226. package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.js +1 -0
  227. package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.d.ts +4 -0
  228. package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.js +1 -0
  229. package/lib/src/interfaces/events/PlaybackErrorEvent.d.ts +6 -0
  230. package/lib/src/interfaces/events/PlaybackErrorEvent.js +1 -0
  231. package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.d.ts +16 -0
  232. package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.js +1 -0
  233. package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.d.ts +4 -0
  234. package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.js +1 -0
  235. package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.d.ts +4 -0
  236. package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.js +1 -0
  237. package/lib/src/interfaces/events/PlaybackQueueEndedEvent.d.ts +9 -0
  238. package/lib/src/interfaces/events/PlaybackQueueEndedEvent.js +1 -0
  239. package/lib/src/interfaces/events/PlaybackResumeEvent.d.ts +3 -0
  240. package/lib/src/interfaces/events/PlaybackResumeEvent.js +1 -0
  241. package/lib/src/interfaces/events/PlaybackTrackChangedEvent.d.ts +11 -0
  242. package/lib/src/interfaces/events/PlaybackTrackChangedEvent.js +1 -0
  243. package/lib/src/interfaces/events/PlayerErrorEvent.d.ts +6 -0
  244. package/lib/src/interfaces/events/PlayerErrorEvent.js +1 -0
  245. package/lib/src/interfaces/events/RemoteBrowseEvent.d.ts +4 -0
  246. package/lib/src/interfaces/events/RemoteBrowseEvent.js +1 -0
  247. package/lib/src/interfaces/events/RemoteCustomActionEvent.d.ts +7 -0
  248. package/lib/src/interfaces/events/RemoteCustomActionEvent.js +1 -0
  249. package/lib/src/interfaces/events/RemoteDuckEvent.d.ts +13 -0
  250. package/lib/src/interfaces/events/RemoteDuckEvent.js +1 -0
  251. package/lib/src/interfaces/events/RemoteJumpBackwardEvent.d.ts +7 -0
  252. package/lib/src/interfaces/events/RemoteJumpBackwardEvent.js +1 -0
  253. package/lib/src/interfaces/events/RemoteJumpForwardEvent.d.ts +7 -0
  254. package/lib/src/interfaces/events/RemoteJumpForwardEvent.js +1 -0
  255. package/lib/src/interfaces/events/RemotePlayIdEvent.d.ts +4 -0
  256. package/lib/src/interfaces/events/RemotePlayIdEvent.js +1 -0
  257. package/lib/src/interfaces/events/RemotePlaySearchEvent.d.ts +9 -0
  258. package/lib/src/interfaces/events/RemotePlaySearchEvent.js +1 -0
  259. package/lib/src/interfaces/events/RemoteSearchEvent.d.ts +3 -0
  260. package/lib/src/interfaces/events/RemoteSearchEvent.js +1 -0
  261. package/lib/src/interfaces/events/RemoteSeekEvent.d.ts +4 -0
  262. package/lib/src/interfaces/events/RemoteSeekEvent.js +1 -0
  263. package/lib/src/interfaces/events/RemoteSetRatingEvent.d.ts +4 -0
  264. package/lib/src/interfaces/events/RemoteSetRatingEvent.js +1 -0
  265. package/lib/src/interfaces/events/RemoteSkipEvent.d.ts +3 -0
  266. package/lib/src/interfaces/events/RemoteSkipEvent.js +1 -0
  267. package/lib/src/interfaces/events/index.d.ts +20 -0
  268. package/lib/src/interfaces/events/index.js +20 -0
  269. package/lib/src/interfaces/index.d.ts +15 -0
  270. package/lib/src/interfaces/index.js +15 -0
  271. package/lib/src/resolveAssetSource.d.ts +2 -0
  272. package/lib/src/resolveAssetSource.js +3 -0
  273. package/lib/src/resolveAssetSource.web.d.ts +2 -0
  274. package/lib/src/resolveAssetSource.web.js +8 -0
  275. package/lib/src/trackPlayer.d.ts +371 -0
  276. package/lib/src/trackPlayer.js +627 -0
  277. package/lib/web/TrackPlayer/Player.d.ts +40 -0
  278. package/lib/web/TrackPlayer/Player.js +188 -0
  279. package/lib/web/TrackPlayer/PlaylistPlayer.d.ts +31 -0
  280. package/lib/web/TrackPlayer/PlaylistPlayer.js +181 -0
  281. package/lib/web/TrackPlayer/RepeatMode.d.ts +5 -0
  282. package/lib/web/TrackPlayer/RepeatMode.js +6 -0
  283. package/lib/web/TrackPlayer/SetupNotCalledError.d.ts +3 -0
  284. package/lib/web/TrackPlayer/SetupNotCalledError.js +5 -0
  285. package/lib/web/TrackPlayer/index.d.ts +3 -0
  286. package/lib/web/TrackPlayer/index.js +3 -0
  287. package/lib/web/TrackPlayerModule.d.ts +63 -0
  288. package/lib/web/TrackPlayerModule.js +153 -0
  289. package/lib/web/index.d.ts +3 -0
  290. package/lib/web/index.js +3 -0
  291. package/package.json +85 -6
  292. package/react-native-track-player.podspec +13 -13
  293. package/specs/NativeTrackPlayer.ts +153 -0
  294. package/src/TrackPlayerModule.web.ts +2 -0
  295. package/src/VideoView.tsx +51 -0
  296. package/src/constants/AndroidAudioContentType.ts +35 -0
  297. package/src/constants/AndroidAutoContentStyle.ts +10 -0
  298. package/src/constants/AppKilledPlaybackBehavior.ts +19 -0
  299. package/src/constants/Capability.ts +19 -0
  300. package/src/constants/Event.ts +173 -0
  301. package/src/constants/IOSCategory.ts +36 -0
  302. package/src/constants/IOSCategoryMode.ts +47 -0
  303. package/src/constants/IOSCategoryOptions.ts +44 -0
  304. package/src/constants/MediaItemPlayable.ts +4 -0
  305. package/src/constants/PitchAlgorithm.ts +16 -0
  306. package/src/constants/RatingType.ts +10 -0
  307. package/src/constants/RepeatMode.ts +10 -0
  308. package/src/constants/State.ts +34 -0
  309. package/src/constants/TrackType.ts +6 -0
  310. package/src/constants/index.ts +14 -0
  311. package/src/hooks/index.ts +6 -0
  312. package/src/hooks/useActiveTrack.ts +36 -0
  313. package/src/hooks/useAppIsInBackground.ts +20 -0
  314. package/src/hooks/useIsPlaying.ts +56 -0
  315. package/src/hooks/usePlayWhenReady.ts +37 -0
  316. package/src/hooks/usePlaybackState.ts +45 -0
  317. package/src/hooks/useProgress.ts +64 -0
  318. package/src/hooks/useTrackPlayerEvents.ts +48 -0
  319. package/src/index.ts +8 -0
  320. package/src/interfaces/AndroidAutoBrowseTree.ts +6 -0
  321. package/src/interfaces/AndroidOptions.ts +48 -0
  322. package/src/interfaces/CustomButtons.ts +6 -0
  323. package/src/interfaces/FeedbackOptions.ts +7 -0
  324. package/src/interfaces/MediaItem.ts +19 -0
  325. package/src/interfaces/MetadataOptions.ts +4 -0
  326. package/src/interfaces/NowPlayingMetadata.ts +5 -0
  327. package/src/interfaces/PlaybackState.ts +11 -0
  328. package/src/interfaces/PlayerOptions.ts +138 -0
  329. package/src/interfaces/Progress.ts +15 -0
  330. package/src/interfaces/ResourceObject.ts +1 -0
  331. package/src/interfaces/ServiceHandler.ts +1 -0
  332. package/src/interfaces/Track.ts +23 -0
  333. package/src/interfaces/TrackMetadataBase.ts +29 -0
  334. package/src/interfaces/UpdateOptions.ts +59 -0
  335. package/src/interfaces/events/AudioMetadataReceivedEvent.ts +37 -0
  336. package/src/interfaces/events/ControllerConnectedEvent.ts +9 -0
  337. package/src/interfaces/events/EventPayloadByEvent.ts +80 -0
  338. package/src/interfaces/events/FFTUpdateEvent.ts +9 -0
  339. package/src/interfaces/events/PlaybackActiveTrackChangedEvent.ts +29 -0
  340. package/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.ts +4 -0
  341. package/src/interfaces/events/PlaybackErrorEvent.ts +6 -0
  342. package/src/interfaces/events/PlaybackMetadataReceivedEvent.ts +16 -0
  343. package/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.ts +4 -0
  344. package/src/interfaces/events/PlaybackProgressUpdatedEvent.ts +5 -0
  345. package/src/interfaces/events/PlaybackQueueEndedEvent.ts +9 -0
  346. package/src/interfaces/events/PlaybackResumeEvent.ts +5 -0
  347. package/src/interfaces/events/PlaybackTrackChangedEvent.ts +11 -0
  348. package/src/interfaces/events/PlayerErrorEvent.ts +6 -0
  349. package/src/interfaces/events/RemoteBrowseEvent.ts +4 -0
  350. package/src/interfaces/events/RemoteCustomActionEvent.ts +7 -0
  351. package/src/interfaces/events/RemoteDuckEvent.ts +13 -0
  352. package/src/interfaces/events/RemoteJumpBackwardEvent.ts +7 -0
  353. package/src/interfaces/events/RemoteJumpForwardEvent.ts +7 -0
  354. package/src/interfaces/events/RemotePlayIdEvent.ts +4 -0
  355. package/src/interfaces/events/RemotePlaySearchEvent.ts +21 -0
  356. package/src/interfaces/events/RemoteSearchEvent.ts +3 -0
  357. package/src/interfaces/events/RemoteSeekEvent.ts +4 -0
  358. package/src/interfaces/events/RemoteSetRatingEvent.ts +5 -0
  359. package/src/interfaces/events/RemoteSkipEvent.ts +3 -0
  360. package/src/interfaces/events/index.ts +20 -0
  361. package/src/interfaces/index.ts +15 -0
  362. package/src/resolveAssetSource.ts +3 -0
  363. package/src/resolveAssetSource.web.ts +10 -0
  364. package/src/trackPlayer.ts +806 -0
  365. package/web/TrackPlayer/Player.ts +201 -0
  366. package/web/TrackPlayer/PlaylistPlayer.ts +215 -0
  367. package/web/TrackPlayer/RepeatMode.ts +6 -0
  368. package/web/TrackPlayer/SetupNotCalledError.ts +5 -0
  369. package/web/TrackPlayer/index.ts +3 -0
  370. package/web/TrackPlayerModule.ts +181 -0
  371. package/web/index.ts +4 -0
  372. package/CHANGELOG.md +0 -75
  373. package/android/react-native-music-control.iml +0 -139
  374. package/android/react-native-track-player.iml +0 -151
  375. package/android/src/main/ic_home-playstore.png +0 -0
  376. package/android/src/main/ic_repeat-playstore.png +0 -0
  377. package/android/src/main/ic_repeat_50-playstore.png +0 -0
  378. package/android/src/main/ic_shuffle-playstore.png +0 -0
  379. package/android/src/main/ic_shuffle_50-playstore.png +0 -0
  380. package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
  381. package/android/src/main/ic_stop-playstore.png +0 -0
  382. package/android/src/main/ic_test-playstore.png +0 -0
  383. package/android/src/main/java/com/guichaguri/trackplayer/HeadlessJsMediaService.java +0 -225
  384. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +0 -25
  385. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +0 -20
  386. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +0 -10
  387. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +0 -66
  388. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +0 -43
  389. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +0 -8
  390. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +0 -8
  391. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +0 -9
  392. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +0 -49
  393. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +0 -678
  394. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +0 -10
  395. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +0 -864
  396. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +0 -35
  397. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +0 -26
  398. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +0 -12
  399. package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +0 -120
  400. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +0 -19
  401. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +0 -11
  402. package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +0 -151
  403. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +0 -1177
  404. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +0 -31
  405. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +0 -347
  406. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +0 -1254
  407. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +0 -228
  408. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +0 -141
  409. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +0 -396
  410. package/android/src/main/res/drawable-hdpi/ic_forward.png +0 -0
  411. package/android/src/main/res/drawable-hdpi/ic_home.png +0 -0
  412. package/android/src/main/res/drawable-hdpi/ic_next.png +0 -0
  413. package/android/src/main/res/drawable-hdpi/ic_pause.png +0 -0
  414. package/android/src/main/res/drawable-hdpi/ic_play.png +0 -0
  415. package/android/src/main/res/drawable-hdpi/ic_previous.png +0 -0
  416. package/android/src/main/res/drawable-hdpi/ic_rewind.png +0 -0
  417. package/android/src/main/res/drawable-hdpi/ic_stop.png +0 -0
  418. package/android/src/main/res/drawable-mdpi/ic_forward.png +0 -0
  419. package/android/src/main/res/drawable-mdpi/ic_home.png +0 -0
  420. package/android/src/main/res/drawable-mdpi/ic_next.png +0 -0
  421. package/android/src/main/res/drawable-mdpi/ic_pause.png +0 -0
  422. package/android/src/main/res/drawable-mdpi/ic_play.png +0 -0
  423. package/android/src/main/res/drawable-mdpi/ic_previous.png +0 -0
  424. package/android/src/main/res/drawable-mdpi/ic_rewind.png +0 -0
  425. package/android/src/main/res/drawable-mdpi/ic_stop.png +0 -0
  426. package/android/src/main/res/drawable-xhdpi/ic_forward.png +0 -0
  427. package/android/src/main/res/drawable-xhdpi/ic_home.png +0 -0
  428. package/android/src/main/res/drawable-xhdpi/ic_next.png +0 -0
  429. package/android/src/main/res/drawable-xhdpi/ic_pause.png +0 -0
  430. package/android/src/main/res/drawable-xhdpi/ic_play.png +0 -0
  431. package/android/src/main/res/drawable-xhdpi/ic_previous.png +0 -0
  432. package/android/src/main/res/drawable-xhdpi/ic_rewind.png +0 -0
  433. package/android/src/main/res/drawable-xhdpi/ic_stop.png +0 -0
  434. package/android/src/main/res/drawable-xxhdpi/ic_forward.png +0 -0
  435. package/android/src/main/res/drawable-xxhdpi/ic_home.png +0 -0
  436. package/android/src/main/res/drawable-xxhdpi/ic_next.png +0 -0
  437. package/android/src/main/res/drawable-xxhdpi/ic_pause.png +0 -0
  438. package/android/src/main/res/drawable-xxhdpi/ic_play.png +0 -0
  439. package/android/src/main/res/drawable-xxhdpi/ic_previous.png +0 -0
  440. package/android/src/main/res/drawable-xxhdpi/ic_rewind.png +0 -0
  441. package/android/src/main/res/drawable-xxhdpi/ic_stop.png +0 -0
  442. package/android/src/main/res/drawable-xxxhdpi/ic_forward.png +0 -0
  443. package/android/src/main/res/drawable-xxxhdpi/ic_home.png +0 -0
  444. package/android/src/main/res/drawable-xxxhdpi/ic_next.png +0 -0
  445. package/android/src/main/res/drawable-xxxhdpi/ic_pause.png +0 -0
  446. package/android/src/main/res/drawable-xxxhdpi/ic_play.png +0 -0
  447. package/android/src/main/res/drawable-xxxhdpi/ic_previous.png +0 -0
  448. package/android/src/main/res/drawable-xxxhdpi/ic_rewind.png +0 -0
  449. package/android/src/main/res/drawable-xxxhdpi/ic_stop.png +0 -0
  450. package/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
  451. package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
  452. package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
  453. package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
  454. package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
  455. package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
  456. package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
  457. package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
  458. package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
  459. package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
  460. package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
  461. package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
  462. package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
  463. package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
  464. package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
  465. package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
  466. package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
  467. package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
  468. package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
  469. package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
  470. package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
  471. package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
  472. package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
  473. package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
  474. package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
  475. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
  476. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
  477. package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  478. package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
  479. package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
  480. package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
  481. package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
  482. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
  483. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
  484. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
  485. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
  486. package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  487. package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
  488. package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
  489. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
  490. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
  491. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
  492. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
  493. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
  494. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
  495. package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
  496. package/android/src/main/res/strings.xml +0 -6
  497. package/index.d.ts +0 -235
  498. package/index.js +0 -4
  499. package/ios/RNTrackPlayer/RNTrackPlayerBridge.h +0 -12
  500. package/ios/RNTrackPlayer/RNTrackPlayerBridge.m +0 -29
  501. package/ios/TrackPlayer.xcodeproj/project.pbxproj +0 -495
  502. package/ios/TrackPlayer.xcodeproj/project.xcworkspace/xcuserdata/marco.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  503. package/lib/ProgressComponent.js +0 -70
  504. package/lib/eventTypes.js +0 -28
  505. package/lib/hooks.js +0 -160
  506. package/lib/index.js +0 -178
  507. /package/ios/{TrackPlayer.xcodeproj → Example/SwiftAudio.xcodeproj}/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
@@ -1,1177 +0,0 @@
1
- package com.guichaguri.trackplayer.module
2
-
3
- import android.annotation.SuppressLint
4
- import android.app.AlarmManager
5
- import android.app.PendingIntent
6
- import android.content.*
7
- import android.graphics.Bitmap
8
- import android.graphics.BitmapFactory
9
- import android.graphics.BitmapShader
10
- import android.graphics.Canvas
11
- import android.graphics.Color
12
- import android.graphics.Paint
13
- import android.graphics.Shader
14
- import android.graphics.drawable.Drawable
15
- import android.net.Uri
16
- import android.os.*
17
- import android.support.v4.media.MediaBrowserCompat
18
- import android.support.v4.media.MediaBrowserCompat.MediaItem
19
- import android.support.v4.media.MediaDescriptionCompat
20
- import android.support.v4.media.RatingCompat
21
- import android.support.v4.media.session.PlaybackStateCompat
22
- import androidx.localbroadcastmanager.content.LocalBroadcastManager
23
- import androidx.media.utils.MediaConstants
24
- import com.bumptech.glide.Glide
25
- import com.bumptech.glide.request.target.CustomTarget
26
- import com.bumptech.glide.request.transition.Transition
27
- import com.facebook.react.ReactApplication
28
- import com.facebook.react.ReactHost
29
- import com.facebook.react.ReactNativeHost
30
- import com.facebook.react.bridge.*
31
- import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.bridgelessEnabled
32
- import com.facebook.react.modules.core.DeviceEventManagerModule
33
- import com.google.android.exoplayer2.DefaultLoadControl.*
34
- import com.guichaguri.trackplayer.kotlinaudio.models.AudioPlayerState
35
- import com.guichaguri.trackplayer.service.MusicBinder
36
- import com.guichaguri.trackplayer.service.MusicService
37
- import com.guichaguri.trackplayer.service.Utils
38
- import com.guichaguri.trackplayer.service.Utils.EVENT_INTENT
39
- import com.guichaguri.trackplayer.model.Track
40
- import kotlinx.coroutines.MainScope
41
- import kotlinx.coroutines.delay
42
- import kotlinx.coroutines.launch
43
- import timber.log.Timber
44
- import java.util.*
45
- import java.util.concurrent.Callable
46
- import java.util.concurrent.ExecutorService
47
- import java.util.concurrent.Executors
48
- import java.util.concurrent.Future
49
- import javax.annotation.Nonnull
50
- import kotlin.collections.HashMap
51
-
52
- /**
53
- * @author Guichaguri
54
- */
55
- class MusicModule(reactContext: ReactApplicationContext?) :
56
- ReactContextBaseJavaModule(reactContext), ServiceConnection, LifecycleEventListener {
57
- private var playerOptions: Bundle? = null
58
- private var isServiceBound = false
59
-
60
- // private var binder: MusicBinder? = null
61
- private var eventHandler: MusicEvents? = null
62
- private val initCallbacks = ArrayDeque<Runnable>()
63
- private var connecting = false
64
- private var options: Bundle? = null
65
- private var musicService: MusicService? = null
66
- private val scope = MainScope()
67
- private val executor: ExecutorService = Executors.newSingleThreadExecutor()
68
-
69
- private val reactNativeHost: ReactNativeHost?
70
- get() = (reactApplicationContext.applicationContext as? ReactApplication)?.reactNativeHost
71
-
72
- private val reactHost: ReactHost?
73
- get() = (reactApplicationContext.applicationContext as? ReactApplication)?.reactHost
74
-
75
- companion object {
76
- var autoConnectionDetector: AutoConnectionDetector? = null
77
- var binder: MusicBinder? = null
78
- var isAppOpen: Boolean = false
79
- var isAndroidTv: Boolean = false
80
- var firstPlayDone = false
81
- }
82
-
83
- @Nonnull
84
- override fun getName(): String {
85
- return "TrackPlayerModule"
86
- }
87
-
88
- private fun onCarConnected() {}
89
-
90
- private fun onCarDisconnected() {
91
- firstPlayDone = false
92
- resetAndroidAutoService()
93
- if (!isAppOpen) {
94
- destroy()
95
- }
96
- }
97
-
98
- override fun initialize() {
99
- val context: ReactContext = reactApplicationContext
100
- context.addLifecycleEventListener(this)
101
- @Suppress("DEPRECATION")
102
- val manager = LocalBroadcastManager.getInstance(context)
103
- eventHandler = MusicEvents(context)
104
- manager.registerReceiver(eventHandler!!, IntentFilter(EVENT_INTENT))
105
- autoConnectionDetector = AutoConnectionDetector(context) { connected ->
106
- if (connected) {
107
- onCarConnected()
108
- } else {
109
- onCarDisconnected()
110
- }
111
- }
112
- autoConnectionDetector?.registerCarConnectionReceiver()
113
- }
114
-
115
- override fun invalidate() {
116
- val context: ReactContext = reactApplicationContext
117
- if (eventHandler != null) {
118
- @Suppress("DEPRECATION")
119
- val manager = LocalBroadcastManager.getInstance(context)
120
- manager.unregisterReceiver(eventHandler!!)
121
- eventHandler = null
122
- }
123
- autoConnectionDetector?.unRegisterCarConnectionReceiver()
124
- }
125
-
126
- override fun onServiceConnected(name: ComponentName, service: IBinder) {
127
- scope.launch {
128
- binder = service as MusicBinder
129
- connecting = false
130
- if (musicService == null) {
131
- val binder: MusicBinder = service
132
- musicService = binder.service
133
- musicService?.setupPlayer(playerOptions);
134
- }
135
-
136
- isServiceBound = true
137
-
138
- // Reapply options that user set before with updateOptions
139
- if (options != null) {
140
- binder!!.updateOptions(options!!)
141
- }
142
-
143
- // Triggers all callbacks
144
- while (!initCallbacks.isEmpty()) {
145
- binder!!.post(initCallbacks.remove())
146
- }
147
- }
148
- }
149
-
150
- override fun onServiceDisconnected(name: ComponentName) {
151
- binder = null
152
- connecting = false
153
- isServiceBound = false
154
- }
155
-
156
- private fun verifyServiceBoundOrReject(promise: Promise): Boolean {
157
- if (!isServiceBound) {
158
- promise.reject(
159
- "player_not_initialized",
160
- "The player is not initialized. Call setupPlayer first."
161
- )
162
- return true
163
- }
164
-
165
- return false
166
- }
167
-
168
- /**
169
- * Waits for a connection to the service and/or runs the [Runnable] in the player thread
170
- */
171
- private fun waitForConnection(r: Runnable) {
172
- if (binder != null) {
173
- binder!!.post(r)
174
- return
175
- } else {
176
- initCallbacks.add(r)
177
- }
178
- if (connecting) return
179
- val context = reactApplicationContext
180
-
181
- // Binds the service to get a MediaWrapper instance
182
- val intent = Intent(context, MusicService::class.java)
183
- //context.startService(intent);
184
- try {
185
- if (Build.VERSION.SDK_INT >= 26) {
186
- context.startForegroundService(intent)
187
- } else {
188
- context.startService(intent)
189
- }
190
- } catch (ex: Exception) {
191
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
192
- val mgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
193
- val i = Intent(context, MusicService::class.java)
194
- val pi = PendingIntent.getForegroundService(
195
- context,
196
- 0,
197
- i,
198
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
199
- )
200
- val calendar = Calendar.getInstance()
201
- calendar.timeInMillis = System.currentTimeMillis()
202
- calendar.add(Calendar.MILLISECOND, 200)
203
- mgr[AlarmManager.RTC_WAKEUP, calendar.timeInMillis] = pi
204
- }
205
- }
206
- intent.action = Utils.CONNECT_INTENT
207
- context.bindService(intent, this, 0)
208
- connecting = true
209
- }
210
-
211
- /* ****************************** API ****************************** */
212
- override fun getConstants(): Map<String, Any> {
213
- val constants: MutableMap<String, Any> = HashMap()
214
-
215
- // Capabilities
216
- constants["CAPABILITY_PLAY"] = PlaybackStateCompat.ACTION_PLAY
217
- constants["CAPABILITY_PLAY_FROM_ID"] = PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID
218
- constants["CAPABILITY_PLAY_FROM_SEARCH"] = PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH
219
- constants["CAPABILITY_PAUSE"] = PlaybackStateCompat.ACTION_PAUSE
220
- constants["CAPABILITY_STOP"] = PlaybackStateCompat.ACTION_STOP
221
- constants["CAPABILITY_SEEK_TO"] = PlaybackStateCompat.ACTION_SEEK_TO
222
- constants["CAPABILITY_SKIP"] = PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM
223
- constants["CAPABILITY_SKIP_TO_NEXT"] = PlaybackStateCompat.ACTION_SKIP_TO_NEXT
224
- constants["CAPABILITY_SKIP_TO_PREVIOUS"] = PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
225
- constants["CAPABILITY_SET_RATING"] = PlaybackStateCompat.ACTION_SET_RATING
226
- constants["CAPABILITY_JUMP_FORWARD"] = PlaybackStateCompat.ACTION_FAST_FORWARD
227
- constants["CAPABILITY_JUMP_BACKWARD"] = PlaybackStateCompat.ACTION_REWIND
228
-
229
- // States
230
- constants["STATE_NONE"] = PlaybackStateCompat.STATE_NONE
231
- constants["STATE_READY"] = PlaybackStateCompat.STATE_PAUSED
232
- constants["STATE_PLAYING"] = PlaybackStateCompat.STATE_PLAYING
233
- constants["STATE_PAUSED"] = PlaybackStateCompat.STATE_PAUSED
234
- constants["STATE_STOPPED"] = PlaybackStateCompat.STATE_STOPPED
235
- constants["STATE_BUFFERING"] = PlaybackStateCompat.STATE_BUFFERING
236
- constants["STATE_CONNECTING"] = PlaybackStateCompat.STATE_CONNECTING
237
-
238
- // Rating Types
239
- constants["RATING_HEART"] = RatingCompat.RATING_HEART
240
- constants["RATING_THUMBS_UP_DOWN"] = RatingCompat.RATING_THUMB_UP_DOWN
241
- constants["RATING_3_STARS"] = RatingCompat.RATING_3_STARS
242
- constants["RATING_4_STARS"] = RatingCompat.RATING_4_STARS
243
- constants["RATING_5_STARS"] = RatingCompat.RATING_5_STARS
244
- constants["RATING_PERCENTAGE"] = RatingCompat.RATING_PERCENTAGE
245
- return constants
246
- }
247
-
248
- private fun convertBlackToWhite(bitmap: Bitmap): Bitmap {
249
- val width = bitmap.width
250
- val height = bitmap.height
251
-
252
- val outputBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
253
-
254
- for (x in 0 until width) {
255
- for (y in 0 until height) {
256
- val pixel = bitmap.getPixel(x, y)
257
- val alpha = Color.alpha(pixel)
258
- val red = Color.red(pixel)
259
- val green = Color.green(pixel)
260
- val blue = Color.blue(pixel)
261
-
262
- outputBitmap.setPixel(
263
- x,
264
- y,
265
- if (red == 0 && green == 0 && blue == 0) Color.argb(
266
- alpha,
267
- 255,
268
- 255,
269
- 255
270
- ) else pixel
271
- )
272
- }
273
- }
274
-
275
- return outputBitmap
276
- }
277
-
278
- private fun loadBitmapFromFile(filePath: String): Bitmap? {
279
- return try {
280
- val uri = Uri.parse(filePath)
281
- val path = uri.path ?: ""
282
- BitmapFactory.decodeFile(path)
283
- } catch (e: Exception) {
284
- null
285
- }
286
- }
287
-
288
- private fun getCircularBitmap(bitmap: Bitmap): Bitmap {
289
- val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
290
- val canvas = Canvas(output)
291
-
292
- val paint = Paint()
293
- paint.isAntiAlias = true
294
- paint.shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
295
-
296
- val radius = bitmap.width.coerceAtMost(bitmap.height) / 2f
297
- canvas.drawCircle(bitmap.width / 2f, bitmap.height / 2f, radius, paint)
298
-
299
- return output
300
- }
301
-
302
- private fun getCroppedBitmap(bitmap: Bitmap): Bitmap {
303
- val output = if (bitmap.width >= bitmap.height) {
304
- Bitmap.createBitmap(
305
- bitmap,
306
- (bitmap.width - bitmap.height) / 2,
307
- 0,
308
- bitmap.height,
309
- bitmap.height
310
- )
311
- } else {
312
- Bitmap.createBitmap(
313
- bitmap,
314
- 0,
315
- (bitmap.height - bitmap.width) / 2,
316
- bitmap.width,
317
- bitmap.width
318
- )
319
- }
320
-
321
- return output
322
- }
323
-
324
- var placeholderBitmap: Bitmap? = null
325
-
326
- @SuppressLint("DiscouragedApi")
327
- private fun hashmapToMediaItem(
328
- parentMediaId: String,
329
- hashmap: HashMap<String, String>,
330
- iconBitmap: Bitmap? = null
331
- ): MediaBrowserCompat.MediaItem {
332
- val mediaId = hashmap["mediaId"]
333
- val title = hashmap["title"]
334
- val subtitle = hashmap["subtitle"]
335
- val mediaUri = hashmap["mediaUri"]
336
- val iconUri = hashmap["iconUri"]
337
- val iconName = hashmap["iconName"]
338
- val cropThumbnail = hashmap["cropThumbnail"].toBoolean()
339
-
340
- val mediaIdParts = mediaId?.split("-/-")
341
- val itemType = mediaIdParts?.getOrNull(1)
342
-
343
- val isArtist = itemType == "artist"
344
- val playableFlag =
345
- if (itemType == "track" || itemType == "empty" || itemType == "shuffle") MediaItem.FLAG_PLAYABLE else MediaItem.FLAG_BROWSABLE
346
-
347
- val mediaDescriptionBuilder = MediaDescriptionCompat.Builder()
348
- mediaDescriptionBuilder.setMediaId(mediaId)
349
- mediaDescriptionBuilder.setTitle(title)
350
- mediaDescriptionBuilder.setSubtitle(subtitle)
351
- mediaDescriptionBuilder.setMediaUri(if (mediaUri != null) Uri.parse(mediaUri) else null)
352
-
353
- if (iconBitmap != null) {
354
- var bitmap = iconBitmap
355
- if (cropThumbnail) {
356
- bitmap = if (isArtist) {
357
- getCircularBitmap(bitmap)
358
- } else {
359
- getCroppedBitmap(bitmap)
360
- }
361
- }
362
-
363
- mediaDescriptionBuilder.setIconBitmap(bitmap)
364
- } else if (iconName != null) {
365
- if (iconName.contains("placeholder") && placeholderBitmap != null) {
366
- mediaDescriptionBuilder.setIconBitmap(placeholderBitmap)
367
- } else {
368
- val currentResourceId = reactApplicationContext.resources.getIdentifier(
369
- iconName,
370
- "mipmap",
371
- reactApplicationContext.packageName
372
- )
373
- if (currentResourceId != 0) {
374
- var bitmap = BitmapFactory.decodeResource(
375
- reactApplicationContext.resources,
376
- currentResourceId
377
- )
378
- if (bitmap != null) {
379
- if (iconName == "ic_auto_placeholder_foreground") {
380
- placeholderBitmap = bitmap
381
- } else if (iconName != "ic_auto_play_shuffle_foreground") {
382
- bitmap = convertBlackToWhite(bitmap)
383
- }
384
- mediaDescriptionBuilder.setIconBitmap(bitmap)
385
- }
386
- }
387
- }
388
- } else if (iconUri != null) {
389
- if (iconUri.startsWith("http")) {
390
- if (cropThumbnail) {
391
- if (placeholderBitmap == null) {
392
- val currentResourceId = reactApplicationContext.resources.getIdentifier(
393
- "placeholder",
394
- "mipmap",
395
- reactApplicationContext.packageName
396
- )
397
- if (currentResourceId != 0) {
398
- placeholderBitmap = BitmapFactory.decodeResource(
399
- reactApplicationContext.resources,
400
- currentResourceId
401
- )
402
- }
403
- }
404
- if (placeholderBitmap != null) {
405
- val bitmap =
406
- if (isArtist) getCircularBitmap(placeholderBitmap!!) else placeholderBitmap
407
- mediaDescriptionBuilder.setIconBitmap(bitmap)
408
- }
409
-
410
- Glide.with(reactApplicationContext)
411
- .asBitmap()
412
- .load(iconUri)
413
- .into(object : CustomTarget<Bitmap>() {
414
- override fun onResourceReady(
415
- resource: Bitmap,
416
- transition: Transition<in Bitmap>?
417
- ) {
418
- if (mediaId == null) return
419
-
420
- executor.submit(Callable {
421
- if (musicService != null) {
422
- val toUpdateMediaItem =
423
- hashmapToMediaItem(parentMediaId, hashmap, resource)
424
- val items =
425
- musicService!!.mediaTree.getOrPut(parentMediaId) { mutableListOf() }
426
- val index =
427
- items.indexOfFirst { it.mediaId == toUpdateMediaItem.mediaId }
428
- if (index != -1) {
429
- items[index] = toUpdateMediaItem
430
- }
431
- musicService!!.mediaTree[parentMediaId] = items
432
- musicService!!.notifyChildrenChanged(parentMediaId)
433
- }
434
- })
435
- }
436
-
437
- override fun onLoadCleared(placeholder: Drawable?) {}
438
- })
439
- } else {
440
- mediaDescriptionBuilder.setIconUri(Uri.parse(iconUri))
441
- }
442
- } else if (iconUri.startsWith("file")) {
443
- var bitmap = loadBitmapFromFile(iconUri)
444
- if (bitmap != null) {
445
- if (cropThumbnail) {
446
- bitmap = if (isArtist) {
447
- getCircularBitmap(bitmap)
448
- } else {
449
- getCroppedBitmap(bitmap)
450
- }
451
- }
452
-
453
- mediaDescriptionBuilder.setIconBitmap(bitmap)
454
- }
455
- }
456
- }
457
-
458
- val extras = Bundle()
459
- if (hashmap["groupTitle"] != null) {
460
- extras.putString(
461
- MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
462
- hashmap["groupTitle"]
463
- )
464
- }
465
- if (hashmap["contentStyle"] != null) {
466
- extras.putInt(
467
- MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
468
- hashmap["contentStyle"]!!
469
- .toInt()
470
- )
471
- }
472
- if (hashmap["childrenPlayableContentStyle"] != null) {
473
- extras.putInt(
474
- MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
475
- hashmap["childrenPlayableContentStyle"]!!
476
- .toInt()
477
- )
478
- }
479
- if (hashmap["childrenBrowsableContentStyle"] != null) {
480
- extras.putInt(
481
- MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
482
- hashmap["childrenBrowsableContentStyle"]!!
483
- .toInt()
484
- )
485
- }
486
- if (hashmap["playbackProgress"] != null) {
487
- val playbackProgress = hashmap["playbackProgress"]!!.toDouble()
488
- if (playbackProgress > 0.98) {
489
- extras.putInt(
490
- MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
491
- MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
492
- )
493
- } else if (playbackProgress == 0.0) {
494
- extras.putInt(
495
- MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
496
- MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
497
- )
498
- } else {
499
- extras.putInt(
500
- MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
501
- MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
502
- )
503
- extras.putDouble(
504
- MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE,
505
- playbackProgress
506
- )
507
- }
508
- }
509
- mediaDescriptionBuilder.setExtras(extras)
510
- return MediaItem(mediaDescriptionBuilder.build(), playableFlag)
511
- }
512
-
513
- private fun readableArrayToMediaItems(
514
- parentMediaId: String,
515
- data: ArrayList<HashMap<String, String>>
516
- ): MutableList<MediaItem> {
517
- val executor: ExecutorService =
518
- Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
519
- val mediaItemList: MutableList<MediaItem> = ArrayList()
520
-
521
- val futures: List<Future<MediaItem>> = data.map { hashmap ->
522
- executor.submit(Callable {
523
- hashmapToMediaItem(parentMediaId, hashmap)
524
- })
525
- }
526
-
527
- for (future in futures) {
528
- try {
529
- mediaItemList.add(future.get())
530
- } catch (_: InterruptedException) {
531
- }
532
- }
533
-
534
- executor.shutdown()
535
- return mediaItemList
536
- }
537
-
538
- @ReactMethod
539
- fun setupPlayer(data: ReadableMap?, promise: Promise) {
540
- try {
541
- if (isServiceBound) {
542
- promise.reject(
543
- "player_already_initialized",
544
- "The player has already been initialized via setupPlayer."
545
- )
546
- return
547
- }
548
-
549
- // prevent crash Fatal Exception: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException
550
- /* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && AppForegroundTracker.backgrounded) {
551
- promise.reject(
552
- "android_cannot_setup_player_in_background",
553
- "On Android the app must be in the foreground when setting up the player."
554
- )
555
- return
556
- }*/
557
-
558
- // Validate buffer keys.
559
- val bundledData = Arguments.toBundle(data)
560
- val minBuffer =
561
- bundledData?.getDouble(MusicService.MIN_BUFFER_KEY)?.toInt()
562
- ?: DEFAULT_MIN_BUFFER_MS
563
- val maxBuffer =
564
- bundledData?.getDouble(MusicService.MAX_BUFFER_KEY)?.toInt()
565
- ?: DEFAULT_MAX_BUFFER_MS
566
- val playBuffer =
567
- bundledData?.getDouble(MusicService.PLAY_BUFFER_KEY)?.toInt()
568
- ?: DEFAULT_BUFFER_FOR_PLAYBACK_MS
569
- val backBuffer =
570
- bundledData?.getDouble(MusicService.BACK_BUFFER_KEY)?.toInt()
571
- ?: DEFAULT_BACK_BUFFER_DURATION_MS
572
-
573
- if (playBuffer < 0) {
574
- promise.reject(
575
- "play_buffer_error",
576
- "The value for playBuffer should be greater than or equal to zero."
577
- )
578
- return
579
- }
580
-
581
- if (backBuffer < 0) {
582
- promise.reject(
583
- "back_buffer_error",
584
- "The value for backBuffer should be greater than or equal to zero."
585
- )
586
- return
587
- }
588
-
589
- if (minBuffer < playBuffer) {
590
- promise.reject(
591
- "min_buffer_error",
592
- "The value for minBuffer should be greater than or equal to playBuffer."
593
- )
594
- return
595
- }
596
-
597
- if (maxBuffer < minBuffer) {
598
- promise.reject(
599
- "min_buffer_error",
600
- "The value for maxBuffer should be greater than or equal to minBuffer."
601
- )
602
- return
603
- }
604
-
605
- // playerSetUpPromise = promise
606
- playerOptions = bundledData
607
-
608
- @Suppress("DEPRECATION")
609
- LocalBroadcastManager.getInstance(reactApplicationContext).registerReceiver(
610
- MusicEvents(reactApplicationContext),
611
- IntentFilter(EVENT_INTENT)
612
- )
613
-
614
- Intent(reactApplicationContext, MusicService::class.java).also { intent ->
615
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
616
- reactApplicationContext.startForegroundService(intent)
617
- } else {
618
- reactApplicationContext.startService(intent)
619
- }
620
- reactApplicationContext.bindService(intent, this, Context.BIND_AUTO_CREATE)
621
- }
622
- } catch (_: Exception) {}
623
- }
624
-
625
- @ReactMethod
626
- fun setBrowseTree(mediaItems: ReadableMap?, callback: Promise) {
627
- waitForConnection {
628
- try {
629
- if (musicService != null) {
630
- executor.submit(Callable {
631
- val mediaItemsMap = mediaItems?.toHashMap()
632
- if (mediaItemsMap != null) {
633
- musicService!!.mediaTree =
634
- mediaItemsMap.mapValues {
635
- @Suppress("UNCHECKED_CAST")
636
- readableArrayToMediaItems(
637
- it.key,
638
- it.value as ArrayList<HashMap<String, String>>
639
- )
640
- } as MutableMap<String, MutableList<MediaItem>>
641
- }
642
-
643
- musicService!!.toUpdateMediaItems.forEach { (parentMediaId, toUpdateItems) ->
644
- val items =
645
- musicService!!.mediaTree.getOrPut(parentMediaId) { mutableListOf() }
646
- toUpdateItems.forEach { toUpdateItem ->
647
- val index =
648
- items.indexOfFirst { it.mediaId == toUpdateItem.mediaId }
649
- if (index != -1) {
650
- items[index] = toUpdateItem
651
- }
652
- }
653
- musicService!!.mediaTree[parentMediaId] = items
654
- }
655
-
656
- musicService!!.mediaTree.keys.forEach {
657
- musicService!!.notifyChildrenChanged(it)
658
- }
659
- callback.resolve(null)
660
- })
661
- }
662
- } catch (_: Exception) {}
663
- }
664
- }
665
-
666
- @ReactMethod
667
- fun updateBrowseTree(mediaItems: ReadableMap, callback: Promise) {
668
- try {
669
- if (musicService != null) {
670
- executor.submit(Callable {
671
- val mediaItemsMap = mediaItems.toHashMap()
672
- musicService!!.mediaTree += mediaItemsMap.mapValues {
673
- @Suppress("UNCHECKED_CAST")
674
- readableArrayToMediaItems(
675
- it.key,
676
- it.value as ArrayList<HashMap<String, String>>
677
- )
678
- } as MutableMap<String, MutableList<MediaItem>>
679
- mediaItemsMap.keys.forEach {
680
- musicService!!.notifyChildrenChanged(it)
681
- }
682
- callback.resolve(null)
683
- })
684
- }
685
- } catch (_: Exception) {}
686
- }
687
-
688
- @ReactMethod
689
- fun setSearchResult(mediaItems: ReadableArray, data: ReadableMap, callback: Promise) {
690
- waitForConnection {
691
- try {
692
- if (musicService != null) {
693
- val bundle = Arguments.toBundle(data)
694
- val query = bundle?.getString("query")
695
- if (query == musicService!!.searchQuery) {
696
- musicService!!.searchResult?.sendResult(
697
- @Suppress("UNCHECKED_CAST")
698
- readableArrayToMediaItems(
699
- "search",
700
- mediaItems.toArrayList() as ArrayList<HashMap<String, String>>
701
- )
702
- )
703
- }
704
- callback.resolve(null)
705
- }
706
- } catch (_: Exception) {}
707
- }
708
- }
709
-
710
- @ReactMethod
711
- fun destroy() {
712
- val serviceConnection = this
713
- scope.launch {
714
- musicService = null
715
- isServiceBound = false
716
- connecting = false
717
- firstPlayDone = false
718
-
719
- // Ignore if it was already destroyed
720
- if (binder == null && !connecting) return@launch
721
- try {
722
- if (binder != null) {
723
- binder!!.manager.metadata.removeNotifications()
724
- delay(300)
725
- binder!!.destroy()
726
- binder = null
727
- }
728
- val context: ReactContext? = reactApplicationContext
729
- context?.unbindService(serviceConnection)
730
- } catch (ex: Exception) {
731
- // This method shouldn't be throwing unhandled errors even if something goes wrong.
732
- Timber.tag(Utils.LOG).e(ex, "An error occurred while destroying the service")
733
- }
734
- }
735
- }
736
-
737
- @ReactMethod
738
- fun updateAndroidAutoPlayerOptions(data: ReadableMap?, callback: Promise) {
739
- scope.launch {
740
- waitForConnection {
741
- try {
742
- val options = Arguments.toBundle(data)
743
-
744
- options?.let {
745
- musicService?.updateOptions(it)
746
- }
747
-
748
- callback.resolve(null)
749
- } catch (_: Exception) {}
750
- }
751
- }
752
- }
753
-
754
- @ReactMethod
755
- fun updateOptions(data: ReadableMap?, callback: Promise) {
756
- scope.launch {
757
- try {
758
- // keep options as we may need them for correct MetadataManager reinitialization later
759
- options = Arguments.toBundle(data)
760
- waitForConnection {
761
- options?.let { binder?.updateOptions(it) }
762
- callback.resolve(null)
763
- }
764
- } catch (_: Exception) {
765
- }
766
- }
767
- }
768
-
769
- // @ReactMethod
770
- // fun setNowPlaying(trackMap: ReadableMap, callback: Promise) {
771
- // val bundle = Arguments.toBundle(trackMap)
772
- //
773
- // waitForConnection {
774
- // try {
775
- // val track = bundle?.let {
776
- // binder?.let { it1 ->
777
- // Track(
778
- // reactApplicationContext,
779
- // it,
780
- // it1.ratingType
781
- // )
782
- // }
783
- // }
784
- // if (track != null) {
785
- // binder?.manager?.currentTrack = track
786
- // binder?.manager?.metadata?.updateMetadata(track)
787
- // }
788
- // } catch (ex: Exception) {
789
- // callback.reject("invalid_track_object", ex)
790
- // return@waitForConnection // @waitForConnection
791
- // }
792
- //
793
- // if (binder != null && binder!!.manager != null && binder!!.manager.currentTrack == null)
794
- // callback.reject("invalid_track_object", "Track is missing a required key")
795
- //
796
- // callback.resolve(null)
797
- // }
798
- // }
799
-
800
- @ReactMethod
801
- fun setNowPlaying(trackMap: ReadableMap, callback: Promise) {
802
- scope.launch {
803
- val bundle = Arguments.toBundle(trackMap)
804
-
805
- waitForConnection {
806
- try {
807
- val state = if (trackMap.hasKey("state")) trackMap.getInt("state") else 0
808
-
809
- var elapsedTime: Long = -1
810
-
811
- if (trackMap.hasKey("elapsedTime")) {
812
- elapsedTime = try {
813
- Utils.toMillis(trackMap.getDouble("elapsedTime"))
814
- } catch (ex: Exception) {
815
- Utils.toMillis(trackMap.getInt("elapsedTime").toDouble())
816
- }
817
- }
818
-
819
- if (bundle != null && binder != null) {
820
- val track = Track(reactApplicationContext, bundle, binder!!.ratingType)
821
- binder!!.manager.currentTrack = track
822
- binder!!.manager.metadata.updateMetadata(track)
823
- binder!!.manager.setState(state, elapsedTime)
824
- }
825
- } catch (ex: Exception) {
826
- callback.reject("invalid_track_object", ex)
827
- return@waitForConnection
828
- }
829
-
830
- if (binder?.manager?.currentTrack == null) {
831
- callback.reject("invalid_track_object", "Track is missing a required key")
832
- }
833
-
834
- callback.resolve(null)
835
- }
836
- }
837
- }
838
-
839
-
840
- @ReactMethod
841
- fun setAndroidAutoPlayerTracks(tracksArray: ReadableArray, options: ReadableMap, callback: Promise) {
842
- scope.launch {
843
- waitForConnection {
844
- try {
845
- Handler(Looper.getMainLooper()).postDelayed({
846
- val bundle = Arguments.toBundle(options)
847
- val editQueue = bundle?.getBoolean("editQueue")
848
-
849
- val tracks = mutableListOf<Track>()
850
-
851
- for (i in 0 until tracksArray.size()) {
852
- val trackMap = tracksArray.getMap(i)
853
- val trackBundle = Arguments.toBundle(trackMap)
854
-
855
- val track = trackBundle?.let {
856
- binder?.let { it1 ->
857
- Track(
858
- reactApplicationContext,
859
- it,
860
- it1.ratingType
861
- )
862
- }
863
- }
864
-
865
- track?.let { tracks.add(it) }
866
- }
867
-
868
- if (tracks.isNotEmpty()) {
869
- if (editQueue == true) {
870
- musicService?.removeUpcomingTracks()
871
- musicService?.removePreviousTracks()
872
-
873
- musicService?.add(
874
- tracks,
875
- 1
876
- )
877
- } else {
878
- if (tracks[0].url.isEmpty()) {
879
- musicService?.playWhenReady = false
880
- if (musicService?.state != AudioPlayerState.PAUSED) musicService?.pause()
881
- } else {
882
- musicService?.playWhenReady = firstPlayDone
883
- }
884
-
885
- if (musicService?.getPlayerQueueHead() == null) {
886
- musicService?.add(
887
- tracks,
888
- 0
889
- )
890
- } else {
891
- musicService?.removeUpcomingTracks()
892
- musicService?.removePreviousTracks()
893
-
894
- musicService?.add(
895
- tracks,
896
- 1
897
- )
898
-
899
- musicService?.skipToNext()
900
-
901
- musicService?.updateMetadataForTrack(0, tracks[0])
902
-
903
- musicService?.remove(0)
904
- }
905
- }
906
- }
907
-
908
- callback.resolve(null)
909
- }, 100)
910
- } catch (_: Exception) {}
911
- }
912
- }
913
-
914
- }
915
-
916
- @ReactMethod
917
- fun updatePlayback(trackMap: ReadableMap, callback: Promise) {
918
- val bundle = Arguments.toBundle(trackMap)
919
- waitForConnection {
920
- try {
921
- val state =
922
- if (trackMap.hasKey("state")) trackMap.getInt("state") else -1
923
- var elapsedTime: Long = -1
924
- if (trackMap.hasKey("elapsedTime")) {
925
- elapsedTime = try {
926
- Utils.toMillis(trackMap.getInt("elapsedTime").toDouble())
927
- } catch (ex: Exception) {
928
- Utils.toMillis(trackMap.getDouble("elapsedTime"))
929
- }
930
- }
931
-
932
- var duration: Long = -1
933
- if (trackMap.hasKey("duration")) {
934
- duration = try {
935
- Utils.toMillis(trackMap.getInt("duration").toDouble())
936
- } catch (ex: Exception) {
937
- Utils.toMillis(trackMap.getDouble("duration"))
938
- }
939
- }
940
- //update current track duration
941
- val currentTrack: Track? =
942
- binder?.manager?.currentTrack
943
- if (currentTrack != null && duration > -1) {
944
- currentTrack.duration = duration
945
- binder?.manager?.metadata?.updateMetadata(currentTrack)
946
- }
947
- if (state > -1) {
948
- binder?.manager?.setState(state, elapsedTime)
949
- }
950
-
951
- if (autoConnectionDetector?.isCarConnected == true || isAndroidTv) {
952
- Handler(Looper.getMainLooper()).postDelayed({
953
- val isLoading = bundle?.getBoolean("isLoading")
954
- if (state == 3) {
955
- musicService?.play()
956
- } else if (state == 2) {
957
- musicService?.pause()
958
- }
959
- if (elapsedTime >= 0 && isLoading == false) {
960
- musicService?.seekTo((elapsedTime / 1000).toFloat())
961
- }
962
- }, 100)
963
- }
964
-
965
- callback.resolve(null)
966
-
967
- } catch (ex: Exception) {
968
- callback.reject("invalid_track_object", ex)
969
- return@waitForConnection
970
- }
971
- if (binder != null && binder!!.manager
972
- .currentTrack == null
973
- ) callback.reject("invalid_track_object", "Track is missing a required key")
974
- }
975
- }
976
-
977
-
978
- private fun bundleToTrack(bundle: Bundle): Track? {
979
- return musicService?.let {
980
- Track(
981
- reactApplicationContext.baseContext,
982
- bundle,
983
- it.ratingType
984
- )
985
- }
986
- }
987
-
988
- private fun readableArrayToTrackList(data: ReadableArray?): MutableList<Track> {
989
- val bundleList = Arguments.toList(data)
990
- if (bundleList != null) {
991
- return bundleList.mapNotNull {
992
- if (it is Bundle) {
993
- bundleToTrack(it)
994
- } else {
995
- null
996
- // or handle invalid bundle case
997
- }
998
- }.toMutableList()
999
- }
1000
- return mutableListOf()
1001
- }
1002
-
1003
- @ReactMethod
1004
- fun add(data: ReadableArray?, insertBeforeIndex: Int, callback: Promise) {
1005
- scope.launch {
1006
- if (verifyServiceBoundOrReject(callback)) return@launch
1007
-
1008
- try {
1009
- val tracks = readableArrayToTrackList(data);
1010
- if (insertBeforeIndex < -1 || insertBeforeIndex > (musicService?.tracks?.size
1011
- ?: 0)
1012
- ) {
1013
- callback.reject("index_out_of_bounds", "The track index is out of bounds")
1014
- return@launch
1015
- }
1016
- val index =
1017
- if (insertBeforeIndex == -1) musicService?.tracks?.size else insertBeforeIndex
1018
- if (index != null) {
1019
- musicService?.add(
1020
- tracks,
1021
- index
1022
- )
1023
- }
1024
- callback.resolve(index)
1025
- } catch (exception: Exception) {
1026
- // rejectWithException(callback, exception)
1027
- }
1028
- }
1029
- }
1030
-
1031
- @ReactMethod
1032
- fun load(data: ReadableMap?, callback: Promise) {
1033
- scope.launch {
1034
- if (verifyServiceBoundOrReject(callback)) return@launch
1035
-
1036
- try {
1037
- if (data == null) {
1038
- callback.resolve(null)
1039
- return@launch
1040
- }
1041
- val bundle = Arguments.toBundle(data);
1042
- if (bundle is Bundle) {
1043
- bundleToTrack(bundle)?.let { musicService?.load(it) }
1044
- callback.resolve(null)
1045
- } else {
1046
- callback.reject("invalid_track_object", "Track was not a dictionary type")
1047
- }
1048
- } catch (_: Exception) {}
1049
- }
1050
- }
1051
-
1052
- @ReactMethod
1053
- fun reset(callback: Promise) {
1054
- waitForConnection {
1055
- try {
1056
- if (binder != null) {
1057
- binder!!.manager.onReset()
1058
- callback.resolve(null)
1059
- }
1060
- } catch (_: Exception) {}
1061
- }
1062
- }
1063
-
1064
- @ReactMethod
1065
- fun removeNotifications(callback: Promise) {
1066
- waitForConnection {
1067
- try {
1068
- if (binder != null) {
1069
- binder!!.manager.metadata.removeNotifications()
1070
- callback.resolve(null)
1071
- }
1072
- } catch (_: Exception) {}
1073
- }
1074
- }
1075
-
1076
- @ReactMethod
1077
- fun resetAndroidAutoService() {
1078
- scope.launch {
1079
- // if (verifyServiceBoundOrReject(callback)) return@launch
1080
-
1081
- try {
1082
- musicService?.stop()
1083
- delay(300) // Allow playback to stop
1084
- musicService?.clear()
1085
-
1086
- // callback.resolve(null)
1087
- } catch (_: Exception) {}
1088
- }
1089
- }
1090
-
1091
- @ReactMethod
1092
- fun clear(callback: Promise) {
1093
- scope.launch {
1094
- if (verifyServiceBoundOrReject(callback)) return@launch
1095
-
1096
- try {
1097
- musicService?.clear()
1098
- callback.resolve(null)
1099
- } catch (_: Exception) {}
1100
- }
1101
- }
1102
-
1103
- @ReactMethod
1104
- fun play(callback: Promise) {
1105
- scope.launch {
1106
- if (verifyServiceBoundOrReject(callback)) return@launch
1107
-
1108
- try {
1109
- musicService?.play()
1110
- callback.resolve(null)
1111
- } catch (_: Exception) {}
1112
- }
1113
- }
1114
-
1115
- @ReactMethod
1116
- fun pause(callback: Promise) {
1117
- scope.launch {
1118
- if (verifyServiceBoundOrReject(callback)) return@launch
1119
-
1120
- try {
1121
- musicService?.pause()
1122
- callback.resolve(null)
1123
- } catch (_: Exception) {}
1124
- }
1125
- }
1126
-
1127
- @ReactMethod
1128
- fun setIsAndroidTv(value: Boolean, callback: Promise) {
1129
- scope.launch {
1130
- isAndroidTv = value
1131
- }
1132
- }
1133
-
1134
- @SuppressLint("VisibleForTests")
1135
- @ReactMethod
1136
- fun checkAndroidAutoConnection(callback: Promise) {
1137
- scope.launch {
1138
- val params = Arguments.createMap()
1139
- params.putBoolean("connected", autoConnectionDetector?.isCarConnected == true)
1140
-
1141
- val currentReactContext = if (bridgelessEnabled) reactHost?.currentReactContext else reactNativeHost?.reactInstanceManager?.currentReactContext
1142
- currentReactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
1143
- ?.emit(
1144
- "car-connection-update", params
1145
- )
1146
- }
1147
- }
1148
-
1149
- override fun onHostResume() {
1150
- isAppOpen = true
1151
- }
1152
-
1153
- override fun onHostPause() {}
1154
-
1155
- @SuppressLint("VisibleForTests")
1156
- override fun onHostDestroy() {
1157
- val currentReactContext = if (bridgelessEnabled) reactHost?.currentReactContext else reactNativeHost?.reactInstanceManager?.currentReactContext
1158
- isAppOpen = false
1159
- if (autoConnectionDetector?.isCarConnected == true) {
1160
- // musicService?.clear()
1161
-
1162
- Handler(Looper.getMainLooper()).postDelayed({
1163
- if (autoConnectionDetector?.isCarConnected == true && currentReactContext == null) {
1164
- musicService?.invokeStartTask(reactApplicationContext, true)
1165
- }
1166
- }, 2000)
1167
- }
1168
-
1169
- if (isAndroidTv) {
1170
- musicService?.clear()
1171
- }
1172
-
1173
- if (autoConnectionDetector?.isCarConnected != true) {
1174
- destroy()
1175
- }
1176
- }
1177
- }