@javascriptcommon/react-native-track-player 1.2.9 → 4.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/README.md +8 -0
- package/android/build.gradle +92 -18
- package/android/proguard-rules.txt +0 -3
- package/android/src/main/AndroidManifest.xml +10 -13
- package/android/src/main/java/com/doublesymmetry/trackplayer/HeadlessJsMediaService.kt +199 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/TrackPlayer.kt +33 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/EnumExtensions.kt +5 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/extensions/NumberExt.kt +13 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/MetadataAdapter.kt +227 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/NowPlayingMetadata.kt +16 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/PlaybackMetadata.kt +203 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/State.kt +13 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/Track.kt +67 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/TrackAudioItem.kt +18 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/TrackMetadata.kt +38 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicEvents.kt +67 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/module/MusicModule.kt +778 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt +1286 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/utils/AppForegroundTracker.kt +35 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/utils/BundleUtils.kt +147 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/utils/CoilBitmapLoader.kt +65 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/utils/MediaItemBuilder.kt +41 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/utils/RejectionException.kt +11 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/video/TrackPlayerVideoView.kt +42 -0
- package/android/src/main/java/com/doublesymmetry/trackplayer/video/TrackPlayerVideoViewManager.kt +18 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/event/EventHolder.kt +30 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/event/PlayerEventHolder.kt +124 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioContentType.kt +10 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItem.kt +118 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioPlayerState.kt +30 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/BufferConfig.kt +8 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CacheConfig.kt +17 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/Capability.kt +19 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CustomButton.kt +19 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/FocusChangeData.kt +3 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/MediaSessionCallback.kt +17 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayWhenReadyChangeData.kt +3 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlaybackError.kt +6 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerConfig.kt +36 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerOptions.kt +40 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PositionChangedReason.kt +39 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/RepeatMode.kt +16 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/WakeMode.kt +7 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/AudioPlayer.kt +756 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/ForwardingPlayer.java +1124 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/QueuedAudioPlayer.kt +279 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/APMRenderersFactory.kt +33 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Buffer.kt +34 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/Cache.kt +27 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/FocusManager.kt +59 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/MediaFactory.kt +130 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/processors/TeeListener.kt +171 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/service/MusicService.kt +127 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/utils/FFT.java +99 -0
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/utils/Utils.kt +113 -0
- package/android/src/main/res/drawable/baseline_repeat_24.xml +5 -0
- package/android/src/main/res/drawable/baseline_repeat_one_24.xml +5 -0
- package/android/src/main/res/drawable/forward.xml +5 -0
- package/android/src/main/res/drawable/heart_24px.xml +5 -0
- package/android/src/main/res/drawable/hearte_24px.xml +5 -0
- package/android/src/main/res/drawable/ifl_24px.xml +5 -0
- package/android/src/main/res/drawable/rewind.xml +5 -0
- package/android/src/main/res/drawable/shuffle_24px.xml +5 -0
- package/android/src/main/res/values/strings.xml +5 -0
- package/android/src/main/res/xml/automotive_app_desc.xml +3 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/22AMillion.jpg +0 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/22AMI.imageset/Contents.json +21 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/Contents.json +6 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/Contents.json +21 -0
- package/ios/Example/SwiftAudio/Assets.xcassets/cover.imageset/cover.jpg +0 -0
- package/ios/Example/SwiftAudio/AudioController.swift +46 -0
- package/ios/Example/SwiftAudio/Extensions.swift +22 -0
- package/ios/Example/SwiftAudio/PlayerView.swift +172 -0
- package/ios/Example/SwiftAudio/PlayerViewModel.swift +120 -0
- package/ios/Example/SwiftAudio/Preview Content/Preview Assets.xcassets/Contents.json +6 -0
- package/ios/Example/SwiftAudio/QueueView.swift +65 -0
- package/ios/{TrackPlayer.xcodeproj/xcuserdata/marco.xcuserdatad/xcschemes/xcschememanagement.plist → Example/SwiftAudio/SwiftAudio.entitlements} +6 -8
- package/ios/Example/SwiftAudio/SwiftAudioApp.swift +17 -0
- package/ios/Example/SwiftAudio.xcodeproj/project.pbxproj +412 -0
- package/ios/{TrackPlayer.xcodeproj → Example/SwiftAudio.xcodeproj}/project.xcworkspace/contents.xcworkspacedata +1 -1
- package/ios/RNTrackPlayer/Models/Capabilities.swift +39 -4
- package/ios/RNTrackPlayer/Models/MediaURL.swift +12 -6
- package/ios/RNTrackPlayer/Models/MetadataAdapter.swift +147 -0
- package/ios/RNTrackPlayer/Models/PitchAlgorithms.swift +13 -0
- package/ios/RNTrackPlayer/Models/SessionCategories.swift +106 -0
- package/ios/RNTrackPlayer/Models/State.swift +26 -0
- package/ios/RNTrackPlayer/Models/Track.swift +74 -54
- package/ios/RNTrackPlayer/RNTrackPlayer.swift +867 -406
- package/ios/RNTrackPlayer/Support/RNTrackPlayer-Bridging-Header.h +1 -0
- package/ios/RNTrackPlayer/TrackPlayer.h +14 -0
- package/ios/RNTrackPlayer/TrackPlayer.mm +249 -0
- package/ios/RNTrackPlayer/Utils/EventType.swift +45 -0
- package/ios/RNTrackPlayer/Utils/Metadata.swift +60 -0
- package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoView.swift +83 -0
- package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoViewManager.m +5 -0
- package/ios/RNTrackPlayer/Video/RNTrackPlayerVideoViewManager.swift +17 -0
- package/ios/SwiftAudioEx/Package.swift +20 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapper.swift +531 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperDelegate.swift +27 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperProtocol.swift +69 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AVPlayerWrapper/AVPlayerWrapperState.swift +43 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioItem.swift +158 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayer.swift +459 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioPlayerError.swift +26 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSession.swift +33 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioSessionController/AudioSessionController.swift +135 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/AudioTap.swift +96 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Event.swift +155 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/MediaItemProperty.swift +95 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoCenter.swift +17 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoController.swift +73 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoControllerProtocol.swift +26 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoKeyValue.swift +14 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/NowPlayingInfoController/NowPlayingInfoProperty.swift +234 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemNotificationObserver.swift +102 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerItemObserver.swift +136 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerObserver.swift +120 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Observer/AVPlayerTimeObserver.swift +112 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueueManager.swift +356 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/QueuedAudioPlayer.swift +236 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommand.swift +170 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommandController.swift +206 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RepeatMode.swift +15 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/TimeEventFrequency.swift +26 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/Utils/DispatchQueueType.swift +18 -0
- package/ios/SwiftAudioEx/Sources/SwiftAudioEx/WaveformAudioTap.swift +159 -0
- package/lib/specs/NativeTrackPlayer.d.ts +134 -0
- package/lib/specs/NativeTrackPlayer.js +4 -0
- package/lib/src/TrackPlayerModule.web.d.ts +2 -0
- package/lib/src/TrackPlayerModule.web.js +2 -0
- package/lib/src/VideoView.d.ts +16 -0
- package/lib/src/VideoView.js +25 -0
- package/lib/src/constants/AndroidAudioContentType.d.ts +35 -0
- package/lib/src/constants/AndroidAudioContentType.js +36 -0
- package/lib/src/constants/AndroidAutoContentStyle.d.ts +10 -0
- package/lib/src/constants/AndroidAutoContentStyle.js +11 -0
- package/lib/src/constants/AppKilledPlaybackBehavior.d.ts +17 -0
- package/lib/src/constants/AppKilledPlaybackBehavior.js +18 -0
- package/lib/src/constants/Capability.d.ts +17 -0
- package/lib/src/constants/Capability.js +19 -0
- package/lib/src/constants/Event.d.ts +172 -0
- package/lib/src/constants/Event.js +173 -0
- package/lib/src/constants/IOSCategory.d.ts +36 -0
- package/lib/src/constants/IOSCategory.js +37 -0
- package/lib/src/constants/IOSCategoryMode.d.ts +47 -0
- package/lib/src/constants/IOSCategoryMode.js +48 -0
- package/lib/src/constants/IOSCategoryOptions.d.ts +44 -0
- package/lib/src/constants/IOSCategoryOptions.js +45 -0
- package/lib/src/constants/MediaItemPlayable.d.ts +4 -0
- package/lib/src/constants/MediaItemPlayable.js +5 -0
- package/lib/src/constants/PitchAlgorithm.d.ts +14 -0
- package/lib/src/constants/PitchAlgorithm.js +16 -0
- package/lib/src/constants/RatingType.d.ts +8 -0
- package/lib/src/constants/RatingType.js +10 -0
- package/lib/src/constants/RepeatMode.d.ts +8 -0
- package/lib/src/constants/RepeatMode.js +10 -0
- package/lib/src/constants/State.d.ts +34 -0
- package/lib/src/constants/State.js +35 -0
- package/lib/src/constants/TrackType.d.ts +6 -0
- package/lib/src/constants/TrackType.js +7 -0
- package/lib/src/constants/index.d.ts +14 -0
- package/lib/src/constants/index.js +14 -0
- package/lib/src/hooks/index.d.ts +6 -0
- package/lib/src/hooks/index.js +6 -0
- package/lib/src/hooks/useActiveTrack.d.ts +2 -0
- package/lib/src/hooks/useActiveTrack.js +28 -0
- package/lib/src/hooks/useAppIsInBackground.d.ts +1 -0
- package/lib/src/hooks/useAppIsInBackground.js +16 -0
- package/lib/src/hooks/useIsPlaying.d.ts +35 -0
- package/lib/src/hooks/useIsPlaying.js +50 -0
- package/lib/src/hooks/usePlayWhenReady.d.ts +1 -0
- package/lib/src/hooks/usePlayWhenReady.js +27 -0
- package/lib/src/hooks/usePlaybackState.d.ts +10 -0
- package/lib/src/hooks/usePlaybackState.js +35 -0
- package/lib/src/hooks/useProgress.d.ts +7 -0
- package/lib/src/hooks/useProgress.js +55 -0
- package/lib/src/hooks/useTrackPlayerEvents.d.ts +8 -0
- package/lib/src/hooks/useTrackPlayerEvents.js +30 -0
- package/lib/src/index.d.ts +6 -0
- package/lib/src/index.js +6 -0
- package/lib/src/interfaces/AndroidAutoBrowseTree.d.ts +5 -0
- package/lib/src/interfaces/AndroidAutoBrowseTree.js +1 -0
- package/lib/src/interfaces/AndroidOptions.d.ts +41 -0
- package/lib/src/interfaces/AndroidOptions.js +1 -0
- package/lib/src/interfaces/CustomButtons.d.ts +5 -0
- package/lib/src/interfaces/CustomButtons.js +1 -0
- package/lib/src/interfaces/FeedbackOptions.d.ts +6 -0
- package/lib/src/interfaces/FeedbackOptions.js +1 -0
- package/lib/src/interfaces/MediaItem.d.ts +18 -0
- package/lib/src/interfaces/MediaItem.js +1 -0
- package/lib/src/interfaces/MetadataOptions.d.ts +3 -0
- package/lib/src/interfaces/MetadataOptions.js +1 -0
- package/lib/src/interfaces/NowPlayingMetadata.d.ts +4 -0
- package/lib/src/interfaces/NowPlayingMetadata.js +1 -0
- package/lib/src/interfaces/PlaybackState.d.ts +8 -0
- package/lib/src/interfaces/PlaybackState.js +1 -0
- package/lib/src/interfaces/PlayerOptions.d.ts +132 -0
- package/lib/src/interfaces/PlayerOptions.js +1 -0
- package/lib/src/interfaces/Progress.d.ts +15 -0
- package/lib/src/interfaces/Progress.js +1 -0
- package/lib/src/interfaces/ResourceObject.d.ts +1 -0
- package/lib/src/interfaces/ResourceObject.js +1 -0
- package/lib/src/interfaces/ServiceHandler.d.ts +1 -0
- package/lib/src/interfaces/ServiceHandler.js +1 -0
- package/lib/src/interfaces/Track.d.ts +21 -0
- package/lib/src/interfaces/Track.js +1 -0
- package/lib/src/interfaces/TrackMetadataBase.d.ts +28 -0
- package/lib/src/interfaces/TrackMetadataBase.js +1 -0
- package/lib/src/interfaces/UpdateOptions.d.ts +52 -0
- package/lib/src/interfaces/UpdateOptions.js +1 -0
- package/lib/src/interfaces/events/AudioMetadataReceivedEvent.d.ts +33 -0
- package/lib/src/interfaces/events/AudioMetadataReceivedEvent.js +1 -0
- package/lib/src/interfaces/events/ControllerConnectedEvent.d.ts +8 -0
- package/lib/src/interfaces/events/ControllerConnectedEvent.js +1 -0
- package/lib/src/interfaces/events/EventPayloadByEvent.d.ts +77 -0
- package/lib/src/interfaces/events/EventPayloadByEvent.js +1 -0
- package/lib/src/interfaces/events/FFTUpdateEvent.d.ts +7 -0
- package/lib/src/interfaces/events/FFTUpdateEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.d.ts +24 -0
- package/lib/src/interfaces/events/PlaybackActiveTrackChangedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.d.ts +4 -0
- package/lib/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackErrorEvent.d.ts +6 -0
- package/lib/src/interfaces/events/PlaybackErrorEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.d.ts +16 -0
- package/lib/src/interfaces/events/PlaybackMetadataReceivedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.d.ts +4 -0
- package/lib/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.d.ts +4 -0
- package/lib/src/interfaces/events/PlaybackProgressUpdatedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackQueueEndedEvent.d.ts +9 -0
- package/lib/src/interfaces/events/PlaybackQueueEndedEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackResumeEvent.d.ts +3 -0
- package/lib/src/interfaces/events/PlaybackResumeEvent.js +1 -0
- package/lib/src/interfaces/events/PlaybackTrackChangedEvent.d.ts +11 -0
- package/lib/src/interfaces/events/PlaybackTrackChangedEvent.js +1 -0
- package/lib/src/interfaces/events/PlayerErrorEvent.d.ts +6 -0
- package/lib/src/interfaces/events/PlayerErrorEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteBrowseEvent.d.ts +4 -0
- package/lib/src/interfaces/events/RemoteBrowseEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteCustomActionEvent.d.ts +7 -0
- package/lib/src/interfaces/events/RemoteCustomActionEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteDuckEvent.d.ts +13 -0
- package/lib/src/interfaces/events/RemoteDuckEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteJumpBackwardEvent.d.ts +7 -0
- package/lib/src/interfaces/events/RemoteJumpBackwardEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteJumpForwardEvent.d.ts +7 -0
- package/lib/src/interfaces/events/RemoteJumpForwardEvent.js +1 -0
- package/lib/src/interfaces/events/RemotePlayIdEvent.d.ts +4 -0
- package/lib/src/interfaces/events/RemotePlayIdEvent.js +1 -0
- package/lib/src/interfaces/events/RemotePlaySearchEvent.d.ts +9 -0
- package/lib/src/interfaces/events/RemotePlaySearchEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteSearchEvent.d.ts +3 -0
- package/lib/src/interfaces/events/RemoteSearchEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteSeekEvent.d.ts +4 -0
- package/lib/src/interfaces/events/RemoteSeekEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteSetRatingEvent.d.ts +4 -0
- package/lib/src/interfaces/events/RemoteSetRatingEvent.js +1 -0
- package/lib/src/interfaces/events/RemoteSkipEvent.d.ts +3 -0
- package/lib/src/interfaces/events/RemoteSkipEvent.js +1 -0
- package/lib/src/interfaces/events/index.d.ts +20 -0
- package/lib/src/interfaces/events/index.js +20 -0
- package/lib/src/interfaces/index.d.ts +15 -0
- package/lib/src/interfaces/index.js +15 -0
- package/lib/src/resolveAssetSource.d.ts +2 -0
- package/lib/src/resolveAssetSource.js +3 -0
- package/lib/src/resolveAssetSource.web.d.ts +2 -0
- package/lib/src/resolveAssetSource.web.js +8 -0
- package/lib/src/trackPlayer.d.ts +371 -0
- package/lib/src/trackPlayer.js +627 -0
- package/lib/web/TrackPlayer/Player.d.ts +40 -0
- package/lib/web/TrackPlayer/Player.js +188 -0
- package/lib/web/TrackPlayer/PlaylistPlayer.d.ts +31 -0
- package/lib/web/TrackPlayer/PlaylistPlayer.js +181 -0
- package/lib/web/TrackPlayer/RepeatMode.d.ts +5 -0
- package/lib/web/TrackPlayer/RepeatMode.js +6 -0
- package/lib/web/TrackPlayer/SetupNotCalledError.d.ts +3 -0
- package/lib/web/TrackPlayer/SetupNotCalledError.js +5 -0
- package/lib/web/TrackPlayer/index.d.ts +3 -0
- package/lib/web/TrackPlayer/index.js +3 -0
- package/lib/web/TrackPlayerModule.d.ts +63 -0
- package/lib/web/TrackPlayerModule.js +153 -0
- package/lib/web/index.d.ts +3 -0
- package/lib/web/index.js +3 -0
- package/package.json +85 -6
- package/react-native-track-player.podspec +13 -13
- package/specs/NativeTrackPlayer.ts +153 -0
- package/src/TrackPlayerModule.web.ts +2 -0
- package/src/VideoView.tsx +51 -0
- package/src/constants/AndroidAudioContentType.ts +35 -0
- package/src/constants/AndroidAutoContentStyle.ts +10 -0
- package/src/constants/AppKilledPlaybackBehavior.ts +19 -0
- package/src/constants/Capability.ts +19 -0
- package/src/constants/Event.ts +173 -0
- package/src/constants/IOSCategory.ts +36 -0
- package/src/constants/IOSCategoryMode.ts +47 -0
- package/src/constants/IOSCategoryOptions.ts +44 -0
- package/src/constants/MediaItemPlayable.ts +4 -0
- package/src/constants/PitchAlgorithm.ts +16 -0
- package/src/constants/RatingType.ts +10 -0
- package/src/constants/RepeatMode.ts +10 -0
- package/src/constants/State.ts +34 -0
- package/src/constants/TrackType.ts +6 -0
- package/src/constants/index.ts +14 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useActiveTrack.ts +36 -0
- package/src/hooks/useAppIsInBackground.ts +20 -0
- package/src/hooks/useIsPlaying.ts +56 -0
- package/src/hooks/usePlayWhenReady.ts +37 -0
- package/src/hooks/usePlaybackState.ts +45 -0
- package/src/hooks/useProgress.ts +64 -0
- package/src/hooks/useTrackPlayerEvents.ts +48 -0
- package/src/index.ts +8 -0
- package/src/interfaces/AndroidAutoBrowseTree.ts +6 -0
- package/src/interfaces/AndroidOptions.ts +48 -0
- package/src/interfaces/CustomButtons.ts +6 -0
- package/src/interfaces/FeedbackOptions.ts +7 -0
- package/src/interfaces/MediaItem.ts +19 -0
- package/src/interfaces/MetadataOptions.ts +4 -0
- package/src/interfaces/NowPlayingMetadata.ts +5 -0
- package/src/interfaces/PlaybackState.ts +11 -0
- package/src/interfaces/PlayerOptions.ts +138 -0
- package/src/interfaces/Progress.ts +15 -0
- package/src/interfaces/ResourceObject.ts +1 -0
- package/src/interfaces/ServiceHandler.ts +1 -0
- package/src/interfaces/Track.ts +23 -0
- package/src/interfaces/TrackMetadataBase.ts +29 -0
- package/src/interfaces/UpdateOptions.ts +59 -0
- package/src/interfaces/events/AudioMetadataReceivedEvent.ts +37 -0
- package/src/interfaces/events/ControllerConnectedEvent.ts +9 -0
- package/src/interfaces/events/EventPayloadByEvent.ts +80 -0
- package/src/interfaces/events/FFTUpdateEvent.ts +9 -0
- package/src/interfaces/events/PlaybackActiveTrackChangedEvent.ts +29 -0
- package/src/interfaces/events/PlaybackAnimatedVolumeChangedEvent.ts +4 -0
- package/src/interfaces/events/PlaybackErrorEvent.ts +6 -0
- package/src/interfaces/events/PlaybackMetadataReceivedEvent.ts +16 -0
- package/src/interfaces/events/PlaybackPlayWhenReadyChangedEvent.ts +4 -0
- package/src/interfaces/events/PlaybackProgressUpdatedEvent.ts +5 -0
- package/src/interfaces/events/PlaybackQueueEndedEvent.ts +9 -0
- package/src/interfaces/events/PlaybackResumeEvent.ts +5 -0
- package/src/interfaces/events/PlaybackTrackChangedEvent.ts +11 -0
- package/src/interfaces/events/PlayerErrorEvent.ts +6 -0
- package/src/interfaces/events/RemoteBrowseEvent.ts +4 -0
- package/src/interfaces/events/RemoteCustomActionEvent.ts +7 -0
- package/src/interfaces/events/RemoteDuckEvent.ts +13 -0
- package/src/interfaces/events/RemoteJumpBackwardEvent.ts +7 -0
- package/src/interfaces/events/RemoteJumpForwardEvent.ts +7 -0
- package/src/interfaces/events/RemotePlayIdEvent.ts +4 -0
- package/src/interfaces/events/RemotePlaySearchEvent.ts +21 -0
- package/src/interfaces/events/RemoteSearchEvent.ts +3 -0
- package/src/interfaces/events/RemoteSeekEvent.ts +4 -0
- package/src/interfaces/events/RemoteSetRatingEvent.ts +5 -0
- package/src/interfaces/events/RemoteSkipEvent.ts +3 -0
- package/src/interfaces/events/index.ts +20 -0
- package/src/interfaces/index.ts +15 -0
- package/src/resolveAssetSource.ts +3 -0
- package/src/resolveAssetSource.web.ts +10 -0
- package/src/trackPlayer.ts +806 -0
- package/web/TrackPlayer/Player.ts +201 -0
- package/web/TrackPlayer/PlaylistPlayer.ts +215 -0
- package/web/TrackPlayer/RepeatMode.ts +6 -0
- package/web/TrackPlayer/SetupNotCalledError.ts +5 -0
- package/web/TrackPlayer/index.ts +3 -0
- package/web/TrackPlayerModule.ts +181 -0
- package/web/index.ts +4 -0
- package/CHANGELOG.md +0 -75
- package/android/react-native-music-control.iml +0 -139
- package/android/react-native-track-player.iml +0 -151
- package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.java +0 -28
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.java +0 -55
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.java +0 -298
- package/android/src/main/java/com/guichaguri/trackplayer/service/HeadlessJsMediaService.java +0 -174
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.java +0 -47
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.java +0 -383
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.java +0 -271
- package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.java +0 -243
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.java +0 -148
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.java +0 -379
- package/android/src/main/java/com/guichaguri/trackplayer/service/models/Track.java +0 -141
- package/android/src/main/java/com/guichaguri/trackplayer/service/models/TrackType.java +0 -35
- package/android/src/main/res/drawable-hdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_next.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_pause.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_play.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_previous.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_rewind.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_stop.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_next.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_pause.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_play.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_previous.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_rewind.png +0 -0
- package/android/src/main/res/drawable-mdpi/ic_stop.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_next.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_pause.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_play.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_previous.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_rewind.png +0 -0
- package/android/src/main/res/drawable-xhdpi/ic_stop.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_next.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_pause.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_play.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_previous.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_rewind.png +0 -0
- package/android/src/main/res/drawable-xxhdpi/ic_stop.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_logo.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_next.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_pause.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_play.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_previous.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_rewind.png +0 -0
- package/android/src/main/res/drawable-xxxhdpi/ic_stop.png +0 -0
- package/index.d.ts +0 -174
- package/index.js +0 -4
- package/ios/RNTrackPlayer/RNTrackPlayerBridge.h +0 -12
- package/ios/RNTrackPlayer/RNTrackPlayerBridge.m +0 -29
- package/ios/TrackPlayer.xcodeproj/project.pbxproj +0 -495
- package/ios/TrackPlayer.xcodeproj/project.xcworkspace/xcuserdata/marco.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/lib/ProgressComponent.js +0 -70
- package/lib/eventTypes.js +0 -28
- package/lib/hooks.js +0 -160
- package/lib/index.js +0 -177
- /package/ios/{TrackPlayer.xcodeproj → Example/SwiftAudio.xcodeproj}/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
@file: OptIn(UnstableApi::class) package com.lovegaoshi.kotlinaudio.player
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import androidx.annotation.OptIn
|
|
5
|
+
import androidx.media3.common.C
|
|
6
|
+
import androidx.media3.common.IllegalSeekPositionException
|
|
7
|
+
import androidx.media3.common.MediaItem
|
|
8
|
+
import androidx.media3.common.Player
|
|
9
|
+
import androidx.media3.common.util.UnstableApi
|
|
10
|
+
import com.lovegaoshi.kotlinaudio.models.*
|
|
11
|
+
import java.util.*
|
|
12
|
+
import kotlin.math.max
|
|
13
|
+
import kotlin.math.min
|
|
14
|
+
|
|
15
|
+
class QueuedAudioPlayer(
|
|
16
|
+
private val context: Context,
|
|
17
|
+
options: PlayerOptions = PlayerOptions()
|
|
18
|
+
) : AudioPlayer(context, options) {
|
|
19
|
+
|
|
20
|
+
var parseEmbeddedArtwork: Boolean = false
|
|
21
|
+
|
|
22
|
+
private val queue = LinkedList<MediaItem>()
|
|
23
|
+
|
|
24
|
+
private fun parseAudioItem(audioItem: AudioItem): MediaItem {
|
|
25
|
+
return audioItem2MediaItem(audioItem, if (parseEmbeddedArtwork) context else null)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var repeatMode: RepeatMode
|
|
29
|
+
get() {
|
|
30
|
+
return when (exoPlayer.repeatMode) {
|
|
31
|
+
Player.REPEAT_MODE_ALL -> RepeatMode.ALL
|
|
32
|
+
Player.REPEAT_MODE_ONE -> RepeatMode.ONE
|
|
33
|
+
else -> RepeatMode.OFF
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
set(value) {
|
|
37
|
+
when (value) {
|
|
38
|
+
RepeatMode.ALL -> players().forEach { p -> p.repeatMode = Player.REPEAT_MODE_ALL }
|
|
39
|
+
RepeatMode.ONE -> players().forEach { p -> p.repeatMode = Player.REPEAT_MODE_ONE }
|
|
40
|
+
RepeatMode.OFF -> players().forEach { p -> p.repeatMode = Player.REPEAT_MODE_OFF }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
val currentIndex
|
|
45
|
+
get() = exoPlayer.currentMediaItemIndex
|
|
46
|
+
|
|
47
|
+
var shuffleMode
|
|
48
|
+
get() = exoPlayer.shuffleModeEnabled
|
|
49
|
+
set(v) {
|
|
50
|
+
players().forEach{ p -> p.shuffleModeEnabled = v }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override val currentItem: AudioItem?
|
|
54
|
+
get() = mediaItem2AudioItem(queue.getOrNull(currentIndex))
|
|
55
|
+
|
|
56
|
+
val nextIndex: Int?
|
|
57
|
+
get() {
|
|
58
|
+
return if (exoPlayer.nextMediaItemIndex == C.INDEX_UNSET) null
|
|
59
|
+
else exoPlayer.nextMediaItemIndex
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
val previousIndex: Int?
|
|
63
|
+
get() {
|
|
64
|
+
return if (exoPlayer.previousMediaItemIndex == C.INDEX_UNSET) null
|
|
65
|
+
else exoPlayer.previousMediaItemIndex
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
val items: List<AudioItem>
|
|
69
|
+
get() = queue.map { mediaItem2AudioItem(it)!! }
|
|
70
|
+
|
|
71
|
+
val previousItems: List<AudioItem>
|
|
72
|
+
get() {
|
|
73
|
+
return if (queue.isEmpty()) emptyList()
|
|
74
|
+
else queue
|
|
75
|
+
.subList(0, exoPlayer.currentMediaItemIndex)
|
|
76
|
+
.map { mediaItem2AudioItem(it)!! }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
val nextItems: List<AudioItem>
|
|
80
|
+
get() {
|
|
81
|
+
return if (queue.isEmpty()) emptyList()
|
|
82
|
+
else queue
|
|
83
|
+
.subList(exoPlayer.currentMediaItemIndex, queue.lastIndex)
|
|
84
|
+
.map { mediaItem2AudioItem(it)!! }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
val nextItem: AudioItem?
|
|
88
|
+
get() = items.getOrNull(currentIndex + 1)
|
|
89
|
+
|
|
90
|
+
val previousItem: AudioItem?
|
|
91
|
+
get() = items.getOrNull(currentIndex - 1)
|
|
92
|
+
|
|
93
|
+
override fun load(item: AudioItem, playWhenReady: Boolean) {
|
|
94
|
+
load(item)
|
|
95
|
+
exoPlayer.playWhenReady = playWhenReady
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
override fun load(item: AudioItem) {
|
|
99
|
+
if (queue.isEmpty()) {
|
|
100
|
+
add(item)
|
|
101
|
+
} else {
|
|
102
|
+
players().forEach { p ->
|
|
103
|
+
p.addMediaItem(currentIndex + 1, parseAudioItem(item))
|
|
104
|
+
p.removeMediaItem(currentIndex)
|
|
105
|
+
p.seekTo(currentIndex, C.TIME_UNSET)
|
|
106
|
+
}
|
|
107
|
+
exoPlayer.prepare()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Add a single item to the queue. If the AudioPlayer has no item loaded, it will load the `item`.
|
|
113
|
+
* @param item The [AudioItem] to add.
|
|
114
|
+
*/
|
|
115
|
+
fun add(item: AudioItem, playWhenReady: Boolean) {
|
|
116
|
+
exoPlayer.playWhenReady = playWhenReady
|
|
117
|
+
add(item)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Add a single item to the queue. If the AudioPlayer has no item loaded, it will load the `item`.
|
|
122
|
+
* @param item The [AudioItem] to add.
|
|
123
|
+
*/
|
|
124
|
+
fun add(item: AudioItem) {
|
|
125
|
+
val mediaSource = parseAudioItem(item)
|
|
126
|
+
queue.add(mediaSource)
|
|
127
|
+
players().forEach { p -> p.addMediaItem(mediaSource) }
|
|
128
|
+
exoPlayer.prepare()
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Add multiple items to the queue. If the AudioPlayer has no item loaded, it will load the first item in the list.
|
|
133
|
+
* @param items The [AudioItem]s to add.
|
|
134
|
+
* @param playWhenReady Whether playback starts automatically.
|
|
135
|
+
*/
|
|
136
|
+
fun add(items: List<AudioItem>, playWhenReady: Boolean) {
|
|
137
|
+
exoPlayer.playWhenReady = playWhenReady
|
|
138
|
+
add(items)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Add multiple items to the queue. If the AudioPlayer has no item loaded, it will load the first item in the list.
|
|
143
|
+
* @param items The [AudioItem]s to add.
|
|
144
|
+
*/
|
|
145
|
+
fun add(items: List<AudioItem>) {
|
|
146
|
+
val mediaSources = items.map { parseAudioItem(it) }
|
|
147
|
+
queue.addAll(mediaSources)
|
|
148
|
+
players().forEach { p -> p.addMediaItems(mediaSources) }
|
|
149
|
+
exoPlayer.prepare()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Add multiple items to the queue.
|
|
155
|
+
* @param items The [AudioItem]s to add.
|
|
156
|
+
* @param atIndex Index to insert items at, if no items loaded this will not automatically start playback.
|
|
157
|
+
*/
|
|
158
|
+
fun add(items: List<AudioItem>, atIndex: Int) {
|
|
159
|
+
val mediaSources = items.map { parseAudioItem(it) }
|
|
160
|
+
queue.addAll(atIndex, mediaSources)
|
|
161
|
+
players().forEach { p -> p.addMediaItems(atIndex, mediaSources) }
|
|
162
|
+
exoPlayer.prepare()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Remove an item from the queue.
|
|
167
|
+
* @param index The index of the item to remove.
|
|
168
|
+
*/
|
|
169
|
+
fun remove(index: Int) {
|
|
170
|
+
queue.removeAt(index)
|
|
171
|
+
players().forEach { p -> p.removeMediaItem(index) }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Remove items from the queue.
|
|
176
|
+
* @param indexes The indexes of the items to remove.
|
|
177
|
+
*/
|
|
178
|
+
fun remove(indexes: List<Int>) {
|
|
179
|
+
val sorted = indexes.toMutableList()
|
|
180
|
+
// Sort the indexes in descending order so we can safely remove them one by one
|
|
181
|
+
// without having the next index possibly newly pointing to another item than intended:
|
|
182
|
+
sorted.sortDescending()
|
|
183
|
+
sorted.forEach {
|
|
184
|
+
remove(it)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Skip to the next item in the queue, which may depend on the current repeat mode.
|
|
190
|
+
* Does nothing if there is no next item to skip to.
|
|
191
|
+
*/
|
|
192
|
+
fun next() {
|
|
193
|
+
exoPlayer.seekToNextMediaItem()
|
|
194
|
+
exoPlayer.prepare()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Skip to the previous item in the queue, which may depend on the current repeat mode.
|
|
199
|
+
* Does nothing if there is no previous item to skip to.
|
|
200
|
+
*/
|
|
201
|
+
fun previous() {
|
|
202
|
+
exoPlayer.seekToPreviousMediaItem()
|
|
203
|
+
exoPlayer.prepare()
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Move an item in the queue from one position to another.
|
|
208
|
+
* @param fromIndex The index of the item ot move.
|
|
209
|
+
* @param toIndex The index to move the item to. If the index is larger than the size of the queue, the item is moved to the end of the queue instead.
|
|
210
|
+
*/
|
|
211
|
+
fun move(fromIndex: Int, toIndex: Int) {
|
|
212
|
+
players().forEach { p -> p.moveMediaItem(fromIndex, toIndex) }
|
|
213
|
+
val item = queue[fromIndex]
|
|
214
|
+
queue.removeAt(fromIndex)
|
|
215
|
+
queue.add(max(0, min(items.size, if (toIndex > fromIndex) toIndex else toIndex - 1)), item)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Jump to an item in the queue.
|
|
220
|
+
* @param index the index to jump to
|
|
221
|
+
* @param playWhenReady Whether playback starts automatically.
|
|
222
|
+
*/
|
|
223
|
+
fun jumpToItem(index: Int, playWhenReady: Boolean) {
|
|
224
|
+
exoPlayer.playWhenReady = playWhenReady
|
|
225
|
+
jumpToItem(index)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Jump to an item in the queue.
|
|
230
|
+
* @param index the index to jump to
|
|
231
|
+
*/
|
|
232
|
+
fun jumpToItem(index: Int) {
|
|
233
|
+
try {
|
|
234
|
+
exoPlayer.seekTo(index, C.TIME_UNSET)
|
|
235
|
+
exoPlayer.prepare()
|
|
236
|
+
} catch (e: IllegalSeekPositionException) {
|
|
237
|
+
throw Error("This item index $index does not exist. The size of the queue is ${queue.size} items.")
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Replaces item at index in queue.
|
|
243
|
+
*/
|
|
244
|
+
fun replaceItem(index: Int, item: AudioItem) {
|
|
245
|
+
val mediaSource = parseAudioItem(item)
|
|
246
|
+
queue[index] = mediaSource
|
|
247
|
+
players().forEach { p -> p.replaceMediaItem(index, mediaSource) }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Removes all the upcoming items, if any (the ones returned by [next]).
|
|
252
|
+
*/
|
|
253
|
+
fun removeUpcomingItems() {
|
|
254
|
+
if (queue.lastIndex == -1 || currentIndex == -1) return
|
|
255
|
+
val lastIndex = queue.lastIndex + 1
|
|
256
|
+
val fromIndex = currentIndex + 1
|
|
257
|
+
|
|
258
|
+
players().forEach { p -> p.removeMediaItems(fromIndex, lastIndex) }
|
|
259
|
+
queue.subList(fromIndex, lastIndex).clear()
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Removes all the previous items, if any (the ones returned by [previous]).
|
|
264
|
+
*/
|
|
265
|
+
fun removePreviousItems() {
|
|
266
|
+
players().forEach { p -> p.removeMediaItems(0, currentIndex) }
|
|
267
|
+
queue.subList(0, currentIndex).clear()
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
override fun destroy() {
|
|
271
|
+
queue.clear()
|
|
272
|
+
super.destroy()
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
override fun clear() {
|
|
276
|
+
queue.clear()
|
|
277
|
+
super.clear()
|
|
278
|
+
}
|
|
279
|
+
}
|
package/android/src/main/java/com/lovegaoshi/kotlinaudio/player/components/APMRenderersFactory.kt
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.lovegaoshi.kotlinaudio.player.components
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import androidx.media3.common.util.UnstableApi
|
|
5
|
+
import androidx.media3.exoplayer.DefaultRenderersFactory
|
|
6
|
+
import androidx.media3.exoplayer.audio.AudioSink
|
|
7
|
+
import androidx.media3.exoplayer.audio.DefaultAudioSink
|
|
8
|
+
import androidx.media3.exoplayer.audio.TeeAudioProcessor
|
|
9
|
+
import com.lovegaoshi.kotlinaudio.processors.FFTEmitter
|
|
10
|
+
import com.lovegaoshi.kotlinaudio.processors.TeeListener
|
|
11
|
+
|
|
12
|
+
@UnstableApi
|
|
13
|
+
class APMRenderersFactory(
|
|
14
|
+
context: Context,
|
|
15
|
+
sampleRate: Int = 4096,
|
|
16
|
+
emitter: FFTEmitter?
|
|
17
|
+
) : DefaultRenderersFactory(context) {
|
|
18
|
+
val teeProcessor = TeeAudioProcessor(TeeListener(sampleRate, emitter))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
override fun buildAudioSink(
|
|
22
|
+
context: Context,
|
|
23
|
+
enableFloatOutput: Boolean,
|
|
24
|
+
enableAudioTrackPlaybackParams: Boolean
|
|
25
|
+
): AudioSink? {
|
|
26
|
+
return DefaultAudioSink.Builder(context)
|
|
27
|
+
.setEnableFloatOutput(enableFloatOutput)
|
|
28
|
+
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
|
29
|
+
.setAudioProcessors(arrayOf(teeProcessor))
|
|
30
|
+
.build()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
package com.lovegaoshi.kotlinaudio.player.components
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.OptIn
|
|
4
|
+
import androidx.media3.common.util.UnstableApi
|
|
5
|
+
import androidx.media3.exoplayer.DefaultLoadControl
|
|
6
|
+
import androidx.media3.exoplayer.DefaultLoadControl.Builder
|
|
7
|
+
import androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS
|
|
8
|
+
import androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
|
|
9
|
+
import androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS
|
|
10
|
+
import androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_MAX_BUFFER_MS
|
|
11
|
+
import androidx.media3.exoplayer.DefaultLoadControl.DEFAULT_MIN_BUFFER_MS
|
|
12
|
+
import com.lovegaoshi.kotlinaudio.models.BufferOptions
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@OptIn(UnstableApi::class) fun setupBuffer(bufferConfig: BufferOptions): DefaultLoadControl {
|
|
16
|
+
bufferConfig.apply {
|
|
17
|
+
val multiplier =
|
|
18
|
+
DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS / DEFAULT_BUFFER_FOR_PLAYBACK_MS
|
|
19
|
+
val minBuffer =
|
|
20
|
+
if (minBuffer != null && minBuffer != 0) minBuffer else DEFAULT_MIN_BUFFER_MS
|
|
21
|
+
val maxBuffer =
|
|
22
|
+
if (maxBuffer != null && maxBuffer != 0) maxBuffer else DEFAULT_MAX_BUFFER_MS
|
|
23
|
+
val playBuffer =
|
|
24
|
+
if (playBuffer != null && playBuffer != 0) playBuffer else DEFAULT_BUFFER_FOR_PLAYBACK_MS
|
|
25
|
+
val backBuffer =
|
|
26
|
+
if (backBuffer != null && backBuffer != 0) backBuffer else DEFAULT_BACK_BUFFER_DURATION_MS
|
|
27
|
+
|
|
28
|
+
return Builder()
|
|
29
|
+
.setBufferDurationsMs(minBuffer, maxBuffer, playBuffer, playBuffer * multiplier)
|
|
30
|
+
.setBackBuffer(backBuffer, false)
|
|
31
|
+
.build()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package com.lovegaoshi.kotlinaudio.player.components
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import androidx.media3.common.util.UnstableApi
|
|
5
|
+
import androidx.media3.database.DatabaseProvider
|
|
6
|
+
import androidx.media3.database.StandaloneDatabaseProvider
|
|
7
|
+
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
|
8
|
+
import androidx.media3.datasource.cache.SimpleCache
|
|
9
|
+
import java.io.File
|
|
10
|
+
|
|
11
|
+
@UnstableApi
|
|
12
|
+
object Cache {
|
|
13
|
+
@Volatile
|
|
14
|
+
private var instance: SimpleCache? = null
|
|
15
|
+
|
|
16
|
+
fun initCache(context: Context, size: Long): SimpleCache {
|
|
17
|
+
val db: DatabaseProvider = StandaloneDatabaseProvider(context)
|
|
18
|
+
|
|
19
|
+
instance ?: synchronized(this) {
|
|
20
|
+
instance ?: SimpleCache(
|
|
21
|
+
File(context.cacheDir, "APM"), LeastRecentlyUsedCacheEvictor(size), db)
|
|
22
|
+
.also { instance = it }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return instance!!
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package com.lovegaoshi.kotlinaudio.player.components
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.media.AudioManager
|
|
5
|
+
import androidx.core.content.ContextCompat
|
|
6
|
+
import androidx.media.AudioAttributesCompat
|
|
7
|
+
import androidx.media.AudioFocusRequestCompat
|
|
8
|
+
import androidx.media.AudioManagerCompat
|
|
9
|
+
import com.lovegaoshi.kotlinaudio.models.PlayerOptions
|
|
10
|
+
|
|
11
|
+
class FocusManager (
|
|
12
|
+
private val context: Context,
|
|
13
|
+
private val listener: AudioManager.OnAudioFocusChangeListener,
|
|
14
|
+
options: PlayerOptions
|
|
15
|
+
) {
|
|
16
|
+
var hasAudioFocus = false
|
|
17
|
+
var alwaysPauseOnInterruption = options.alwaysPauseOnInterruption
|
|
18
|
+
private var focus: AudioFocusRequestCompat? = null
|
|
19
|
+
|
|
20
|
+
fun requestAudioFocus() {
|
|
21
|
+
if (hasAudioFocus) return
|
|
22
|
+
|
|
23
|
+
val manager = ContextCompat.getSystemService(context, AudioManager::class.java)
|
|
24
|
+
|
|
25
|
+
focus = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
|
|
26
|
+
.setOnAudioFocusChangeListener(listener)
|
|
27
|
+
.setAudioAttributes(
|
|
28
|
+
AudioAttributesCompat.Builder()
|
|
29
|
+
.setUsage(AudioAttributesCompat.USAGE_MEDIA)
|
|
30
|
+
.setContentType(AudioAttributesCompat.CONTENT_TYPE_MUSIC)
|
|
31
|
+
.build()
|
|
32
|
+
)
|
|
33
|
+
.setWillPauseWhenDucked(alwaysPauseOnInterruption)
|
|
34
|
+
.build()
|
|
35
|
+
|
|
36
|
+
val result: Int = if (manager != null && focus != null) {
|
|
37
|
+
AudioManagerCompat.requestAudioFocus(manager, focus!!)
|
|
38
|
+
} else {
|
|
39
|
+
AudioManager.AUDIOFOCUS_REQUEST_FAILED
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
hasAudioFocus = (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fun abandonAudioFocusIfHeld() {
|
|
46
|
+
if (!hasAudioFocus) return
|
|
47
|
+
|
|
48
|
+
val manager = ContextCompat.getSystemService(context, AudioManager::class.java)
|
|
49
|
+
|
|
50
|
+
val result: Int = if (manager != null && focus != null) {
|
|
51
|
+
AudioManagerCompat.abandonAudioFocusRequest(manager, focus!!)
|
|
52
|
+
} else {
|
|
53
|
+
AudioManager.AUDIOFOCUS_REQUEST_FAILED
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
hasAudioFocus = (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
package com.lovegaoshi.kotlinaudio.player.components
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Build
|
|
5
|
+
import androidx.annotation.OptIn
|
|
6
|
+
import androidx.media3.common.MediaItem
|
|
7
|
+
import androidx.media3.common.util.UnstableApi
|
|
8
|
+
import androidx.media3.datasource.DataSource
|
|
9
|
+
import androidx.media3.datasource.DataSpec
|
|
10
|
+
import androidx.media3.datasource.DefaultDataSource
|
|
11
|
+
import androidx.media3.datasource.DefaultHttpDataSource
|
|
12
|
+
import androidx.media3.datasource.RawResourceDataSource
|
|
13
|
+
import androidx.media3.datasource.cache.CacheDataSource
|
|
14
|
+
import androidx.media3.datasource.cache.SimpleCache
|
|
15
|
+
import androidx.media3.exoplayer.dash.DashMediaSource
|
|
16
|
+
import androidx.media3.exoplayer.dash.DefaultDashChunkSource
|
|
17
|
+
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider
|
|
18
|
+
import androidx.media3.exoplayer.hls.HlsMediaSource
|
|
19
|
+
import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource
|
|
20
|
+
import androidx.media3.exoplayer.smoothstreaming.SsMediaSource
|
|
21
|
+
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
|
22
|
+
import androidx.media3.exoplayer.source.MediaSource
|
|
23
|
+
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
|
24
|
+
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy
|
|
25
|
+
import androidx.media3.extractor.DefaultExtractorsFactory
|
|
26
|
+
import com.lovegaoshi.kotlinaudio.utils.isUriLocalFile
|
|
27
|
+
import androidx.core.net.toUri
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@OptIn(UnstableApi::class)
|
|
31
|
+
class MediaFactory (
|
|
32
|
+
private val context: Context,
|
|
33
|
+
private val cache: SimpleCache?
|
|
34
|
+
) : MediaSource.Factory{
|
|
35
|
+
|
|
36
|
+
private val mediaFactory = DefaultMediaSourceFactory(context)
|
|
37
|
+
|
|
38
|
+
override fun setDrmSessionManagerProvider(drmSessionManagerProvider: DrmSessionManagerProvider): MediaSource.Factory {
|
|
39
|
+
return mediaFactory.setDrmSessionManagerProvider(drmSessionManagerProvider)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override fun setLoadErrorHandlingPolicy(loadErrorHandlingPolicy: LoadErrorHandlingPolicy): MediaSource.Factory {
|
|
43
|
+
return mediaFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override fun getSupportedTypes(): IntArray {
|
|
47
|
+
return mediaFactory.supportedTypes
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override fun createMediaSource(mediaItem: MediaItem): MediaSource {
|
|
51
|
+
|
|
52
|
+
val userAgent = mediaItem.mediaMetadata.extras?.getString("user-agent")
|
|
53
|
+
val headers = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
54
|
+
mediaItem.mediaMetadata.extras?.getSerializable("headers", HashMap::class.java)
|
|
55
|
+
} else {
|
|
56
|
+
mediaItem.mediaMetadata.extras?.getSerializable("headers")
|
|
57
|
+
}
|
|
58
|
+
val resourceId = mediaItem.mediaMetadata.extras?.getInt("resource-id")
|
|
59
|
+
// HACK: why are these capitalized?
|
|
60
|
+
val resourceType = mediaItem.mediaMetadata.extras?.getString("type")?.lowercase()
|
|
61
|
+
val uri = mediaItem.mediaMetadata.extras?.getString("uri")!!.toUri()
|
|
62
|
+
val factory: DataSource.Factory = when {
|
|
63
|
+
resourceId != 0 && resourceId != null -> {
|
|
64
|
+
val raw = RawResourceDataSource(context)
|
|
65
|
+
raw.open(DataSpec(uri))
|
|
66
|
+
DataSource.Factory { raw }
|
|
67
|
+
}
|
|
68
|
+
isUriLocalFile(uri) -> {
|
|
69
|
+
DefaultDataSource.Factory(context)
|
|
70
|
+
}
|
|
71
|
+
else -> {
|
|
72
|
+
val tempFactory = DefaultHttpDataSource.Factory().apply {
|
|
73
|
+
setUserAgent(userAgent)
|
|
74
|
+
setAllowCrossProtocolRedirects(true)
|
|
75
|
+
|
|
76
|
+
headers?.let {
|
|
77
|
+
setDefaultRequestProperties(it as HashMap<String, String>)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
enableCaching(tempFactory)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return when (resourceType) {
|
|
86
|
+
"dash" -> createDashSource(mediaItem, factory)
|
|
87
|
+
"hls" -> createHlsSource(mediaItem, factory)
|
|
88
|
+
"smoothstreaming" -> createSsSource(mediaItem, factory)
|
|
89
|
+
else -> createProgressiveSource(mediaItem, factory)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private fun createDashSource(mediaItem: MediaItem, factory: DataSource.Factory?): MediaSource {
|
|
94
|
+
return DashMediaSource.Factory(DefaultDashChunkSource.Factory(factory!!), factory)
|
|
95
|
+
.createMediaSource(mediaItem)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private fun createHlsSource(mediaItem: MediaItem, factory: DataSource.Factory?): MediaSource {
|
|
99
|
+
return HlsMediaSource.Factory(factory!!)
|
|
100
|
+
.createMediaSource(mediaItem)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private fun createSsSource(mediaItem: MediaItem, factory: DataSource.Factory?): MediaSource {
|
|
104
|
+
return SsMediaSource.Factory(DefaultSsChunkSource.Factory(factory!!), factory)
|
|
105
|
+
.createMediaSource(mediaItem)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private fun createProgressiveSource(
|
|
109
|
+
mediaItem: MediaItem,
|
|
110
|
+
factory: DataSource.Factory
|
|
111
|
+
): ProgressiveMediaSource {
|
|
112
|
+
return ProgressiveMediaSource.Factory(
|
|
113
|
+
factory, DefaultExtractorsFactory()
|
|
114
|
+
.setConstantBitrateSeekingEnabled(true)
|
|
115
|
+
)
|
|
116
|
+
.createMediaSource(mediaItem)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private fun enableCaching(factory: DataSource.Factory): DataSource.Factory {
|
|
120
|
+
return if (cache == null) {
|
|
121
|
+
factory
|
|
122
|
+
} else {
|
|
123
|
+
CacheDataSource.Factory().apply {
|
|
124
|
+
setCache(cache!!)
|
|
125
|
+
setUpstreamDataSourceFactory(factory)
|
|
126
|
+
setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|