@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,1254 +0,0 @@
1
- package com.guichaguri.trackplayer.service
2
-
3
- import android.annotation.SuppressLint
4
- import android.app.ActivityManager
5
- import android.app.ForegroundServiceStartNotAllowedException
6
- import android.app.Notification
7
- import android.app.NotificationChannel
8
- import android.app.NotificationManager
9
- import android.app.PendingIntent
10
- import android.content.Context
11
- import android.content.Intent
12
- import android.content.pm.ServiceInfo
13
- import android.os.Build
14
- import android.os.Bundle
15
- import android.os.Handler
16
- import android.os.IBinder
17
- import android.support.v4.media.MediaBrowserCompat.MediaItem
18
- import android.support.v4.media.RatingCompat
19
- import android.support.v4.media.session.MediaSessionCompat
20
- import android.support.v4.media.session.PlaybackStateCompat
21
- import android.view.KeyEvent
22
- import android.view.KeyEvent.KEYCODE_MEDIA_STOP
23
- import androidx.annotation.MainThread
24
- import androidx.core.app.NotificationCompat
25
- import androidx.media.session.MediaButtonReceiver
26
- import androidx.media.utils.MediaConstants
27
- import com.facebook.react.ReactHost
28
- import com.facebook.react.ReactInstanceEventListener
29
- import com.facebook.react.ReactInstanceManager
30
- import com.facebook.react.bridge.Arguments
31
- import com.facebook.react.bridge.ReactContext
32
- import com.facebook.react.bridge.WritableNativeMap
33
- import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.bridgelessEnabled
34
- import com.facebook.react.jstasks.HeadlessJsTaskConfig
35
- import com.facebook.react.modules.appregistry.AppRegistry
36
- import com.facebook.react.modules.core.DeviceEventManagerModule
37
- import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper
38
- import com.google.android.exoplayer2.source.MediaSource
39
- import com.guichaguri.trackplayer.HeadlessJsMediaService
40
- import com.guichaguri.trackplayer.R
41
- import com.guichaguri.trackplayer.extensions.asLibState
42
- import com.guichaguri.trackplayer.kotlinaudio.models.AAMediaSessionCallBack
43
- import com.guichaguri.trackplayer.kotlinaudio.models.AudioContentType
44
- import com.guichaguri.trackplayer.kotlinaudio.models.AudioItemTransitionReason
45
- import com.guichaguri.trackplayer.kotlinaudio.models.AudioPlayerState
46
- import com.guichaguri.trackplayer.kotlinaudio.models.BufferConfig
47
- import com.guichaguri.trackplayer.kotlinaudio.models.CacheConfig
48
- import com.guichaguri.trackplayer.kotlinaudio.models.Capability
49
- import com.guichaguri.trackplayer.kotlinaudio.models.MediaSessionCallback
50
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton
51
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.CUSTOM_ACTION
52
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.NEXT
53
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.PLAY_PAUSE
54
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.PREVIOUS
55
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.SEEK_TO
56
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationButton.STOP
57
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationConfig
58
- import com.guichaguri.trackplayer.kotlinaudio.models.NotificationState
59
- import com.guichaguri.trackplayer.kotlinaudio.models.PlayerConfig
60
- import com.guichaguri.trackplayer.kotlinaudio.models.RepeatMode
61
- import com.guichaguri.trackplayer.kotlinaudio.players.QueuedAudioPlayer
62
- import com.guichaguri.trackplayer.model.Track
63
- import com.guichaguri.trackplayer.model.TrackAudioItem
64
- import com.guichaguri.trackplayer.module.AutoConnectionDetector
65
- import com.guichaguri.trackplayer.module.MusicEvents
66
- import com.guichaguri.trackplayer.module.MusicModule
67
- import com.guichaguri.trackplayer.module.MusicModule.Companion.autoConnectionDetector
68
- import com.guichaguri.trackplayer.service.Utils.setRating
69
- import kotlinx.coroutines.Dispatchers
70
- import kotlinx.coroutines.Job
71
- import kotlinx.coroutines.MainScope
72
- import kotlinx.coroutines.delay
73
- import kotlinx.coroutines.flow.flow
74
- import kotlinx.coroutines.launch
75
- import kotlinx.coroutines.withContext
76
- import java.util.concurrent.TimeUnit
77
-
78
- /**
79
- * @author Guichaguri
80
- */
81
-
82
- class MusicService : HeadlessJsMediaService() {
83
- private var player: QueuedAudioPlayer? = null
84
- var manager: MusicManager? = null
85
- var handler: Handler? = null
86
- private var intentToStop = false
87
- var mediaTree: MutableMap<String, MutableList<MediaItem>> = HashMap()
88
- var toUpdateMediaItems: MutableMap<String, MutableList<MediaItem>> = HashMap()
89
- var loadingChildrenParentMediaId: String? = null
90
- var searchQuery: String? = null
91
- var searchResult: Result<MutableList<MediaItem>>? = null
92
-
93
- private val scope = MainScope()
94
-
95
- val tracks: List<Track>
96
- get() = player?.items?.map { (it as TrackAudioItem).track } ?: emptyList()
97
-
98
- val state
99
- get() = player?.playerState
100
-
101
- var ratingType: Int
102
- get() = player?.ratingType ?: RatingCompat.RATING_NONE
103
- set(value) {
104
- player?.ratingType = value
105
- }
106
-
107
- val playbackError
108
- get() = player?.playbackError
109
-
110
- val event
111
- get() = player?.event
112
-
113
- var playWhenReady: Boolean
114
- get() = player?.playWhenReady ?: false
115
- set(value) {
116
- player?.playWhenReady = value
117
- }
118
-
119
- private var latestOptions: Bundle? = null
120
-
121
- private var mediaSession: MediaSessionCompat? = null
122
- private var stateBuilder: PlaybackStateCompat.Builder? = null
123
-
124
- override fun getTaskConfig(intent: Intent): HeadlessJsTaskConfig {
125
- return HeadlessJsTaskConfig("TrackPlayer", Arguments.createMap(), 0, true)
126
- }
127
-
128
- override fun onHeadlessJsTaskFinish(taskId: Int) {
129
- // Overridden to prevent the service from being terminated
130
- }
131
-
132
- @SuppressLint("VisibleForTests")
133
- @MainThread
134
- fun emit(event: String, data: Bundle? = null) {
135
- val currentReactContext = if (bridgelessEnabled) reactHost.currentReactContext else reactNativeHost.reactInstanceManager.currentReactContext
136
- currentReactContext
137
- ?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
138
- ?.emit(event, data?.let { Arguments.fromBundle(it) })
139
- }
140
-
141
- fun destroy(intentToStop: Boolean) {
142
- try {
143
- if (handler != null) {
144
- handler!!.removeMessages(0)
145
- handler = null
146
- }
147
- if (manager != null) {
148
- manager!!.destroy(intentToStop)
149
- manager = null
150
- }
151
-
152
- if (autoConnectionDetector?.isCarConnected != true) {
153
- player?.destroy()
154
- }
155
- } catch (_: Exception) {}
156
- }
157
-
158
- @SuppressLint("VisibleForTests")
159
- private fun onStartForeground() {
160
- var serviceForeground = false
161
- if (manager != null) {
162
- // The session is only active when the service is on foreground
163
- serviceForeground = manager!!.metadata.session.isActive
164
- }
165
-
166
- if (!serviceForeground) {
167
- val currentReactContext = if (bridgelessEnabled) reactHost.currentReactContext else reactNativeHost.reactInstanceManager.currentReactContext
168
-
169
- // Checks whether there is a React activity
170
- if (currentReactContext == null || !currentReactContext.hasCurrentActivity()) {
171
- val channel = Utils.getNotificationChannel(this as Context)
172
-
173
- // Sets the service to foreground with an empty notification
174
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
175
- startForeground(
176
- 1,
177
- NotificationCompat.Builder(this, channel).build(),
178
- ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
179
- )
180
- } else {
181
- startForeground(1, NotificationCompat.Builder(this, channel).build())
182
- }
183
- // Stops the service right after
184
- stopSelf()
185
- }
186
- }
187
- }
188
-
189
- override fun onBind(intent: Intent): IBinder? {
190
- /* if(Utils.CONNECT_INTENT.equals(intent.getAction())) {
191
- return new MusicBinder(this, manager);
192
- }
193
- return super.onBind(intent); */
194
-
195
- return if (SERVICE_INTERFACE == intent.action) {
196
- super.onBind(intent)
197
- } else MusicBinder(this, manager!!)
198
- }
199
-
200
- fun invokeStartTask(reactContext: ReactContext, restart: Boolean = false) {
201
- try {
202
- val catalystInstance = reactContext.catalystInstance
203
- val jsAppModuleName = "AndroidAuto"
204
- val appParams = WritableNativeMap()
205
- appParams.putDouble("rootTag", 1.0)
206
- appParams.putBoolean("restart", restart)
207
- val appProperties = Bundle.EMPTY
208
- if (appProperties != null) {
209
- appParams.putMap("initialProps", Arguments.fromBundle(appProperties))
210
- }
211
- val jsModule = catalystInstance.getJSModule(AppRegistry::class.java)
212
- if (jsModule !== null) jsModule.runApplication(jsAppModuleName, appParams)
213
- } catch (e: Exception) {
214
- e.printStackTrace()
215
- }
216
- }
217
-
218
- override fun onSearch(query: String, extras: Bundle?, result: Result<MutableList<MediaItem>>) {
219
- searchQuery = query
220
- searchResult = result
221
- result.detach()
222
- emit(MusicEvents.SEARCH, Bundle().apply {
223
- putString("query", query)
224
- });
225
- }
226
-
227
- override fun onGetRoot(
228
- clientPackageName: String,
229
- clientUid: Int,
230
- rootHints: Bundle?
231
- ): BrowserRoot {
232
- if (clientPackageName == "com.google.android.projection.gearhead") {
233
- val currentReactContext = if (bridgelessEnabled) reactHost.currentReactContext else reactNativeHost.reactInstanceManager.currentReactContext
234
-
235
- if (currentReactContext == null) {
236
- if (bridgelessEnabled) { // new arch
237
- val reactHost: ReactHost = reactHost
238
- reactHost.addReactInstanceEventListener(
239
- object : ReactInstanceEventListener {
240
- override fun onReactContextInitialized(context: ReactContext) {
241
- invokeStartTask(context)
242
- reactHost.removeReactInstanceEventListener(this)
243
- }
244
- }
245
- )
246
- reactHost.start()
247
- } else { // old arch
248
- val reactInstanceManager =
249
- reactNativeHost.reactInstanceManager
250
- reactInstanceManager.addReactInstanceEventListener(object :
251
- @Suppress("DEPRECATION")
252
- ReactInstanceManager.ReactInstanceEventListener {
253
- override fun onReactContextInitialized(context: ReactContext) {
254
- invokeStartTask(context)
255
- reactInstanceManager.removeReactInstanceEventListener(this)
256
-
257
- autoConnectionDetector?.isCarConnected = true
258
-
259
- val params = Arguments.createMap()
260
- params.putBoolean("connected", true)
261
-
262
- context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
263
- ?.emit(
264
- "car-connection-update", params
265
- )
266
- }
267
- })
268
- reactInstanceManager.createReactContextInBackground()
269
- }
270
- } else {
271
- if (MusicModule.isAppOpen) {
272
- autoConnectionDetector?.isCarConnected = true
273
-
274
- val params = Arguments.createMap()
275
- params.putBoolean("connected", true)
276
-
277
- currentReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)?.emit(
278
- "car-connection-update", params
279
- )
280
- } else {
281
- if (bridgelessEnabled) { // new arch
282
- val reactHost: ReactHost = reactHost
283
- reactHost.destroy("track-player", null)
284
- reactHost.addReactInstanceEventListener(object :
285
- @Suppress("DEPRECATION")
286
- ReactInstanceEventListener {
287
- override fun onReactContextInitialized(context: ReactContext) {
288
- invokeStartTask(context)
289
- reactHost.removeReactInstanceEventListener(
290
- this
291
- )
292
-
293
- autoConnectionDetector?.isCarConnected = true
294
-
295
- val params = Arguments.createMap()
296
- params.putBoolean("connected", true)
297
-
298
- context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
299
- ?.emit(
300
- "car-connection-update", params
301
- )
302
- }
303
- })
304
- reactHost.start()
305
- } else { // old arch
306
- reactNativeHost.reactInstanceManager.destroy()
307
- reactNativeHost.reactInstanceManager.addReactInstanceEventListener(object :
308
- @Suppress("DEPRECATION")
309
- ReactInstanceManager.ReactInstanceEventListener {
310
- override fun onReactContextInitialized(context: ReactContext) {
311
- invokeStartTask(context)
312
- reactNativeHost.reactInstanceManager.removeReactInstanceEventListener(
313
- this
314
- )
315
-
316
- autoConnectionDetector?.isCarConnected = true
317
-
318
- val params = Arguments.createMap()
319
- params.putBoolean("connected", true)
320
-
321
- context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
322
- ?.emit(
323
- "car-connection-update", params
324
- )
325
- }
326
- })
327
- reactNativeHost.reactInstanceManager.createReactContextInBackground()
328
- }
329
- }
330
- }
331
- }
332
-
333
- val extras = Bundle()
334
-
335
- extras.putBoolean(
336
- MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true)
337
-
338
- return BrowserRoot("/", extras)
339
- }
340
-
341
- @MainThread
342
- fun add(track: Track) {
343
- add(listOf(track))
344
- }
345
-
346
- @MainThread
347
- fun add(tracks: List<Track>) {
348
- val items = tracks.map {
349
- val x = it
350
- x.toAudioItem()
351
- }
352
- player?.add(items)
353
- }
354
-
355
- @MainThread
356
- fun add(tracks: List<Track>, atIndex: Int) {
357
- if (player != null && (atIndex <= (player?.getQueueSize() ?: -1))) {
358
- val items = tracks.map {
359
- val x = it
360
- if (x.url.isEmpty()) {
361
- val rawId = R.raw.silent_5_seconds
362
- x.url = "android.resource://${applicationContext.packageName}/$rawId"
363
- x.duration = 10
364
- }
365
- x.toAudioItem()
366
- }
367
- player?.add(items, atIndex)
368
- }
369
- }
370
-
371
- @MainThread
372
- fun load(track: Track) {
373
- val audioItem = track.toAudioItem()
374
- player?.load(audioItem)
375
- }
376
-
377
- @MainThread
378
- fun move(fromIndex: Int, toIndex: Int) {
379
- player?.move(fromIndex, toIndex);
380
- }
381
-
382
- @MainThread
383
- fun remove(index: Int) {
384
- remove(listOf(index))
385
- }
386
-
387
- @MainThread
388
- fun remove(indexes: List<Int>) {
389
- player?.remove(indexes)
390
- }
391
-
392
- @MainThread
393
- fun clear() {
394
- player?.clear()
395
- }
396
-
397
- @MainThread
398
- fun play() {
399
- MusicModule.firstPlayDone = true
400
- player?.play()
401
- }
402
-
403
- @MainThread
404
- fun pause() {
405
- player?.pause()
406
- }
407
-
408
- @MainThread
409
- fun stop() {
410
- player?.stop()
411
- }
412
-
413
- @MainThread
414
- fun removeUpcomingTracks() {
415
- player?.removeUpcomingItems()
416
- }
417
-
418
- @MainThread
419
- fun removePreviousTracks() {
420
- player?.removePreviousItems()
421
- }
422
-
423
- @MainThread
424
- fun skip(index: Int) {
425
- player?.jumpToItem(index)
426
- }
427
-
428
- @MainThread
429
- fun skipToNext() {
430
- player?.next()
431
- }
432
-
433
- @MainThread
434
- fun skipToPrevious() {
435
- player?.previous()
436
- }
437
-
438
- @MainThread
439
- fun seekTo(seconds: Float) {
440
- player?.seek((seconds * 1000).toLong(), TimeUnit.MILLISECONDS)
441
- }
442
-
443
- @MainThread
444
- fun seekBy(offset: Float) {
445
- player?.seekBy((offset.toLong()), TimeUnit.SECONDS)
446
- }
447
-
448
- @MainThread
449
- fun retry() {
450
- player?.prepare()
451
- }
452
-
453
- @MainThread
454
- fun getCurrentTrackIndex(): Int {
455
- // return player?.currentIndex ?: 0
456
- return 0
457
- }
458
-
459
- @MainThread
460
- fun getRate(): Float {
461
- return player?.playbackSpeed ?: 1f
462
- }
463
-
464
- @MainThread
465
- fun setRate(value: Float) {
466
- if (player != null) {
467
- player!!.playbackSpeed = value
468
- }
469
- }
470
-
471
- @MainThread
472
- fun getRepeatMode(): RepeatMode {
473
- return player?.playerOptions?.repeatMode ?: RepeatMode.OFF
474
- }
475
-
476
- @MainThread
477
- fun setRepeatMode(value: RepeatMode) {
478
- if (player != null) {
479
- player!!.playerOptions.repeatMode = value
480
- }
481
- }
482
-
483
- @MainThread
484
- fun getVolume(): Float {
485
- return player?.volume ?: 0f
486
- }
487
-
488
- @MainThread
489
- fun setVolume(value: Float) {
490
- if (player != null) {
491
- player!!.volume = value
492
- }
493
- }
494
-
495
- @MainThread
496
- fun getDurationInSeconds(): Double {
497
- return ((player?.duration ?: 0) / 1000).toDouble()
498
- }
499
-
500
- @MainThread
501
- fun getPositionInSeconds(): Double {
502
- return ((player?.position ?: 0) / 1000).toDouble()
503
- }
504
-
505
- @MainThread
506
- fun getBufferedPositionInSeconds(): Double {
507
- return ((player?.bufferedPosition ?: 0) / 1000).toDouble()
508
- }
509
-
510
- @MainThread
511
- fun getPlayerStateBundle(state: AudioPlayerState): Bundle {
512
- val bundle = Bundle()
513
- bundle.putString(STATE_KEY, state.asLibState.state)
514
- if (state == AudioPlayerState.ERROR) {
515
- bundle.putBundle(ERROR_KEY, getPlaybackErrorBundle())
516
- }
517
- return bundle
518
- }
519
-
520
- @MainThread
521
- fun updateMetadataForTrack(index: Int, track: Track) {
522
- player?.replaceItem(index, track.toAudioItem())
523
- }
524
-
525
- @MainThread
526
- fun getPlayerQueueHead(): MediaSource? {
527
- return player?.getQueueHead()
528
- }
529
-
530
- // @MainThread
531
- // fun updateNowPlayingMetadata(track: Track) {
532
- // val audioItem = track.toAudioItem()
533
- // player.notificationManager.notificationMetadata = NotificationMetadata(audioItem?.title, audioItem?.artist, audioItem?.artwork, audioItem?.duration)
534
- // }
535
-
536
- @MainThread
537
- fun clearNotificationMetadata() {
538
- player?.notificationManager?.hideNotification()
539
- }
540
-
541
- //
542
- // FORCED CURRENT INDEX TO 0
543
- //
544
- private fun emitPlaybackTrackChangedEvents(
545
- // index: Int?,
546
- previousIndex: Int?,
547
- oldPosition: Double
548
- ) {
549
- if (player != null) {
550
- val a = Bundle()
551
- a.putDouble(POSITION_KEY, oldPosition)
552
- //if (index != null) {
553
- a.putInt(NEXT_TRACK_KEY, 0)
554
- //}
555
-
556
- if (previousIndex != null) {
557
- a.putInt(TRACK_KEY, previousIndex)
558
- }
559
-
560
- emit(MusicEvents.PLAYBACK_TRACK_CHANGED, a)
561
-
562
- val b = Bundle()
563
- b.putDouble("lastPosition", oldPosition)
564
- if (tracks.isNotEmpty()) {
565
- // b.putInt("index", player.currentIndex)
566
- // b.putBundle("track", tracks[player.currentIndex].originalItem)
567
- b.putInt("index", 0)
568
- b.putBundle("track", tracks[0].originalItem)
569
- if (previousIndex != null) {
570
- b.putInt("lastIndex", previousIndex)
571
- b.putBundle("lastTrack", tracks[previousIndex].originalItem)
572
- }
573
- }
574
- emit(MusicEvents.PLAYBACK_ACTIVE_TRACK_CHANGED, b)
575
- }
576
- }
577
-
578
- override fun onLoadChildren(
579
- parentMediaId: String,
580
- result: Result<List<MediaItem>>
581
- ) {
582
- try {
583
- val mediaIdParts = parentMediaId.split("-/-")
584
- val itemType = mediaIdParts.getOrNull(1)
585
-
586
- if (itemType == "empty") {
587
- result.sendResult(emptyList())
588
- }
589
-
590
- if (mediaTree.keys.contains(parentMediaId) || parentMediaId == "/" || parentMediaId.contains(
591
- "tab"
592
- )
593
- ) {
594
- result.sendResult(mediaTree[parentMediaId])
595
- } else if (parentMediaId != loadingChildrenParentMediaId) {
596
- loadingChildrenParentMediaId = parentMediaId
597
- emit(MusicEvents.BUTTON_BROWSE, Bundle().apply {
598
- putString("mediaId", parentMediaId)
599
- })
600
- result.sendResult(mediaTree["placeholder"])
601
- }
602
- } catch (_: Exception) {}
603
- }
604
-
605
- override fun onLoadItem(itemId: String, result: Result<MediaItem>) {}
606
-
607
- @SuppressLint("RestrictedApi")
608
- override fun onCreate() {
609
- super.onCreate()
610
-
611
- // Create a MediaSessionCompat
612
- // mediaSession = MediaSessionCompat(baseContext, PackageManagerCompat.LOG_TAG)
613
-
614
- // Enable callbacks from MediaButtons and TransportControls
615
- // @Suppress("DEPRECATION")
616
- // mediaSession!!.setFlags(
617
- // MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
618
- // MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
619
- // )
620
-
621
- // Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player
622
- // stateBuilder = PlaybackStateCompat.Builder()
623
- // .setActions(
624
- // PlaybackStateCompat.ACTION_SKIP_TO_NEXT
625
- // )
626
-
627
- // if (stateBuilder != null) {
628
- // mediaSession!!.setPlaybackState(stateBuilder!!.build())
629
- // }
630
-
631
- // MySessionCallback() has methods that handle callbacks from a media controller
632
- // mediaSession.setCallback(new MySessionCallback());
633
-
634
- // Set the session's token so that client activities can communicate with it.
635
-
636
- // remove comment if not using player
637
- //sessionToken = mediaSession!!.sessionToken
638
-
639
- //onStartForeground();
640
- if (manager == null) manager = MusicManager(this)
641
- @Suppress("DEPRECATION")
642
- if (handler == null) handler = Handler()
643
- val channel = Utils.getNotificationChannel(this as Context)
644
-
645
- // Sets the service to foreground with an empty notification
646
- try {
647
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
648
- startForeground(
649
- 1,
650
- NotificationCompat.Builder(this, channel).build(),
651
- ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
652
- )
653
- } else {
654
- startForeground(1, NotificationCompat.Builder(this, channel).build())
655
- }
656
- } catch (_: Exception) { }
657
- }
658
-
659
- override fun onCustomAction(action: String, extras: Bundle?, result: Result<Bundle>) {}
660
-
661
- /**
662
- * Workaround for the "Context.startForegroundService() did not then call Service.startForeground()"
663
- * within 5s" ANR and crash by creating an empty notification and stopping it right after. For more
664
- * information see https://github.com/doublesymmetry/react-native-track-player/issues/1666
665
- */
666
- private fun startAndStopEmptyNotificationToAvoidANR() {
667
- val notificationManager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
668
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
669
- notificationManager.createNotificationChannel(
670
- NotificationChannel("Playback", "Playback", NotificationManager.IMPORTANCE_LOW)
671
- )
672
- }
673
-
674
- val resId = applicationContext.resources.getIdentifier("track_player_logo", "drawable", applicationContext.packageName)
675
- val logo = if (resId != 0) resId else R.drawable.ic_play
676
- val notificationBuilder: NotificationCompat.Builder = NotificationCompat.Builder(
677
- this, "Playback"
678
- )
679
- .setPriority(NotificationCompat.PRIORITY_LOW)
680
- .setCategory(NotificationCompat.CATEGORY_SERVICE)
681
- .setSmallIcon(logo)
682
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
683
- notificationBuilder.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
684
- }
685
- val notification = notificationBuilder.build()
686
- startForeground(1, notification)
687
- @Suppress("DEPRECATION")
688
- stopForeground(true)
689
- }
690
-
691
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
692
-
693
- if (intent == null) {
694
- return START_NOT_STICKY
695
- }
696
-
697
- if (Intent.ACTION_MEDIA_BUTTON == intent.action) {
698
- onStartForeground()
699
-
700
- if (Build.VERSION.SDK_INT >= 33) {
701
- try {
702
- startAndStopEmptyNotificationToAvoidANR()
703
- } catch (_: java.lang.Exception) {}
704
- }
705
-
706
- @Suppress("DEPRECATION")
707
- val intentExtra: KeyEvent? = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
708
- if (intentExtra!!.keyCode == KEYCODE_MEDIA_STOP) {
709
- intentToStop = true
710
- startServiceOreoAndAbove()
711
- stopSelf()
712
- } else {
713
- intentToStop = false
714
- }
715
-
716
- if (manager != null) {
717
- MediaButtonReceiver.handleIntent(manager!!.metadata.session, intent)
718
- return START_NOT_STICKY
719
- }
720
- }
721
-
722
- if (manager == null) manager = MusicManager(this)
723
-
724
- @Suppress("DEPRECATION")
725
- if (handler == null) handler = Handler()
726
-
727
- super.onStartCommand(intent, flags, startId)
728
- return START_NOT_STICKY
729
- }
730
-
731
- private fun startServiceOreoAndAbove() {
732
- // Needed to prevent crash when dismissing notification
733
- // https://stackoverflow.com/questions/47609261/bound-service-crash-with-context-startforegroundservice-did-not-then-call-ser?rq=1
734
- if (Build.VERSION.SDK_INT >= 26) {
735
- val channelId = Utils.NOTIFICATION_CHANNEL
736
- val channelName = "Playback"
737
- val channel = NotificationChannel(
738
- channelId,
739
- channelName,
740
- NotificationManager.IMPORTANCE_DEFAULT
741
- )
742
- (getSystemService(NOTIFICATION_SERVICE) as NotificationManager).createNotificationChannel(
743
- channel
744
- )
745
- val resId = applicationContext.resources.getIdentifier("track_player_logo", "drawable", applicationContext.packageName)
746
- val logo = if (resId != 0) resId else R.drawable.ic_play
747
- val notification = NotificationCompat.Builder(this, channelId)
748
- .setCategory(Notification.CATEGORY_SERVICE).setSmallIcon(logo)
749
- .setPriority(
750
- NotificationCompat.PRIORITY_MIN
751
- ).build()
752
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
753
- startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
754
- } else {
755
- startForeground(1, notification)
756
- }
757
- }
758
- }
759
-
760
- override fun onDestroy() {
761
- super.onDestroy()
762
- if (manager != null) {
763
- manager!!.destroy(true)
764
- manager = null
765
- }
766
- }
767
-
768
- override fun onTaskRemoved(rootIntent: Intent) {
769
- super.onTaskRemoved(rootIntent)
770
- if (manager == null || manager!!.shouldStopWithApp()) {
771
- destroy(true)
772
- stopSelf()
773
- }
774
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
775
- stopForeground(STOP_FOREGROUND_REMOVE)
776
- } else {
777
- @Suppress("DEPRECATION")
778
- stopForeground(true)
779
- }
780
- }
781
-
782
- @MainThread
783
- fun setupPlayer(playerOptions: Bundle?) {
784
- if (player != null) {
785
- print("Player was initialized. Prevent re-initializing again")
786
- return
787
- }
788
-
789
- val bufferConfig = BufferConfig(
790
- playerOptions?.getDouble(MIN_BUFFER_KEY)?.toInt(),
791
- playerOptions?.getDouble(MAX_BUFFER_KEY)?.toInt(),
792
- playerOptions?.getDouble(PLAY_BUFFER_KEY)?.toInt(),
793
- playerOptions?.getDouble(BACK_BUFFER_KEY)?.toInt(),
794
- )
795
-
796
- val cacheConfig = CacheConfig(playerOptions?.getDouble(MAX_CACHE_SIZE_KEY)?.toLong())
797
- val playerConfig = PlayerConfig(
798
- interceptPlayerActionsTriggeredExternally = true,
799
- handleAudioBecomingNoisy = true,
800
- handleAudioFocus = true,
801
- audioContentType = AudioContentType.MUSIC
802
- )
803
-
804
- val automaticallyUpdateNotificationMetadata = playerOptions?.getBoolean(AUTO_UPDATE_METADATA, true) ?: true
805
- val mediaSessionCallback = object: AAMediaSessionCallBack {
806
- override fun handleCustomActions(action: String?, extras: Bundle?) {}
807
-
808
- override fun handlePlayFromMediaId(mediaId: String?, extras: Bundle?) {
809
- val emitBundle = extras ?: Bundle()
810
- emit(MusicEvents.BUTTON_PLAY_FROM_ID, emitBundle.apply {
811
- putString("mediaId", mediaId)
812
- })
813
- }
814
-
815
- override fun handlePlayFromSearch(query: String?, extras: Bundle?) {
816
- val emitBundle = extras ?: Bundle()
817
- emit(MusicEvents.BUTTON_PLAY_FROM_SEARCH, emitBundle.apply {
818
- putString("query", query)
819
- })
820
- }
821
-
822
- override fun handleSkipToQueueItem(id: Long) {
823
- val emitBundle = Bundle()
824
- emit(MusicEvents.BUTTON_PLAY_FROM_QUEUE, emitBundle.apply {
825
- putInt("index", id.toInt())
826
- })
827
- }
828
- }
829
- player = QueuedAudioPlayer(this@MusicService, playerConfig, bufferConfig, cacheConfig, mediaSessionCallback)
830
- if (MusicModule.isAndroidTv) {
831
- player!!.volume = 0f
832
- }
833
- player!!.automaticallyUpdateNotificationMetadata = automaticallyUpdateNotificationMetadata
834
- sessionToken = player!!.getMediaSessionToken()
835
-
836
- observeEvents()
837
- setupForegrounding()
838
- }
839
-
840
- private fun getPlaybackErrorBundle(): Bundle {
841
- val bundle = Bundle()
842
- val error = playbackError
843
- if (error?.message != null) {
844
- bundle.putString("message", error.message)
845
- }
846
- if (error?.code != null) {
847
- bundle.putString("code", "android-" + error.code)
848
- }
849
- return bundle
850
- }
851
-
852
- private fun emitQueueEndedEvent() {
853
- if (player != null) {
854
- val bundle = Bundle()
855
- bundle.putInt(TRACK_KEY, player!!.currentIndex)
856
- bundle.putDouble(POSITION_KEY, (player!!.position / 1000).toDouble())
857
- emit(MusicEvents.PLAYBACK_QUEUE_ENDED, bundle)
858
- }
859
- }
860
-
861
- private var capabilities: List<Capability> = emptyList()
862
- private var notificationCapabilities: List<Capability> = emptyList()
863
- private var compactCapabilities: List<Capability> = emptyList()
864
- private var progressUpdateJob: Job? = null
865
-
866
- private fun isCompact(capability: Capability): Boolean {
867
- return compactCapabilities.contains(capability)
868
- }
869
-
870
- private fun getPendingIntentFlags(): Int {
871
- return PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
872
- }
873
-
874
- private fun getIcon(options: Bundle, propertyName: String, defaultIcon: Int): Int {
875
- if (!options.containsKey(propertyName)) return defaultIcon
876
- val bundle = options.getBundle(propertyName) ?: return defaultIcon
877
- val helper = ResourceDrawableIdHelper.getInstance()
878
- val icon = helper.getResourceDrawableId(this, bundle.getString("uri"))
879
- return if (icon == 0) defaultIcon else icon
880
- }
881
-
882
- @MainThread
883
- fun updateOptions(options: Bundle) {
884
- latestOptions = options
885
- val androidOptions = options.getBundle(ANDROID_OPTIONS_KEY)
886
-
887
- ratingType = BundleUtils.getInt(options, "ratingType", RatingCompat.RATING_NONE)
888
-
889
- if (player != null) {
890
- player!!.playerOptions.alwaysPauseOnInterruption =
891
- androidOptions?.getBoolean(PAUSE_ON_INTERRUPTION_KEY) ?: false
892
- }
893
-
894
- capabilities = options.getIntegerArrayList("capabilities")?.map {
895
- Capability.entries[it] } ?: emptyList()
896
- notificationCapabilities = options.getIntegerArrayList("notificationCapabilities")?.map { Capability.entries[it] } ?: emptyList()
897
- compactCapabilities = options.getIntegerArrayList("compactCapabilities")?.map { Capability.entries[it] } ?: emptyList()
898
- val customActions = options.getStringArrayList(CUSTOM_ACTIONS_KEY)
899
- if (notificationCapabilities.isEmpty()) notificationCapabilities = capabilities
900
-
901
- fun customIcon(customAction: String): Int {
902
- return when (customAction) {
903
- "shuffle-on" -> R.mipmap.ic_shuffle_on_foreground
904
- "shuffle-off" -> R.mipmap.ic_shuffle_off_foreground
905
- "repeat-on" -> R.mipmap.ic_repeat_on_foreground
906
- "repeat-off" -> R.mipmap.ic_repeat_off_foreground
907
- "heart" -> R.mipmap.ic_heart_foreground
908
- "heart-outlined" -> R.mipmap.ic_heart_outlined_foreground
909
- "clock" -> R.mipmap.ic_clock_now_foreground
910
- "arrow-down-circle" -> R.mipmap.ic_arrow_down_circle_foreground
911
- "md-close" -> R.mipmap.ic_close_foreground
912
- else -> R.mipmap.ic_heart_outlined_foreground
913
- }
914
- }
915
-
916
- val buttonsList = mutableListOf<NotificationButton>()
917
-
918
- notificationCapabilities.forEach { capability ->
919
- when (capability) {
920
- Capability.PLAY, Capability.PAUSE -> {
921
- val playIcon = getIcon(options, "playIcon", R.drawable.ic_play)
922
- val pauseIcon = getIcon(options, "pauseIcon", R.drawable.ic_pause)
923
- buttonsList.addAll(listOf(PLAY_PAUSE(playIcon = playIcon, pauseIcon = pauseIcon)))
924
- }
925
- Capability.STOP -> {
926
- val stopIcon = getIcon(options, "stopIcon", R.drawable.ic_stop)
927
- buttonsList.addAll(listOf(STOP(icon = stopIcon)))
928
- }
929
- Capability.SKIP_TO_NEXT -> {
930
- val nextIcon = getIcon(options, "nextIcon", R.drawable.ic_next)
931
- buttonsList.addAll(listOf(NEXT(icon = nextIcon, isCompact = isCompact(capability))))
932
- }
933
- Capability.SKIP_TO_PREVIOUS -> {
934
- val previousIcon = getIcon(options, "previousIcon", R.drawable.ic_previous)
935
- buttonsList.addAll(listOf(PREVIOUS(icon = previousIcon, isCompact = isCompact(capability))))
936
- }
937
- // Capability.JUMP_FORWARD -> {
938
- // val forwardIcon = BundleUtils.getIconOrNull(this, options, "forwardIcon")
939
- // buttonsList.addAll(listOf(FORWARD(icon = forwardIcon, isCompact = isCompact(capability))))
940
- // }
941
- // Capability.JUMP_BACKWARD -> {
942
- // val backwardIcon = BundleUtils.getIconOrNull(this, options, "rewindIcon")
943
- // buttonsList.addAll(listOf(BACKWARD(icon = backwardIcon, isCompact = isCompact(capability))))
944
- // }
945
- Capability.SEEK_TO -> {
946
- buttonsList.addAll(listOf(SEEK_TO))
947
- }
948
- else -> {}
949
- }
950
- }
951
-
952
- if (customActions != null) {
953
- for (customAction in customActions) {
954
- val customIcon = customIcon(customAction)
955
- buttonsList.add(CUSTOM_ACTION(icon=customIcon, customAction = customAction, isCompact = false))
956
- }
957
- }
958
-
959
- val openAppIntent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
960
- // flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
961
- flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
962
- action = Intent.ACTION_VIEW
963
- }
964
-
965
- val accentColor = BundleUtils.getIntOrNull(options, "color")
966
- val resId = applicationContext.resources.getIdentifier("track_player_logo", "drawable", applicationContext.packageName)
967
- val smallIcon = if (resId != 0) resId else R.drawable.ic_play
968
- val pendingIntent = PendingIntent.getActivity(this, 0, openAppIntent, getPendingIntentFlags())
969
- val notificationConfig = NotificationConfig(buttonsList, accentColor, smallIcon, pendingIntent)
970
-
971
- // player.notificationManager.destroy()
972
- player?.notificationManager?.createNotification(notificationConfig)
973
-
974
- // setup progress update events if configured
975
- progressUpdateJob?.cancel()
976
- val updateInterval = BundleUtils.getIntOrNull(options, PROGRESS_UPDATE_EVENT_INTERVAL_KEY)
977
- if (updateInterval != null && updateInterval > 0) {
978
- progressUpdateJob = scope.launch {
979
- progressUpdateEventFlow(updateInterval.toDouble()).collect { emit(MusicEvents.PLAYBACK_PROGRESS_UPDATED, it) }
980
- }
981
- }
982
- }
983
-
984
- @MainThread
985
- private fun progressUpdateEventFlow(interval: Double) = flow {
986
- while (true) {
987
- if (player?.isPlaying == true) {
988
- val bundle = progressUpdateEvent()
989
- emit(bundle)
990
- }
991
-
992
- delay((interval * 1000).toLong())
993
- }
994
- }
995
-
996
- @MainThread
997
- private suspend fun progressUpdateEvent(): Bundle {
998
- return withContext(Dispatchers.Main) {
999
- player?.let {
1000
- Bundle().apply {
1001
- putDouble(POSITION_KEY, (it.position / 1000).toDouble())
1002
- putDouble(DURATION_KEY, (it.duration / 1000).toDouble())
1003
- putDouble(BUFFERED_POSITION_KEY, (it.bufferedPosition / 1000).toDouble())
1004
- putInt(TRACK_KEY, it.currentIndex)
1005
- }
1006
- } ?: Bundle()
1007
- }
1008
- }
1009
-
1010
-
1011
- @MainThread
1012
- private fun observeEvents() {
1013
- scope.launch {
1014
- event?.audioItemTransition?.collect {
1015
- if (it !is AudioItemTransitionReason.REPEAT && player != null) {
1016
- // emitPlaybackTrackChangedEvents(
1017
- // player.currentIndex,
1018
- // player.previousIndex,
1019
- // (it?.oldPosition ?: 0).toDouble()
1020
- // )
1021
- //
1022
- // FORCED CURRENT INDEX TO 0
1023
- //
1024
- emitPlaybackTrackChangedEvents(
1025
- player!!.previousIndex,
1026
- (it?.oldPosition ?: 0).toDouble()
1027
- )
1028
- }
1029
- }
1030
- }
1031
-
1032
- scope.launch {
1033
- event?.onAudioFocusChanged?.collect {
1034
- Bundle().apply {
1035
- putBoolean(IS_FOCUS_LOSS_PERMANENT_KEY, it.isFocusLostPermanently)
1036
- putBoolean(IS_PAUSED_KEY, it.isPaused)
1037
- emit(MusicEvents.BUTTON_DUCK, this)
1038
- }
1039
- }
1040
- }
1041
-
1042
-
1043
- scope.launch {
1044
- event?.onPlayerActionTriggeredExternally?.collect {
1045
- when (it) {
1046
- is MediaSessionCallback.RATING -> {
1047
- Bundle().apply {
1048
- setRating(this, "rating", it.rating)
1049
- emit(MusicEvents.BUTTON_SET_RATING, this)
1050
- }
1051
- }
1052
-
1053
- is MediaSessionCallback.SEEK -> {
1054
- Bundle().apply {
1055
- putDouble("position", (it.positionMs / 1000).toDouble())
1056
- emit(MusicEvents.BUTTON_SEEK_TO, this)
1057
- }
1058
- }
1059
-
1060
- MediaSessionCallback.PLAY -> emit(MusicEvents.BUTTON_PLAY)
1061
- MediaSessionCallback.PAUSE -> emit(MusicEvents.BUTTON_PAUSE)
1062
- MediaSessionCallback.NEXT -> emit(MusicEvents.BUTTON_SKIP_NEXT)
1063
- MediaSessionCallback.PREVIOUS -> emit(MusicEvents.BUTTON_SKIP_PREVIOUS)
1064
- MediaSessionCallback.STOP -> emit(MusicEvents.BUTTON_STOP)
1065
- MediaSessionCallback.FORWARD -> {
1066
- // Bundle().apply {
1067
- // val interval = latestOptions?.getDouble(FORWARD_JUMP_INTERVAL_KEY, DEFAULT_JUMP_INTERVAL) ?: DEFAULT_JUMP_INTERVAL
1068
- // putInt("interval", interval.toInt())
1069
- // emit(MusicEvents.BUTTON_JUMP_FORWARD, this)
1070
- // }
1071
- }
1072
-
1073
- MediaSessionCallback.REWIND -> {
1074
- // Bundle().apply {
1075
- // val interval = latestOptions?.getDouble(BACKWARD_JUMP_INTERVAL_KEY, DEFAULT_JUMP_INTERVAL) ?: DEFAULT_JUMP_INTERVAL
1076
- // putInt("interval", interval.toInt())
1077
- // emit(MusicEvents.BUTTON_JUMP_BACKWARD, this)
1078
- // }
1079
- }
1080
-
1081
- is MediaSessionCallback.CUSTOMACTION -> {
1082
- Bundle().apply {
1083
- if (it.customAction == "shuffle-on" || it.customAction == "shuffle-off") {
1084
- emit(MusicEvents.BUTTON_SHUFFLE, this)
1085
- } else if (it.customAction == "repeat-on" || it.customAction == "repeat-off") {
1086
- emit(MusicEvents.BUTTON_REPEAT, this)
1087
- } else if (it.customAction == "heart" || it.customAction == "heart-outlined" || it.customAction == "clock" || it.customAction == "arrow-down-circle" || it.customAction == "md-close") {
1088
- emit(MusicEvents.BUTTON_TRACK_STATUS, this)
1089
- }
1090
- }
1091
- }
1092
- }
1093
- }
1094
- }
1095
- }
1096
-
1097
- @Suppress("DEPRECATION")
1098
- fun isForegroundService(): Boolean {
1099
- val manager = baseContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
1100
- for (service in manager.getRunningServices(Int.MAX_VALUE)) {
1101
- if (MusicService::class.java.name == service.service.className) {
1102
- return service.foreground
1103
- }
1104
- }
1105
- return false
1106
- }
1107
-
1108
- private var stopForegroundGracePeriod: Int = DEFAULT_STOP_FOREGROUND_GRACE_PERIOD
1109
-
1110
- @MainThread
1111
- private fun setupForegrounding() {
1112
- // Implementation based on https://github.com/Automattic/pocket-casts-android/blob/ee8da0c095560ef64a82d3a31464491b8d713104/modules/services/repositories/src/main/java/au/com/shiftyjelly/pocketcasts/repositories/playback/PlaybackService.kt#L218
1113
- var notificationId: Int? = null
1114
- var notification: Notification? = null
1115
- var stopForegroundWhenNotOngoing = false
1116
- var removeNotificationWhenNotOngoing = false
1117
-
1118
- fun startForegroundIfNecessary() {
1119
- if (isForegroundService()) {
1120
- return
1121
- }
1122
- if (notification == null) {
1123
- return
1124
- }
1125
- try {
1126
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
1127
- startForeground(
1128
- notificationId!!,
1129
- notification!!,
1130
- ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
1131
- )
1132
- } else {
1133
- startForeground(notificationId!!, notification)
1134
- }
1135
- } catch (error: Exception) {
1136
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
1137
- error is ForegroundServiceStartNotAllowedException
1138
- ) {
1139
- emit(MusicEvents.PLAYER_ERROR, Bundle().apply {
1140
- putString("message", error.message)
1141
- putString("code", "android-foreground-service-start-not-allowed")
1142
- });
1143
- }
1144
- }
1145
- }
1146
-
1147
- scope.launch {
1148
- val BACKGROUNDABLE_STATES = listOf(
1149
- AudioPlayerState.IDLE,
1150
- AudioPlayerState.ENDED,
1151
- AudioPlayerState.STOPPED,
1152
- AudioPlayerState.ERROR,
1153
- AudioPlayerState.PAUSED
1154
- )
1155
- val REMOVABLE_STATES = listOf(
1156
- AudioPlayerState.IDLE,
1157
- AudioPlayerState.STOPPED,
1158
- AudioPlayerState.ERROR
1159
- )
1160
- val LOADING_STATES = listOf(
1161
- AudioPlayerState.LOADING,
1162
- AudioPlayerState.READY,
1163
- AudioPlayerState.BUFFERING
1164
- )
1165
- var stateCount = 0
1166
- event?.stateChange?.collect {
1167
- stateCount++
1168
- if (it in LOADING_STATES) return@collect;
1169
- // Skip initial idle state, since we are only interested when
1170
- // state becomes idle after not being idle
1171
- stopForegroundWhenNotOngoing = stateCount > 1 && it in BACKGROUNDABLE_STATES
1172
- removeNotificationWhenNotOngoing = stopForegroundWhenNotOngoing && it in REMOVABLE_STATES
1173
- }
1174
- }
1175
-
1176
- fun shouldStopForeground(): Boolean {
1177
- return stopForegroundWhenNotOngoing && (removeNotificationWhenNotOngoing || isForegroundService())
1178
- }
1179
-
1180
- scope.launch {
1181
- event?.notificationStateChange?.collect {
1182
- when (it) {
1183
- is NotificationState.POSTED -> {
1184
- notificationId = it.notificationId;
1185
- notification = it.notification;
1186
- if (it.ongoing) {
1187
- if (player?.playWhenReady == true) {
1188
- startForegroundIfNecessary()
1189
- }
1190
- } else if (shouldStopForeground()) {
1191
- // Allow the application a grace period to complete any actions
1192
- // that may necessitate keeping the service in a foreground state.
1193
- // For instance, queuing new media (e.g., related music) after the
1194
- // user's queue is complete. This prevents the service from potentially
1195
- // being immediately destroyed once the player finishes playing media.
1196
- scope.launch {
1197
- delay(stopForegroundGracePeriod.toLong() * 1000)
1198
- // if (shouldStopForeground()) {
1199
- // @Suppress("DEPRECATION")
1200
- // stopForeground(removeNotificationWhenNotOngoing)
1201
- // }
1202
- }
1203
- }
1204
- }
1205
-
1206
- else -> {}
1207
- }
1208
- }
1209
- }
1210
- }
1211
-
1212
- companion object {
1213
- const val EMPTY_NOTIFICATION_ID = 1
1214
- const val STATE_KEY = "state"
1215
- const val ERROR_KEY = "error"
1216
- const val EVENT_KEY = "event"
1217
- const val DATA_KEY = "data"
1218
- const val TRACK_KEY = "track"
1219
- const val NEXT_TRACK_KEY = "nextTrack"
1220
- const val POSITION_KEY = "position"
1221
- const val DURATION_KEY = "duration"
1222
- const val BUFFERED_POSITION_KEY = "buffered"
1223
-
1224
- const val TASK_KEY = "TrackPlayer"
1225
-
1226
- const val MIN_BUFFER_KEY = "minBuffer"
1227
- const val MAX_BUFFER_KEY = "maxBuffer"
1228
- const val PLAY_BUFFER_KEY = "playBuffer"
1229
- const val BACK_BUFFER_KEY = "backBuffer"
1230
-
1231
- const val FORWARD_JUMP_INTERVAL_KEY = "forwardJumpInterval"
1232
- const val BACKWARD_JUMP_INTERVAL_KEY = "backwardJumpInterval"
1233
- const val PROGRESS_UPDATE_EVENT_INTERVAL_KEY = "progressUpdateEventInterval"
1234
-
1235
- const val MAX_CACHE_SIZE_KEY = "maxCacheSize"
1236
-
1237
- const val ANDROID_OPTIONS_KEY = "android"
1238
-
1239
- const val STOPPING_APP_PAUSES_PLAYBACK_KEY = "stoppingAppPausesPlayback"
1240
- const val APP_KILLED_PLAYBACK_BEHAVIOR_KEY = "appKilledPlaybackBehavior"
1241
- const val STOP_FOREGROUND_GRACE_PERIOD_KEY = "stopForegroundGracePeriod"
1242
- const val PAUSE_ON_INTERRUPTION_KEY = "alwaysPauseOnInterruption"
1243
- const val AUTO_UPDATE_METADATA = "autoUpdateMetadata"
1244
- const val AUTO_HANDLE_INTERRUPTIONS = "autoHandleInterruptions"
1245
- const val ANDROID_AUDIO_CONTENT_TYPE = "androidAudioContentType"
1246
- const val IS_FOCUS_LOSS_PERMANENT_KEY = "permanent"
1247
- const val IS_PAUSED_KEY = "paused"
1248
-
1249
- const val DEFAULT_JUMP_INTERVAL = 15.0
1250
- const val DEFAULT_STOP_FOREGROUND_GRACE_PERIOD = 5
1251
-
1252
- const val CUSTOM_ACTIONS_KEY = "customActions"
1253
- }
1254
- }