react-native-mp3-player 1.0.0

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 (328) hide show
  1. package/LICENSE +205 -0
  2. package/README.md +88 -0
  3. package/android/build.gradle +114 -0
  4. package/android/proguard-rules.txt +0 -0
  5. package/android/src/main/AndroidManifest.xml +27 -0
  6. package/android/src/main/java/com/doublesymmetry/trackplayer/HeadlessJsMediaService.kt +199 -0
  7. package/android/src/main/java/com/doublesymmetry/trackplayer/TrackPlayer.kt +30 -0
  8. package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
  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/doublesymmetry/trackplayer/model/MetadataAdapter.kt +227 -0
  12. package/android/src/main/java/com/doublesymmetry/trackplayer/model/NowPlayingMetadata.kt +16 -0
  13. package/android/src/main/java/com/doublesymmetry/trackplayer/model/PlaybackMetadata.kt +203 -0
  14. package/android/src/main/java/com/doublesymmetry/trackplayer/model/State.kt +13 -0
  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/doublesymmetry/trackplayer/module/MusicEvents.kt +65 -0
  19. package/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt +775 -0
  20. package/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt +1251 -0
  21. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/AppForegroundTracker.kt +35 -0
  22. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/BundleUtils.kt +147 -0
  23. package/android/src/main/java/com/doublesymmetry/trackplayer/utils/CoilBitmapLoader.kt +64 -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/lovegaoshi/kotlinaudio/event/EventHolder.kt +30 -0
  27. package/android/src/main/java/com/lovegaoshi/kotlinaudio/event/PlayerEventHolder.kt +124 -0
  28. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioContentType.kt +10 -0
  29. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItem.kt +133 -0
  30. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
  31. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioPlayerState.kt +30 -0
  32. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/BufferConfig.kt +8 -0
  33. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CacheConfig.kt +17 -0
  34. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/Capability.kt +19 -0
  35. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CustomButton.kt +19 -0
  36. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/FocusChangeData.kt +3 -0
  37. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/MediaSessionCallback.kt +17 -0
  38. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayWhenReadyChangeData.kt +3 -0
  39. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
  40. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlaybackError.kt +6 -0
  41. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerConfig.kt +36 -0
  42. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerOptions.kt +39 -0
  43. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PositionChangedReason.kt +39 -0
  44. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/RepeatMode.kt +16 -0
  45. package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/WakeMode.kt +7 -0
  46. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/AudioPlayer.kt +689 -0
  47. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/ForwardingPlayer.java +1124 -0
  48. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/QueuedAudioPlayer.kt +295 -0
  49. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Buffer.kt +34 -0
  50. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Cache.kt +47 -0
  51. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/FocusManager.kt +59 -0
  52. package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/MediaFactory.kt +165 -0
  53. package/android/src/main/java/com/lovegaoshi/kotlinaudio/service/MusicService.kt +127 -0
  54. package/android/src/main/java/com/lovegaoshi/kotlinaudio/utils/Utils.kt +113 -0
  55. package/android/src/main/res/drawable/baseline_repeat_24.xml +5 -0
  56. package/android/src/main/res/drawable/baseline_repeat_one_24.xml +5 -0
  57. package/android/src/main/res/drawable/forward.xml +5 -0
  58. package/android/src/main/res/drawable/heart_24px.xml +5 -0
  59. package/android/src/main/res/drawable/hearte_24px.xml +5 -0
  60. package/android/src/main/res/drawable/ifl_24px.xml +5 -0
  61. package/android/src/main/res/drawable/rewind.xml +5 -0
  62. package/android/src/main/res/drawable/shuffle_24px.xml +5 -0
  63. package/android/src/main/res/values/strings.xml +5 -0
  64. package/android/src/main/res/xml/automotive_app_desc.xml +3 -0
  65. package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/22AMillion.jpg +0 -0
  66. package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/Contents.json +21 -0
  67. package/ios/Example/SwiftAudio/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  68. package/ios/Example/SwiftAudio/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
  69. package/ios/Example/SwiftAudio/Assets.xcassets/Contents.json +6 -0
  70. package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/Contents.json +21 -0
  71. package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/cover.jpg +0 -0
  72. package/ios/Example/SwiftAudio/AudioController.swift +46 -0
  73. package/ios/Example/SwiftAudio/Extensions.swift +22 -0
  74. package/ios/Example/SwiftAudio/PlayerView.swift +172 -0
  75. package/ios/Example/SwiftAudio/PlayerViewModel.swift +120 -0
  76. package/ios/Example/SwiftAudio/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
  77. package/ios/Example/SwiftAudio/QueueView.swift +65 -0
  78. package/ios/Example/SwiftAudio/SwiftAudio.entitlements +12 -0
  79. package/ios/Example/SwiftAudio/SwiftAudioApp.swift +17 -0
  80. package/ios/Example/SwiftAudio.xcodeproj/project.pbxproj +412 -0
  81. package/ios/Example/SwiftAudio.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  82. package/ios/Example/SwiftAudio.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  83. package/ios/RNTrackPlayer/Models/Capabilities.swift +52 -0
  84. package/ios/RNTrackPlayer/Models/MediaURL.swift +38 -0
  85. package/ios/RNTrackPlayer/Models/MetadataAdapter.swift +147 -0
  86. package/ios/RNTrackPlayer/Models/PitchAlgorithms.swift +13 -0
  87. package/ios/RNTrackPlayer/Models/SessionCategories.swift +106 -0
  88. package/ios/RNTrackPlayer/Models/State.swift +26 -0
  89. package/ios/RNTrackPlayer/Models/Track.swift +140 -0
  90. package/ios/RNTrackPlayer/RNTrackPlayer.swift +941 -0
  91. package/ios/RNTrackPlayer/Support/RNTrackPlayer-Bridging-Header.h +7 -0
  92. package/ios/RNTrackPlayer/TrackPlayer.h +14 -0
  93. package/ios/RNTrackPlayer/TrackPlayer.mm +246 -0
  94. package/ios/RNTrackPlayer/Utils/EventType.swift +44 -0
  95. package/ios/RNTrackPlayer/Utils/Metadata.swift +60 -0
  96. package/ios/SwiftAudioEx/Package.swift +20 -0
  97. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapper.swift +521 -0
  98. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperDelegate.swift +27 -0
  99. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperProtocol.swift +69 -0
  100. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperState.swift +43 -0
  101. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioItem.swift +158 -0
  102. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayer.swift +459 -0
  103. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayerError.swift +26 -0
  104. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSession.swift +33 -0
  105. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSessionController.swift +135 -0
  106. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioTap.swift +99 -0
  107. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Event.swift +155 -0
  108. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/MediaItemProperty.swift +95 -0
  109. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoCenter.swift +17 -0
  110. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoController.swift +73 -0
  111. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoControllerProtocol.swift +26 -0
  112. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoKeyValue.swift +14 -0
  113. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoProperty.swift +234 -0
  114. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemNotificationObserver.swift +102 -0
  115. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemObserver.swift +136 -0
  116. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerObserver.swift +120 -0
  117. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerTimeObserver.swift +112 -0
  118. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueueManager.swift +356 -0
  119. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueuedAudioPlayer.swift +236 -0
  120. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommand.swift +170 -0
  121. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommandController.swift +206 -0
  122. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RepeatMode.swift +15 -0
  123. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/TimeEventFrequency.swift +26 -0
  124. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Utils/DispatchQueueType.swift +18 -0
  125. package/ios/SwiftAudioEx/Sources/SwiftAudioEx/WaveformAudioTap.swift +159 -0
  126. package/lib/specs/NativeTrackPlayer.d.ts +129 -0
  127. package/lib/specs/NativeTrackPlayer.js +4 -0
  128. package/lib/src/constants/AndroidAudioContentType.d.ts +35 -0
  129. package/lib/src/constants/AndroidAudioContentType.js +36 -0
  130. package/lib/src/constants/AndroidAutoContentStyle.d.ts +10 -0
  131. package/lib/src/constants/AndroidAutoContentStyle.js +11 -0
  132. package/lib/src/constants/AppKilledPlaybackBehavior.d.ts +17 -0
  133. package/lib/src/constants/AppKilledPlaybackBehavior.js +18 -0
  134. package/lib/src/constants/Capability.d.ts +17 -0
  135. package/lib/src/constants/Capability.js +19 -0
  136. package/lib/src/constants/Event.d.ts +163 -0
  137. package/lib/src/constants/Event.js +164 -0
  138. package/lib/src/constants/IOSCategory.d.ts +36 -0
  139. package/lib/src/constants/IOSCategory.js +37 -0
  140. package/lib/src/constants/IOSCategoryMode.d.ts +47 -0
  141. package/lib/src/constants/IOSCategoryMode.js +48 -0
  142. package/lib/src/constants/IOSCategoryOptions.d.ts +44 -0
  143. package/lib/src/constants/IOSCategoryOptions.js +45 -0
  144. package/lib/src/constants/MediaItemPlayable.d.ts +4 -0
  145. package/lib/src/constants/MediaItemPlayable.js +5 -0
  146. package/lib/src/constants/PitchAlgorithm.d.ts +14 -0
  147. package/lib/src/constants/PitchAlgorithm.js +16 -0
  148. package/lib/src/constants/RatingType.d.ts +8 -0
  149. package/lib/src/constants/RatingType.js +10 -0
  150. package/lib/src/constants/RepeatMode.d.ts +8 -0
  151. package/lib/src/constants/RepeatMode.js +10 -0
  152. package/lib/src/constants/State.d.ts +34 -0
  153. package/lib/src/constants/State.js +35 -0
  154. package/lib/src/constants/TrackType.d.ts +6 -0
  155. package/lib/src/constants/TrackType.js +7 -0
  156. package/lib/src/constants/index.d.ts +14 -0
  157. package/lib/src/constants/index.js +14 -0
  158. package/lib/src/hooks/index.d.ts +6 -0
  159. package/lib/src/hooks/index.js +6 -0
  160. package/lib/src/hooks/useActiveTrack.d.ts +2 -0
  161. package/lib/src/hooks/useActiveTrack.js +28 -0
  162. package/lib/src/hooks/useAppIsInBackground.d.ts +1 -0
  163. package/lib/src/hooks/useAppIsInBackground.js +16 -0
  164. package/lib/src/hooks/useIsPlaying.d.ts +35 -0
  165. package/lib/src/hooks/useIsPlaying.js +50 -0
  166. package/lib/src/hooks/usePlayWhenReady.d.ts +1 -0
  167. package/lib/src/hooks/usePlayWhenReady.js +27 -0
  168. package/lib/src/hooks/usePlaybackState.d.ts +10 -0
  169. package/lib/src/hooks/usePlaybackState.js +35 -0
  170. package/lib/src/hooks/useProgress.d.ts +7 -0
  171. package/lib/src/hooks/useProgress.js +55 -0
  172. package/lib/src/hooks/useTrackPlayerEvents.d.ts +8 -0
  173. package/lib/src/hooks/useTrackPlayerEvents.js +30 -0
  174. package/lib/src/index.d.ts +5 -0
  175. package/lib/src/index.js +5 -0
  176. package/lib/src/interfaces/AndroidAutoBrowseTree.d.ts +5 -0
  177. package/lib/src/interfaces/AndroidAutoBrowseTree.js +1 -0
  178. package/lib/src/interfaces/AndroidOptions.d.ts +41 -0
  179. package/lib/src/interfaces/AndroidOptions.js +1 -0
  180. package/lib/src/interfaces/CustomButtons.d.ts +5 -0
  181. package/lib/src/interfaces/CustomButtons.js +1 -0
  182. package/lib/src/interfaces/FeedbackOptions.d.ts +6 -0
  183. package/lib/src/interfaces/FeedbackOptions.js +1 -0
  184. package/lib/src/interfaces/MediaItem.d.ts +18 -0
  185. package/lib/src/interfaces/MediaItem.js +1 -0
  186. package/lib/src/interfaces/MetadataOptions.d.ts +3 -0
  187. package/lib/src/interfaces/MetadataOptions.js +1 -0
  188. package/lib/src/interfaces/NowPlayingMetadata.d.ts +4 -0
  189. package/lib/src/interfaces/NowPlayingMetadata.js +1 -0
  190. package/lib/src/interfaces/PlaybackState.d.ts +8 -0
  191. package/lib/src/interfaces/PlaybackState.js +1 -0
  192. package/lib/src/interfaces/PlayerOptions.d.ts +127 -0
  193. package/lib/src/interfaces/PlayerOptions.js +1 -0
  194. package/lib/src/interfaces/Progress.d.ts +15 -0
  195. package/lib/src/interfaces/Progress.js +1 -0
  196. package/lib/src/interfaces/ResourceObject.d.ts +1 -0
  197. package/lib/src/interfaces/ResourceObject.js +1 -0
  198. package/lib/src/interfaces/ServiceHandler.d.ts +1 -0
  199. package/lib/src/interfaces/ServiceHandler.js +1 -0
  200. package/lib/src/interfaces/Track.d.ts +21 -0
  201. package/lib/src/interfaces/Track.js +1 -0
  202. package/lib/src/interfaces/TrackMetadataBase.d.ts +28 -0
  203. package/lib/src/interfaces/TrackMetadataBase.js +1 -0
  204. package/lib/src/interfaces/UpdateOptions.d.ts +52 -0
  205. package/lib/src/interfaces/UpdateOptions.js +1 -0
  206. package/lib/src/interfaces/events/AudioMetadataReceivedEvent.d.ts +33 -0
  207. package/lib/src/interfaces/events/AudioMetadataReceivedEvent.js +1 -0
  208. package/lib/src/interfaces/events/ControllerConnectedEvent.d.ts +8 -0
  209. package/lib/src/interfaces/events/ControllerConnectedEvent.js +1 -0
  210. package/lib/src/interfaces/events/EventPayloadByEvent.d.ts +73 -0
  211. package/lib/src/interfaces/events/EventPayloadByEvent.js +1 -0
  212. package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.d.ts +24 -0
  213. package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.js +1 -0
  214. package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.d.ts +4 -0
  215. package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.js +1 -0
  216. package/lib/src/interfaces/events/PlaybackErrorEvent.d.ts +6 -0
  217. package/lib/src/interfaces/events/PlaybackErrorEvent.js +1 -0
  218. package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.d.ts +16 -0
  219. package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.js +1 -0
  220. package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.d.ts +4 -0
  221. package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.js +1 -0
  222. package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.d.ts +4 -0
  223. package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.js +1 -0
  224. package/lib/src/interfaces/events/PlaybackQueueEndedEvent.d.ts +9 -0
  225. package/lib/src/interfaces/events/PlaybackQueueEndedEvent.js +1 -0
  226. package/lib/src/interfaces/events/PlaybackResumeEvent.d.ts +3 -0
  227. package/lib/src/interfaces/events/PlaybackResumeEvent.js +1 -0
  228. package/lib/src/interfaces/events/PlaybackTrackChangedEvent.d.ts +11 -0
  229. package/lib/src/interfaces/events/PlaybackTrackChangedEvent.js +1 -0
  230. package/lib/src/interfaces/events/PlayerErrorEvent.d.ts +6 -0
  231. package/lib/src/interfaces/events/PlayerErrorEvent.js +1 -0
  232. package/lib/src/interfaces/events/RemoteBrowseEvent.d.ts +4 -0
  233. package/lib/src/interfaces/events/RemoteBrowseEvent.js +1 -0
  234. package/lib/src/interfaces/events/RemoteCustomActionEvent.d.ts +7 -0
  235. package/lib/src/interfaces/events/RemoteCustomActionEvent.js +1 -0
  236. package/lib/src/interfaces/events/RemoteDuckEvent.d.ts +13 -0
  237. package/lib/src/interfaces/events/RemoteDuckEvent.js +1 -0
  238. package/lib/src/interfaces/events/RemoteJumpBackwardEvent.d.ts +8 -0
  239. package/lib/src/interfaces/events/RemoteJumpBackwardEvent.js +1 -0
  240. package/lib/src/interfaces/events/RemoteJumpForwardEvent.d.ts +8 -0
  241. package/lib/src/interfaces/events/RemoteJumpForwardEvent.js +1 -0
  242. package/lib/src/interfaces/events/RemotePlayIdEvent.d.ts +4 -0
  243. package/lib/src/interfaces/events/RemotePlayIdEvent.js +1 -0
  244. package/lib/src/interfaces/events/RemotePlaySearchEvent.d.ts +9 -0
  245. package/lib/src/interfaces/events/RemotePlaySearchEvent.js +1 -0
  246. package/lib/src/interfaces/events/RemoteSeekEvent.d.ts +4 -0
  247. package/lib/src/interfaces/events/RemoteSeekEvent.js +1 -0
  248. package/lib/src/interfaces/events/RemoteSetRatingEvent.d.ts +4 -0
  249. package/lib/src/interfaces/events/RemoteSetRatingEvent.js +1 -0
  250. package/lib/src/interfaces/events/RemoteSkipEvent.d.ts +3 -0
  251. package/lib/src/interfaces/events/RemoteSkipEvent.js +1 -0
  252. package/lib/src/interfaces/events/index.d.ts +18 -0
  253. package/lib/src/interfaces/events/index.js +18 -0
  254. package/lib/src/interfaces/index.d.ts +15 -0
  255. package/lib/src/interfaces/index.js +15 -0
  256. package/lib/src/resolveAssetSource.d.ts +2 -0
  257. package/lib/src/resolveAssetSource.js +3 -0
  258. package/lib/src/trackPlayer.d.ts +347 -0
  259. package/lib/src/trackPlayer.js +592 -0
  260. package/package.json +94 -0
  261. package/react-native-mp3-player.podspec +22 -0
  262. package/specs/NativeTrackPlayer.ts +148 -0
  263. package/src/constants/AndroidAudioContentType.ts +35 -0
  264. package/src/constants/AndroidAutoContentStyle.ts +10 -0
  265. package/src/constants/AppKilledPlaybackBehavior.ts +19 -0
  266. package/src/constants/Capability.ts +19 -0
  267. package/src/constants/Event.ts +164 -0
  268. package/src/constants/IOSCategory.ts +36 -0
  269. package/src/constants/IOSCategoryMode.ts +47 -0
  270. package/src/constants/IOSCategoryOptions.ts +44 -0
  271. package/src/constants/MediaItemPlayable.ts +4 -0
  272. package/src/constants/PitchAlgorithm.ts +16 -0
  273. package/src/constants/RatingType.ts +10 -0
  274. package/src/constants/RepeatMode.ts +10 -0
  275. package/src/constants/State.ts +34 -0
  276. package/src/constants/TrackType.ts +6 -0
  277. package/src/constants/index.ts +14 -0
  278. package/src/hooks/index.ts +6 -0
  279. package/src/hooks/useActiveTrack.ts +36 -0
  280. package/src/hooks/useAppIsInBackground.ts +20 -0
  281. package/src/hooks/useIsPlaying.ts +56 -0
  282. package/src/hooks/usePlayWhenReady.ts +37 -0
  283. package/src/hooks/usePlaybackState.ts +45 -0
  284. package/src/hooks/useProgress.ts +64 -0
  285. package/src/hooks/useTrackPlayerEvents.ts +48 -0
  286. package/src/index.ts +7 -0
  287. package/src/interfaces/AndroidAutoBrowseTree.ts +6 -0
  288. package/src/interfaces/AndroidOptions.ts +48 -0
  289. package/src/interfaces/CustomButtons.ts +6 -0
  290. package/src/interfaces/FeedbackOptions.ts +7 -0
  291. package/src/interfaces/MediaItem.ts +19 -0
  292. package/src/interfaces/MetadataOptions.ts +4 -0
  293. package/src/interfaces/NowPlayingMetadata.ts +5 -0
  294. package/src/interfaces/PlaybackState.ts +11 -0
  295. package/src/interfaces/PlayerOptions.ts +133 -0
  296. package/src/interfaces/Progress.ts +15 -0
  297. package/src/interfaces/ResourceObject.ts +1 -0
  298. package/src/interfaces/ServiceHandler.ts +1 -0
  299. package/src/interfaces/Track.ts +23 -0
  300. package/src/interfaces/TrackMetadataBase.ts +29 -0
  301. package/src/interfaces/UpdateOptions.ts +59 -0
  302. package/src/interfaces/events/AudioMetadataReceivedEvent.ts +37 -0
  303. package/src/interfaces/events/ControllerConnectedEvent.ts +9 -0
  304. package/src/interfaces/events/EventPayloadByEvent.ts +76 -0
  305. package/src/interfaces/events/PlaybackActiveTrackChangedEvent.ts +29 -0
  306. package/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.ts +4 -0
  307. package/src/interfaces/events/PlaybackErrorEvent.ts +6 -0
  308. package/src/interfaces/events/PlaybackMetadataReceivedEvent.ts +16 -0
  309. package/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.ts +4 -0
  310. package/src/interfaces/events/PlaybackProgressUpdatedEvent.ts +5 -0
  311. package/src/interfaces/events/PlaybackQueueEndedEvent.ts +9 -0
  312. package/src/interfaces/events/PlaybackResumeEvent.ts +5 -0
  313. package/src/interfaces/events/PlaybackTrackChangedEvent.ts +11 -0
  314. package/src/interfaces/events/PlayerErrorEvent.ts +6 -0
  315. package/src/interfaces/events/RemoteBrowseEvent.ts +4 -0
  316. package/src/interfaces/events/RemoteCustomActionEvent.ts +7 -0
  317. package/src/interfaces/events/RemoteDuckEvent.ts +13 -0
  318. package/src/interfaces/events/RemoteJumpBackwardEvent.ts +8 -0
  319. package/src/interfaces/events/RemoteJumpForwardEvent.ts +8 -0
  320. package/src/interfaces/events/RemotePlayIdEvent.ts +4 -0
  321. package/src/interfaces/events/RemotePlaySearchEvent.ts +21 -0
  322. package/src/interfaces/events/RemoteSeekEvent.ts +4 -0
  323. package/src/interfaces/events/RemoteSetRatingEvent.ts +5 -0
  324. package/src/interfaces/events/RemoteSkipEvent.ts +3 -0
  325. package/src/interfaces/events/index.ts +18 -0
  326. package/src/interfaces/index.ts +15 -0
  327. package/src/resolveAssetSource.ts +3 -0
  328. package/src/trackPlayer.ts +768 -0
@@ -0,0 +1,127 @@
1
+ @file: OptIn(UnstableApi::class) package com.lovegaoshi.kotlinaudio.service
2
+
3
+ import android.content.Intent
4
+ import android.os.Binder
5
+ import android.os.Bundle
6
+ import android.os.IBinder
7
+ import androidx.annotation.OptIn
8
+ import androidx.media3.common.util.UnstableApi
9
+ import androidx.media3.session.MediaLibraryService
10
+ import androidx.media3.session.MediaSession
11
+ import androidx.media3.session.SessionCommand
12
+ import androidx.media3.session.SessionResult
13
+ import com.google.common.util.concurrent.ListenableFuture
14
+ import com.lovegaoshi.kotlinaudio.models.CustomButton
15
+ import com.lovegaoshi.kotlinaudio.models.PlayerOptions
16
+ import com.lovegaoshi.kotlinaudio.player.QueuedAudioPlayer
17
+ import timber.log.Timber
18
+
19
+ class MusicService : MediaLibraryService() {
20
+ private val binder = MusicBinder()
21
+ lateinit var player: QueuedAudioPlayer
22
+ private lateinit var mediaSession: MediaLibrarySession
23
+
24
+ override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession =
25
+ mediaSession
26
+
27
+ // Create your player and media session in the onCreate lifecycle event
28
+ override fun onCreate() {
29
+ super.onCreate()
30
+ // Service is immediately set up for the KA example.
31
+ setupService(listOf(
32
+ CustomButton(displayName = CROSSFADE_PREV_PREPARE),
33
+ CustomButton(displayName = CROSSFADE_PREV),
34
+ CustomButton(displayName = CROSSFADE_NEXT_PREPARE),
35
+ CustomButton(displayName = CROSSFADE_NEXT),
36
+ ))
37
+ // setMediaNotificationProvider()
38
+ }
39
+
40
+ private fun setupService(customActions: List<CustomButton> = arrayListOf()) {
41
+
42
+ player = QueuedAudioPlayer(this, PlayerOptions(crossfade = true, nativeExample = true))
43
+ mediaSession = MediaLibrarySession
44
+ .Builder(this, player.player, CustomMediaSessionCallback(customActions))
45
+ .setCustomLayout(customActions.filter { v -> v.onLayout }.map{ v -> v.commandButton})
46
+ .setId("APM")
47
+ .build()
48
+ }
49
+
50
+ // The user dismissed the app from the recent tasks
51
+ override fun onTaskRemoved(rootIntent: Intent?) {
52
+ val player = mediaSession.player
53
+ if (!player.playWhenReady || player.mediaItemCount == 0) {
54
+ // Stop the service if not playing, continue playing in the background
55
+ // otherwise.
56
+ stopSelf()
57
+ }
58
+ }
59
+
60
+ // Remember to release the player and media session in onDestroy
61
+ override fun onDestroy() {
62
+ mediaSession.run {
63
+ player.release()
64
+ release()
65
+ mediaSession.release()
66
+ }
67
+ super.onDestroy()
68
+ }
69
+
70
+ @UnstableApi private inner class CustomMediaSessionCallback(
71
+ val customActions: List<CustomButton>
72
+ ) : MediaLibrarySession.Callback {
73
+
74
+ override fun onCustomCommand(
75
+ session: MediaSession,
76
+ controller: MediaSession.ControllerInfo,
77
+ customCommand: SessionCommand,
78
+ args: Bundle
79
+ ): ListenableFuture<SessionResult> {
80
+ Timber.tag("APM").d("custom command triggered: ${customCommand.customAction}")
81
+ when (customCommand.customAction) {
82
+ CROSSFADE_PREV_PREPARE -> { player.crossFadePrepare(true) }
83
+ CROSSFADE_PREV -> { player.switchExoPlayer({ player.previous() }) }
84
+ CROSSFADE_NEXT_PREPARE -> { player.crossFadePrepare() }
85
+ CROSSFADE_NEXT -> {
86
+ player.switchExoPlayer()
87
+ mediaSession.player = player.player
88
+ this@MusicService.onUpdateNotification(mediaSession, true)
89
+ }
90
+ }
91
+ return super.onCustomCommand(session, controller, customCommand, args)
92
+ }
93
+
94
+ // Configure commands available to the controller in onConnect()
95
+ override fun onConnect(
96
+ session: MediaSession,
97
+ controller: MediaSession.ControllerInfo
98
+ ): MediaSession.ConnectionResult {
99
+ val sessionCommands = MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
100
+ customActions.forEach{
101
+ v -> v.commandButton.sessionCommand?.let { sessionCommands.add(it) }
102
+ }
103
+ return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
104
+ .setAvailableSessionCommands(sessionCommands.build())
105
+ .setAvailablePlayerCommands(MediaSession.ConnectionResult.DEFAULT_PLAYER_COMMANDS)
106
+ .build()
107
+ }
108
+ }
109
+
110
+ inner class MusicBinder : Binder() {
111
+ val service = this@MusicService
112
+ }
113
+
114
+ override fun onBind(intent: Intent?): IBinder? {
115
+ val intentAction = intent?.action
116
+ return if (intentAction != null) {
117
+ super.onBind(intent)
118
+ } else {
119
+ binder
120
+ }
121
+ }
122
+ }
123
+
124
+ const val CROSSFADE_PREV_PREPARE = "crossfade prev prepare"
125
+ const val CROSSFADE_PREV = "crossfade prev"
126
+ const val CROSSFADE_NEXT_PREPARE = "crossfade next prepare"
127
+ const val CROSSFADE_NEXT = "crossfade next"
@@ -0,0 +1,113 @@
1
+ package com.lovegaoshi.kotlinaudio.utils
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.ContentResolver
5
+ import android.content.ContentUris
6
+ import android.content.ContentValues
7
+ import android.graphics.Bitmap
8
+ import android.graphics.BitmapFactory
9
+ import android.media.MediaMetadataRetriever
10
+ import android.net.Uri
11
+ import android.os.Build
12
+ import android.os.Environment
13
+ import android.provider.MediaStore
14
+ import androidx.annotation.RequiresApi
15
+ import java.io.OutputStream
16
+
17
+ fun isUriLocalFile(uri: Uri?): Boolean {
18
+ if (uri == null) return false
19
+ val scheme = uri.scheme
20
+ val host = uri.host
21
+ if((scheme == "http" || scheme == "https") && (host == "localhost" || host == "127.0.0.1" || host == "[::1]"))
22
+ {
23
+ return false
24
+ }
25
+ return scheme == null
26
+ || scheme == ContentResolver.SCHEME_FILE
27
+ || scheme == ContentResolver.SCHEME_ANDROID_RESOURCE
28
+ || scheme == ContentResolver.SCHEME_CONTENT
29
+ || scheme == "res" || host == null
30
+ }
31
+
32
+ const val bitmapCoverFileName = "APMCover.png"
33
+ val bitmapCoverDir = "${Environment.DIRECTORY_PICTURES}/APMCache/"
34
+
35
+
36
+ @RequiresApi(Build.VERSION_CODES.R)
37
+ @SuppressLint("Range")
38
+ fun findAPMCacheApi(contentResolver: ContentResolver, contentUri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI): Uri? {
39
+ val selection = "${MediaStore.MediaColumns.RELATIVE_PATH}=?"
40
+ val selectionArgs = arrayOf(bitmapCoverDir)
41
+ val cursor = contentResolver.query(contentUri, null, selection,selectionArgs,null)
42
+ if (cursor != null && cursor.count > 0) {
43
+ while (cursor.moveToNext()) {
44
+ val filename = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME))
45
+ if (filename == bitmapCoverFileName) {
46
+ val id = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns._ID))
47
+ cursor.close()
48
+ return ContentUris.withAppendedId(contentUri, id)
49
+ }
50
+ }
51
+ cursor.close()
52
+ }
53
+ return null
54
+ }
55
+
56
+ @RequiresApi(Build.VERSION_CODES.R)
57
+ fun getAPMCacheBitmapUri(contentResolver: ContentResolver, contentValues: ContentValues): Uri? {
58
+ val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
59
+ val mAPMUri = findAPMCacheApi(contentResolver, contentUri)
60
+ if (mAPMUri != null ) contentResolver.delete(mAPMUri, null)
61
+ return contentResolver.insert(contentUri, contentValues)
62
+ }
63
+
64
+ fun getEmbeddedBitmapArray(path: String?): ByteArray? {
65
+ if (path == null) return null
66
+ val mmr = MediaMetadataRetriever()
67
+ try {
68
+ mmr.setDataSource(path)
69
+ return mmr.embeddedPicture
70
+ } catch (e: Exception) {
71
+ return null
72
+ }
73
+ }
74
+
75
+ fun getEmbeddedBitmap(path: String?): Bitmap? {
76
+ val artworkData = getEmbeddedBitmapArray(path)
77
+ return if (artworkData == null) null else BitmapFactory.decodeByteArray(artworkData, 0, artworkData.size)
78
+ }
79
+
80
+ var cacheKeyG = ""
81
+ // HACK: this will insert a png file at pictures/APMCache/APMCover.png.
82
+ fun saveMediaCoverToPng(path: String?, contentResolver: ContentResolver, cacheKey: String): String? {
83
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
84
+ if (cacheKey == cacheKeyG) {
85
+ return findAPMCacheApi(contentResolver).toString()
86
+ }
87
+ val contentValues = ContentValues().apply {
88
+ put(MediaStore.MediaColumns.DISPLAY_NAME, bitmapCoverFileName)
89
+ put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
90
+ put(MediaStore.MediaColumns.RELATIVE_PATH, bitmapCoverDir)
91
+ put(MediaStore.MediaColumns.IS_PENDING, 1)
92
+ }
93
+ val imageUri = getAPMCacheBitmapUri(contentResolver, contentValues)
94
+ val bitmap = getEmbeddedBitmap(path) ?: return null
95
+ cacheKeyG = cacheKey
96
+ var fos: OutputStream?
97
+
98
+ contentResolver.also { resolver ->
99
+ fos = imageUri?.let { resolver.openOutputStream(it) }
100
+ }
101
+ // TODO: add error handling
102
+ if (imageUri == null) return null
103
+ fos?.use { bitmap.compress(Bitmap.CompressFormat.PNG, 70, it) }
104
+ contentValues.clear()
105
+ contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)
106
+ contentResolver.update(imageUri, contentValues, null, null)
107
+ return imageUri.toString()
108
+ }
109
+ return null
110
+ // TODO: does this insert without overwriting?
111
+ // return MediaStore.Images.Media.insertImage(contentResolver, bitmap,
112
+ // bitmapCoverFileName,"APMCover")
113
+ }
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:tint="#FFFFFF" android:viewportHeight="24"
3
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:tint="#FFFFFF" android:viewportHeight="24"
3
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4zM13,15L13,9h-1l-2,1v1h1.5v4L13,15z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:tint="#FFFFFF" android:viewportHeight="24"
3
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M18,13c0,3.31 -2.69,6 -6,6s-6,-2.69 -6,-6s2.69,-6 6,-6v4l5,-5l-5,-5v4c-4.42,0 -8,3.58 -8,8c0,4.42 3.58,8 8,8c4.42,0 8,-3.58 8,-8H18z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:viewportHeight="960" android:viewportWidth="960"
3
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M480,840L422,788Q321,697 255,631Q189,565 150,512.5Q111,460 95.5,416Q80,372 80,326Q80,232 143,169Q206,106 300,106Q352,106 399,128Q446,150 480,190Q514,150 561,128Q608,106 660,106Q754,106 817,169Q880,232 880,326Q880,372 864.5,416Q849,460 810,512.5Q771,565 705,631Q639,697 538,788L480,840Z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:viewportHeight="960" android:viewportWidth="960"
3
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M480,840L422,788Q321,697 255,631Q189,565 150,512.5Q111,460 95.5,416Q80,372 80,326Q80,232 143,169Q206,106 300,106Q352,106 399,128Q446,150 480,190Q514,150 561,128Q608,106 660,106Q754,106 817,169Q880,232 880,326Q880,372 864.5,416Q849,460 810,512.5Q771,565 705,631Q639,697 538,788L480,840ZM480,732Q576,646 638,584.5Q700,523 736,477.5Q772,432 786,396.5Q800,361 800,326Q800,266 760,226Q720,186 660,186Q613,186 573,212.5Q533,239 518,280L518,280L442,280L442,280Q427,239 387,212.5Q347,186 300,186Q240,186 200,226Q160,266 160,326Q160,361 174,396.5Q188,432 224,477.5Q260,523 322,584.5Q384,646 480,732ZM480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459L480,459L480,459L480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:viewportHeight="960" android:viewportWidth="960"
3
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M640,700Q665,700 682.5,682.5Q700,665 700,640Q700,615 682.5,597.5Q665,580 640,580Q615,580 597.5,597.5Q580,615 580,640Q580,665 597.5,682.5Q615,700 640,700ZM480,540Q505,540 522.5,522.5Q540,505 540,480Q540,455 522.5,437.5Q505,420 480,420Q455,420 437.5,437.5Q420,455 420,480Q420,505 437.5,522.5Q455,540 480,540ZM320,380Q345,380 362.5,362.5Q380,345 380,320Q380,295 362.5,277.5Q345,260 320,260Q295,260 277.5,277.5Q260,295 260,320Q260,345 277.5,362.5Q295,380 320,380ZM200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM200,760L760,760Q760,760 760,760Q760,760 760,760L760,200Q760,200 760,200Q760,200 760,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760ZM200,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L200,760Q200,760 200,760Q200,760 200,760L200,200Q200,200 200,200Q200,200 200,200Z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:tint="#FFFFFF" android:viewportHeight="24"
3
+ android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6 -6,-2.69 -6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8 -3.58,-8 -8,-8z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <vector android:autoMirrored="true" android:height="24dp"
2
+ android:viewportHeight="960" android:viewportWidth="960"
3
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4
+ <path android:fillColor="@android:color/white" android:pathData="M560,800L560,720L664,720L537,593L594,536L720,662L720,560L800,560L800,800L560,800ZM216,800L160,744L664,240L560,240L560,160L800,160L800,400L720,400L720,296L216,800ZM367,423L160,216L216,160L423,367L367,423Z"/>
5
+ </vector>
@@ -0,0 +1,5 @@
1
+ <resources>
2
+ <string name="rntp_temporary_channel_id">rntp_temporary_channel</string>
3
+ <string name="playback_channel_name">Now Playing</string>
4
+ <string name="rntp_temporary_channel_name">temporary_channel</string>
5
+ </resources>
@@ -0,0 +1,3 @@
1
+ <automotiveApp>
2
+ <uses name="media"/>
3
+ </automotiveApp>
@@ -0,0 +1,21 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "filename" : "22AMillion.jpg",
5
+ "idiom" : "universal",
6
+ "scale" : "1x"
7
+ },
8
+ {
9
+ "idiom" : "universal",
10
+ "scale" : "2x"
11
+ },
12
+ {
13
+ "idiom" : "universal",
14
+ "scale" : "3x"
15
+ }
16
+ ],
17
+ "info" : {
18
+ "author" : "xcode",
19
+ "version" : 1
20
+ }
21
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "colors" : [
3
+ {
4
+ "idiom" : "universal"
5
+ }
6
+ ],
7
+ "info" : {
8
+ "author" : "xcode",
9
+ "version" : 1
10
+ }
11
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "idiom" : "mac",
5
+ "scale" : "1x",
6
+ "size" : "16x16"
7
+ },
8
+ {
9
+ "idiom" : "mac",
10
+ "scale" : "2x",
11
+ "size" : "16x16"
12
+ },
13
+ {
14
+ "idiom" : "mac",
15
+ "scale" : "1x",
16
+ "size" : "32x32"
17
+ },
18
+ {
19
+ "idiom" : "mac",
20
+ "scale" : "2x",
21
+ "size" : "32x32"
22
+ },
23
+ {
24
+ "idiom" : "mac",
25
+ "scale" : "1x",
26
+ "size" : "128x128"
27
+ },
28
+ {
29
+ "idiom" : "mac",
30
+ "scale" : "2x",
31
+ "size" : "128x128"
32
+ },
33
+ {
34
+ "idiom" : "mac",
35
+ "scale" : "1x",
36
+ "size" : "256x256"
37
+ },
38
+ {
39
+ "idiom" : "mac",
40
+ "scale" : "2x",
41
+ "size" : "256x256"
42
+ },
43
+ {
44
+ "idiom" : "mac",
45
+ "scale" : "1x",
46
+ "size" : "512x512"
47
+ },
48
+ {
49
+ "idiom" : "mac",
50
+ "scale" : "2x",
51
+ "size" : "512x512"
52
+ }
53
+ ],
54
+ "info" : {
55
+ "author" : "xcode",
56
+ "version" : 1
57
+ }
58
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "info" : {
3
+ "author" : "xcode",
4
+ "version" : 1
5
+ }
6
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "filename" : "cover.jpg",
5
+ "idiom" : "universal",
6
+ "scale" : "1x"
7
+ },
8
+ {
9
+ "idiom" : "universal",
10
+ "scale" : "2x"
11
+ },
12
+ {
13
+ "idiom" : "universal",
14
+ "scale" : "3x"
15
+ }
16
+ ],
17
+ "info" : {
18
+ "author" : "xcode",
19
+ "version" : 1
20
+ }
21
+ }
@@ -0,0 +1,46 @@
1
+ //
2
+ // AudioController.swift
3
+ // SwiftAudio_Example
4
+ //
5
+ // Created by Jørgen Henrichsen on 25/03/2018.
6
+ // Copyright © 2018 CocoaPods. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import SwiftAudioEx
11
+
12
+ class AudioController {
13
+
14
+ static let shared = AudioController()
15
+ let player: QueuedAudioPlayer
16
+
17
+ let sources: [AudioItem] = [
18
+ DefaultAudioItem(audioUrl: "https://rntp.dev/example/Longing.mp3", artist: "David Chavez", title: "Longing", sourceType: .stream, artwork: #imageLiteral(resourceName: "22AMI")),
19
+ DefaultAudioItem(audioUrl: "https://rntp.dev/example/Soul%20Searching.mp3", artist: "David Chavez", title: "Soul Searching (Demo)", sourceType: .stream, artwork: #imageLiteral(resourceName: "22AMI")),
20
+ DefaultAudioItem(audioUrl: "https://rntp.dev/example/Lullaby%20(Demo).mp3", artist: "David Chavez", title: "Lullaby (Demo)", sourceType: .stream, artwork: #imageLiteral(resourceName: "cover")),
21
+ DefaultAudioItem(audioUrl: "https://rntp.dev/example/Rhythm%20City%20(Demo).mp3", artist: "David Chavez", title: "Rhythm City (Demo)", sourceType: .stream, artwork: #imageLiteral(resourceName: "22AMI")),
22
+ DefaultAudioItem(audioUrl: "https://rntp.dev/example/hls/whip/playlist.m3u8", title: "Whip", sourceType: .stream, artwork: #imageLiteral(resourceName: "22AMI")),
23
+ DefaultAudioItem(audioUrl: "https://ais-sa5.cdnstream1.com/b75154_128mp3", artist: "New York, NY", title: "Smooth Jazz 24/7", sourceType: .stream, artwork: #imageLiteral(resourceName: "cover")),
24
+ DefaultAudioItem(audioUrl: "https://traffic.libsyn.com/atpfm/atp545.mp3", title: "Chapters", sourceType: .stream, artwork: #imageLiteral(resourceName: "22AMI")),
25
+ ]
26
+
27
+ init() {
28
+ let controller = RemoteCommandController()
29
+ player = QueuedAudioPlayer(remoteCommandController: controller)
30
+ player.remoteCommands = [
31
+ .stop,
32
+ .play,
33
+ .pause,
34
+ .togglePlayPause,
35
+ .next,
36
+ .previous,
37
+ .changePlaybackPosition
38
+ ]
39
+ player.audioTap = WaveformAudioTap()
40
+ player.repeatMode = .queue
41
+ DispatchQueue.main.async {
42
+ self.player.add(items: self.sources)
43
+ }
44
+ }
45
+
46
+ }
@@ -0,0 +1,22 @@
1
+ //
2
+ // Extensions.swift
3
+ // SwiftAudio
4
+ //
5
+ // Created by Brandon Sneed on 3/30/24.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ extension Double {
11
+ private var formatter: DateComponentsFormatter {
12
+ let formatter = DateComponentsFormatter()
13
+ formatter.allowedUnits = [.minute, .second]
14
+ formatter.unitsStyle = .positional
15
+ formatter.zeroFormattingBehavior = .pad
16
+ return formatter
17
+ }
18
+
19
+ func secondsToString() -> String {
20
+ return formatter.string(from: self) ?? ""
21
+ }
22
+ }