@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,531 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AVPlayerWrapper.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 06/03/2018.
|
|
6
|
+
// Copyright © 2018 Jørgen Henrichsen. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import AVFoundation
|
|
11
|
+
import MediaPlayer
|
|
12
|
+
import UIKit
|
|
13
|
+
|
|
14
|
+
public enum PlaybackEndedReason: String {
|
|
15
|
+
case playedUntilEnd
|
|
16
|
+
case playerStopped
|
|
17
|
+
case skippedToNext
|
|
18
|
+
case skippedToPrevious
|
|
19
|
+
case jumpedToIndex
|
|
20
|
+
case cleared
|
|
21
|
+
case failed
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class AVPlayerWrapper: AVPlayerWrapperProtocol {
|
|
25
|
+
public var player: AVPlayer { avPlayer }
|
|
26
|
+
// MARK: - Properties
|
|
27
|
+
|
|
28
|
+
fileprivate var avPlayer = AVPlayer()
|
|
29
|
+
internal var audioTap: AudioTap? = nil
|
|
30
|
+
private let playerObserver = AVPlayerObserver()
|
|
31
|
+
internal let playerTimeObserver: AVPlayerTimeObserver
|
|
32
|
+
private let playerItemNotificationObserver = AVPlayerItemNotificationObserver()
|
|
33
|
+
private let playerItemObserver = AVPlayerItemObserver()
|
|
34
|
+
fileprivate var timeToSeekToAfterLoading: TimeInterval?
|
|
35
|
+
fileprivate var asset: AVAsset? = nil
|
|
36
|
+
fileprivate var item: AVPlayerItem? = nil
|
|
37
|
+
fileprivate var url: URL? = nil
|
|
38
|
+
fileprivate var urlOptions: [String: Any]? = nil
|
|
39
|
+
fileprivate let stateQueue = DispatchQueue(
|
|
40
|
+
label: "AVPlayerWrapper.stateQueue",
|
|
41
|
+
attributes: .concurrent
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
public init() {
|
|
45
|
+
playerTimeObserver = AVPlayerTimeObserver(periodicObserverTimeInterval: timeEventFrequency.getTime())
|
|
46
|
+
|
|
47
|
+
playerObserver.delegate = self
|
|
48
|
+
playerTimeObserver.delegate = self
|
|
49
|
+
playerItemNotificationObserver.delegate = self
|
|
50
|
+
playerItemObserver.delegate = self
|
|
51
|
+
|
|
52
|
+
setupAVPlayer();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// MARK: - AVPlayerWrapperProtocol
|
|
56
|
+
|
|
57
|
+
fileprivate(set) var playbackError: AudioPlayerError.PlaybackError? = nil
|
|
58
|
+
|
|
59
|
+
var _state: AVPlayerWrapperState = AVPlayerWrapperState.idle
|
|
60
|
+
var state: AVPlayerWrapperState {
|
|
61
|
+
get {
|
|
62
|
+
var state: AVPlayerWrapperState!
|
|
63
|
+
stateQueue.sync {
|
|
64
|
+
state = _state
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return state
|
|
68
|
+
}
|
|
69
|
+
set {
|
|
70
|
+
stateQueue.async(flags: .barrier) { [weak self] in
|
|
71
|
+
guard let self = self else { return }
|
|
72
|
+
let currentState = self._state
|
|
73
|
+
if (currentState != newValue) {
|
|
74
|
+
self._state = newValue
|
|
75
|
+
self.delegate?.AVWrapper(didChangeState: newValue)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fileprivate(set) var lastPlayerTimeControlStatus: AVPlayer.TimeControlStatus = AVPlayer.TimeControlStatus.paused
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
Whether AVPlayer should start playing automatically when the item is ready.
|
|
85
|
+
*/
|
|
86
|
+
public var playWhenReady: Bool = false {
|
|
87
|
+
didSet {
|
|
88
|
+
if (playWhenReady == true && (state == .failed || state == .stopped)) {
|
|
89
|
+
reload(startFromCurrentTime: state == .failed)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
applyAVPlayerRate()
|
|
93
|
+
|
|
94
|
+
if oldValue != playWhenReady {
|
|
95
|
+
delegate?.AVWrapper(didChangePlayWhenReady: playWhenReady)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var currentItem: AVPlayerItem? {
|
|
101
|
+
avPlayer.currentItem
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
var playbackActive: Bool {
|
|
105
|
+
switch state {
|
|
106
|
+
case .idle, .stopped, .ended, .failed:
|
|
107
|
+
return false
|
|
108
|
+
default: return true
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
var currentTime: TimeInterval {
|
|
113
|
+
let seconds = avPlayer.currentTime().seconds
|
|
114
|
+
return seconds.isNaN ? 0 : seconds
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var duration: TimeInterval {
|
|
118
|
+
if let seconds = currentItem?.asset.duration.seconds, !seconds.isNaN {
|
|
119
|
+
return seconds
|
|
120
|
+
}
|
|
121
|
+
else if let seconds = currentItem?.duration.seconds, !seconds.isNaN {
|
|
122
|
+
return seconds
|
|
123
|
+
}
|
|
124
|
+
else if let seconds = currentItem?.seekableTimeRanges.last?.timeRangeValue.duration.seconds,
|
|
125
|
+
!seconds.isNaN {
|
|
126
|
+
return seconds
|
|
127
|
+
}
|
|
128
|
+
return 0.0
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
var bufferedPosition: TimeInterval {
|
|
132
|
+
currentItem?.loadedTimeRanges.last?.timeRangeValue.end.seconds ?? 0
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var reasonForWaitingToPlay: AVPlayer.WaitingReason? {
|
|
136
|
+
avPlayer.reasonForWaitingToPlay
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private var _rate: Float = 1.0;
|
|
140
|
+
var rate: Float {
|
|
141
|
+
get { _rate }
|
|
142
|
+
set {
|
|
143
|
+
_rate = newValue
|
|
144
|
+
applyAVPlayerRate()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
weak var delegate: AVPlayerWrapperDelegate? = nil
|
|
149
|
+
|
|
150
|
+
var bufferDuration: TimeInterval = 0
|
|
151
|
+
|
|
152
|
+
var timeEventFrequency: TimeEventFrequency = .everySecond {
|
|
153
|
+
didSet {
|
|
154
|
+
playerTimeObserver.periodicObserverTimeInterval = timeEventFrequency.getTime()
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
var volume: Float {
|
|
159
|
+
get { avPlayer.volume }
|
|
160
|
+
set { avPlayer.volume = newValue }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var isMuted: Bool {
|
|
164
|
+
get { avPlayer.isMuted }
|
|
165
|
+
set { avPlayer.isMuted = newValue }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
var automaticallyWaitsToMinimizeStalling: Bool {
|
|
169
|
+
get { avPlayer.automaticallyWaitsToMinimizeStalling }
|
|
170
|
+
set { avPlayer.automaticallyWaitsToMinimizeStalling = newValue }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
func play() {
|
|
174
|
+
playWhenReady = true
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
func pause() {
|
|
178
|
+
playWhenReady = false
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
func togglePlaying() {
|
|
182
|
+
switch avPlayer.timeControlStatus {
|
|
183
|
+
case .playing, .waitingToPlayAtSpecifiedRate:
|
|
184
|
+
pause()
|
|
185
|
+
case .paused:
|
|
186
|
+
play()
|
|
187
|
+
@unknown default:
|
|
188
|
+
fatalError("Unknown AVPlayer.timeControlStatus")
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
func stop() {
|
|
193
|
+
state = .stopped
|
|
194
|
+
clearCurrentItem()
|
|
195
|
+
playWhenReady = false
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
func seek(to seconds: TimeInterval) {
|
|
199
|
+
// if the player is loading then we need to defer seeking until it's ready.
|
|
200
|
+
if (avPlayer.currentItem == nil) {
|
|
201
|
+
timeToSeekToAfterLoading = seconds
|
|
202
|
+
} else {
|
|
203
|
+
let time = CMTimeMakeWithSeconds(seconds, preferredTimescale: 1000)
|
|
204
|
+
avPlayer.seek(to: time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) { (finished) in
|
|
205
|
+
self.delegate?.AVWrapper(seekTo: Double(seconds), didFinish: finished)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
func seek(by seconds: TimeInterval) {
|
|
211
|
+
if let currentItem = avPlayer.currentItem {
|
|
212
|
+
let time = currentItem.currentTime().seconds + seconds
|
|
213
|
+
avPlayer.seek(
|
|
214
|
+
to: CMTimeMakeWithSeconds(time, preferredTimescale: 1000)
|
|
215
|
+
) { (finished) in
|
|
216
|
+
self.delegate?.AVWrapper(seekTo: Double(time), didFinish: finished)
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
if let timeToSeekToAfterLoading = timeToSeekToAfterLoading {
|
|
220
|
+
self.timeToSeekToAfterLoading = timeToSeekToAfterLoading + seconds
|
|
221
|
+
} else {
|
|
222
|
+
timeToSeekToAfterLoading = seconds
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private func playbackFailed(error: AudioPlayerError.PlaybackError) {
|
|
228
|
+
state = .failed
|
|
229
|
+
self.playbackError = error
|
|
230
|
+
self.delegate?.AVWrapper(failedWithError: error)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
func load() {
|
|
234
|
+
if (state == .failed) {
|
|
235
|
+
recreateAVPlayer()
|
|
236
|
+
} else {
|
|
237
|
+
clearCurrentItem()
|
|
238
|
+
}
|
|
239
|
+
if let url = url {
|
|
240
|
+
let pendingAsset = AVURLAsset(url: url, options: urlOptions)
|
|
241
|
+
asset = pendingAsset
|
|
242
|
+
state = .loading
|
|
243
|
+
|
|
244
|
+
// Load metadata keys asynchronously and separate from playable, to allow that to execute as quickly as it can
|
|
245
|
+
let metdataKeys = ["commonMetadata", "availableChapterLocales", "availableMetadataFormats"]
|
|
246
|
+
pendingAsset.loadValuesAsynchronously(forKeys: metdataKeys, completionHandler: { [weak self] in
|
|
247
|
+
guard let self = self else { return }
|
|
248
|
+
if (pendingAsset != self.asset) { return; }
|
|
249
|
+
|
|
250
|
+
let commonData = pendingAsset.commonMetadata
|
|
251
|
+
if (!commonData.isEmpty) {
|
|
252
|
+
self.delegate?.AVWrapper(didReceiveCommonMetadata: commonData)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if pendingAsset.availableChapterLocales.count > 0 {
|
|
256
|
+
for locale in pendingAsset.availableChapterLocales {
|
|
257
|
+
let chapters = pendingAsset.chapterMetadataGroups(withTitleLocale: locale, containingItemsWithCommonKeys: nil)
|
|
258
|
+
self.delegate?.AVWrapper(didReceiveChapterMetadata: chapters)
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
for format in pendingAsset.availableMetadataFormats {
|
|
262
|
+
let timeRange = CMTimeRange(start: CMTime(seconds: 0, preferredTimescale: 1000), end: pendingAsset.duration)
|
|
263
|
+
let group = AVTimedMetadataGroup(items: pendingAsset.metadata(forFormat: format), timeRange: timeRange)
|
|
264
|
+
self.delegate?.AVWrapper(didReceiveTimedMetadata: [group])
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
// Load playable portion of the track and commence when ready
|
|
270
|
+
let playableKeys = ["playable"]
|
|
271
|
+
pendingAsset.loadValuesAsynchronously(forKeys: playableKeys, completionHandler: { [weak self] in
|
|
272
|
+
guard let self = self else { return }
|
|
273
|
+
|
|
274
|
+
DispatchQueue.main.async {
|
|
275
|
+
if (pendingAsset != self.asset) { return; }
|
|
276
|
+
|
|
277
|
+
for key in playableKeys {
|
|
278
|
+
var error: NSError?
|
|
279
|
+
let keyStatus = pendingAsset.statusOfValue(forKey: key, error: &error)
|
|
280
|
+
switch keyStatus {
|
|
281
|
+
case .failed:
|
|
282
|
+
self.playbackFailed(error: AudioPlayerError.PlaybackError.failedToLoadKeyValue)
|
|
283
|
+
return
|
|
284
|
+
case .cancelled, .loading, .unknown:
|
|
285
|
+
return
|
|
286
|
+
case .loaded:
|
|
287
|
+
break
|
|
288
|
+
default: break
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (!pendingAsset.isPlayable) {
|
|
293
|
+
self.playbackFailed(error: AudioPlayerError.PlaybackError.itemWasUnplayable)
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let item = AVPlayerItem(
|
|
298
|
+
asset: pendingAsset,
|
|
299
|
+
automaticallyLoadedAssetKeys: playableKeys
|
|
300
|
+
)
|
|
301
|
+
self.item = item;
|
|
302
|
+
item.preferredForwardBufferDuration = self.bufferDuration
|
|
303
|
+
self.avPlayer.replaceCurrentItem(with: item)
|
|
304
|
+
self.startObservingAVPlayer(item: item)
|
|
305
|
+
self.applyAVPlayerRate()
|
|
306
|
+
|
|
307
|
+
if let initialTime = self.timeToSeekToAfterLoading {
|
|
308
|
+
self.timeToSeekToAfterLoading = nil
|
|
309
|
+
self.seek(to: initialTime)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
func load(from url: URL, playWhenReady: Bool, options: [String: Any]? = nil) {
|
|
317
|
+
self.playWhenReady = playWhenReady
|
|
318
|
+
self.url = url
|
|
319
|
+
self.urlOptions = options
|
|
320
|
+
self.load()
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
func load(
|
|
324
|
+
from url: URL,
|
|
325
|
+
playWhenReady: Bool,
|
|
326
|
+
initialTime: TimeInterval? = nil,
|
|
327
|
+
options: [String : Any]? = nil
|
|
328
|
+
) {
|
|
329
|
+
self.load(from: url, playWhenReady: playWhenReady, options: options)
|
|
330
|
+
if let initialTime = initialTime {
|
|
331
|
+
self.seek(to: initialTime)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
func load(
|
|
336
|
+
from url: String,
|
|
337
|
+
type: SourceType = .stream,
|
|
338
|
+
playWhenReady: Bool = false,
|
|
339
|
+
initialTime: TimeInterval? = nil,
|
|
340
|
+
options: [String : Any]? = nil
|
|
341
|
+
) {
|
|
342
|
+
if let itemUrl = type == .file
|
|
343
|
+
? URL(fileURLWithPath: url)
|
|
344
|
+
: URL(string: url)
|
|
345
|
+
{
|
|
346
|
+
self.load(from: itemUrl, playWhenReady: playWhenReady, options: options)
|
|
347
|
+
if let initialTime = initialTime {
|
|
348
|
+
self.seek(to: initialTime)
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
clearCurrentItem()
|
|
352
|
+
playbackFailed(error: AudioPlayerError.PlaybackError.invalidSourceUrl(url))
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
func unload() {
|
|
357
|
+
clearCurrentItem()
|
|
358
|
+
state = .idle
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
func reload(startFromCurrentTime: Bool) {
|
|
362
|
+
var time : Double? = nil
|
|
363
|
+
if (startFromCurrentTime) {
|
|
364
|
+
if let currentItem = currentItem {
|
|
365
|
+
if (!currentItem.duration.isIndefinite) {
|
|
366
|
+
time = currentItem.currentTime().seconds
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
load()
|
|
371
|
+
if let time = time {
|
|
372
|
+
seek(to: time)
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// MARK: - Util
|
|
377
|
+
|
|
378
|
+
private func clearCurrentItem() {
|
|
379
|
+
guard let asset = asset else { return }
|
|
380
|
+
stopObservingAVPlayerItem()
|
|
381
|
+
|
|
382
|
+
asset.cancelLoading()
|
|
383
|
+
self.asset = nil
|
|
384
|
+
|
|
385
|
+
avPlayer.replaceCurrentItem(with: nil)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private func startObservingAVPlayer(item: AVPlayerItem) {
|
|
389
|
+
playerItemObserver.startObserving(item: item)
|
|
390
|
+
playerItemNotificationObserver.startObserving(item: item)
|
|
391
|
+
attachTap(audioTap, to: item)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private func stopObservingAVPlayerItem() {
|
|
395
|
+
playerItemObserver.stopObservingCurrentItem()
|
|
396
|
+
playerItemNotificationObserver.stopObservingCurrentItem()
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private func recreateAVPlayer() {
|
|
400
|
+
playbackError = nil
|
|
401
|
+
playerTimeObserver.unregisterForBoundaryTimeEvents()
|
|
402
|
+
playerTimeObserver.unregisterForPeriodicEvents()
|
|
403
|
+
playerObserver.stopObserving()
|
|
404
|
+
stopObservingAVPlayerItem()
|
|
405
|
+
clearCurrentItem()
|
|
406
|
+
|
|
407
|
+
avPlayer = AVPlayer()
|
|
408
|
+
setupAVPlayer()
|
|
409
|
+
|
|
410
|
+
// Update global reference and notify.
|
|
411
|
+
RNTrackPlayer.sharedAVPlayer = avPlayer
|
|
412
|
+
NotificationCenter.default.post(name: .RNTPPlayerRecreated, object: nil)
|
|
413
|
+
|
|
414
|
+
delegate?.AVWrapperDidRecreateAVPlayer()
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
private func setupAVPlayer() {
|
|
418
|
+
// disabled since we're not making use of video playback
|
|
419
|
+
avPlayer.allowsExternalPlayback = false;
|
|
420
|
+
|
|
421
|
+
playerObserver.player = avPlayer
|
|
422
|
+
playerObserver.startObserving()
|
|
423
|
+
|
|
424
|
+
playerTimeObserver.player = avPlayer
|
|
425
|
+
playerTimeObserver.registerForBoundaryTimeEvents()
|
|
426
|
+
playerTimeObserver.registerForPeriodicTimeEvents()
|
|
427
|
+
|
|
428
|
+
applyAVPlayerRate()
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
private func applyAVPlayerRate() {
|
|
432
|
+
avPlayer.rate = playWhenReady ? _rate : 0
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
extension AVPlayerWrapper: AVPlayerObserverDelegate {
|
|
437
|
+
|
|
438
|
+
// MARK: - AVPlayerObserverDelegate
|
|
439
|
+
|
|
440
|
+
func player(didChangeTimeControlStatus status: AVPlayer.TimeControlStatus) {
|
|
441
|
+
switch status {
|
|
442
|
+
case .paused:
|
|
443
|
+
let state = self.state
|
|
444
|
+
if self.asset == nil && state != .stopped {
|
|
445
|
+
self.state = .idle
|
|
446
|
+
} else if (state != .failed && state != .stopped) {
|
|
447
|
+
// Playback may have become paused externally for example due to a bluetooth device disconnecting:
|
|
448
|
+
if (self.playWhenReady) {
|
|
449
|
+
// Only if we are not on the boundaries of the track, otherwise itemDidPlayToEndTime will handle it instead.
|
|
450
|
+
if (self.currentTime > 0 && self.currentTime < self.duration) {
|
|
451
|
+
self.playWhenReady = false;
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
self.state = .paused
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
case .waitingToPlayAtSpecifiedRate:
|
|
458
|
+
if self.asset != nil {
|
|
459
|
+
self.state = .buffering
|
|
460
|
+
}
|
|
461
|
+
case .playing:
|
|
462
|
+
self.state = .playing
|
|
463
|
+
@unknown default:
|
|
464
|
+
break
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
func player(statusDidChange status: AVPlayer.Status) {
|
|
469
|
+
if (status == .failed) {
|
|
470
|
+
let error = item!.error as NSError?
|
|
471
|
+
playbackFailed(error: error?.code == URLError.notConnectedToInternet.rawValue
|
|
472
|
+
? AudioPlayerError.PlaybackError.notConnectedToInternet
|
|
473
|
+
: AudioPlayerError.PlaybackError.playbackFailed
|
|
474
|
+
)
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
extension AVPlayerWrapper: AVPlayerTimeObserverDelegate {
|
|
480
|
+
|
|
481
|
+
// MARK: - AVPlayerTimeObserverDelegate
|
|
482
|
+
|
|
483
|
+
func audioDidStart() {
|
|
484
|
+
state = .playing
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
func timeEvent(time: CMTime) {
|
|
488
|
+
delegate?.AVWrapper(secondsElapsed: time.seconds)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
extension AVPlayerWrapper: AVPlayerItemNotificationObserverDelegate {
|
|
494
|
+
// MARK: - AVPlayerItemNotificationObserverDelegate
|
|
495
|
+
|
|
496
|
+
func itemFailedToPlayToEndTime() {
|
|
497
|
+
playbackFailed(error: AudioPlayerError.PlaybackError.playbackFailed)
|
|
498
|
+
delegate?.AVWrapperItemFailedToPlayToEndTime()
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
func itemPlaybackStalled() {
|
|
502
|
+
delegate?.AVWrapperItemPlaybackStalled()
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
func itemDidPlayToEndTime() {
|
|
506
|
+
delegate?.AVWrapperItemDidPlayToEndTime()
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
extension AVPlayerWrapper: AVPlayerItemObserverDelegate {
|
|
512
|
+
// MARK: - AVPlayerItemObserverDelegate
|
|
513
|
+
|
|
514
|
+
func item(didUpdatePlaybackLikelyToKeepUp playbackLikelyToKeepUp: Bool) {
|
|
515
|
+
if (playbackLikelyToKeepUp && state != .playing) {
|
|
516
|
+
state = .ready
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
func item(didUpdateDuration duration: Double) {
|
|
521
|
+
delegate?.AVWrapper(didUpdateDuration: duration)
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
func item(didReceiveTimedMetadata metadata: [AVTimedMetadataGroup]) {
|
|
525
|
+
delegate?.AVWrapper(didReceiveTimedMetadata: metadata)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
extension Notification.Name {
|
|
530
|
+
static let RNTPPlayerRecreated = Notification.Name("RNTPPlayerRecreated")
|
|
531
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AVPlayerWrapperDelegate.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 26/10/2018.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import MediaPlayer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
protocol AVPlayerWrapperDelegate: AnyObject {
|
|
13
|
+
|
|
14
|
+
func AVWrapper(didChangeState state: AVPlayerWrapperState)
|
|
15
|
+
func AVWrapper(secondsElapsed seconds: Double)
|
|
16
|
+
func AVWrapper(failedWithError error: Error?)
|
|
17
|
+
func AVWrapper(seekTo seconds: Double, didFinish: Bool)
|
|
18
|
+
func AVWrapper(didUpdateDuration duration: Double)
|
|
19
|
+
func AVWrapper(didReceiveCommonMetadata metadata: [AVMetadataItem])
|
|
20
|
+
func AVWrapper(didReceiveChapterMetadata metadata: [AVTimedMetadataGroup])
|
|
21
|
+
func AVWrapper(didReceiveTimedMetadata metadata: [AVTimedMetadataGroup])
|
|
22
|
+
func AVWrapper(didChangePlayWhenReady playWhenReady: Bool)
|
|
23
|
+
func AVWrapperItemDidPlayToEndTime()
|
|
24
|
+
func AVWrapperItemFailedToPlayToEndTime()
|
|
25
|
+
func AVWrapperItemPlaybackStalled()
|
|
26
|
+
func AVWrapperDidRecreateAVPlayer()
|
|
27
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AVPlayerWrapperProtocol.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 26/10/2018.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import AVFoundation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
protocol AVPlayerWrapperProtocol: AnyObject {
|
|
13
|
+
|
|
14
|
+
var audioTap: AudioTap? { get set }
|
|
15
|
+
|
|
16
|
+
var state: AVPlayerWrapperState { get set }
|
|
17
|
+
|
|
18
|
+
var playWhenReady: Bool { get set }
|
|
19
|
+
|
|
20
|
+
var currentItem: AVPlayerItem? { get }
|
|
21
|
+
|
|
22
|
+
var playbackActive: Bool { get }
|
|
23
|
+
|
|
24
|
+
var currentTime: TimeInterval { get }
|
|
25
|
+
|
|
26
|
+
var duration: TimeInterval { get }
|
|
27
|
+
|
|
28
|
+
var bufferedPosition: TimeInterval { get }
|
|
29
|
+
|
|
30
|
+
var reasonForWaitingToPlay: AVPlayer.WaitingReason? { get }
|
|
31
|
+
|
|
32
|
+
var playbackError: AudioPlayerError.PlaybackError? { get }
|
|
33
|
+
|
|
34
|
+
var rate: Float { get set }
|
|
35
|
+
|
|
36
|
+
var delegate: AVPlayerWrapperDelegate? { get set }
|
|
37
|
+
|
|
38
|
+
var bufferDuration: TimeInterval { get set }
|
|
39
|
+
|
|
40
|
+
var timeEventFrequency: TimeEventFrequency { get set }
|
|
41
|
+
|
|
42
|
+
var volume: Float { get set }
|
|
43
|
+
|
|
44
|
+
var isMuted: Bool { get set }
|
|
45
|
+
|
|
46
|
+
var automaticallyWaitsToMinimizeStalling: Bool { get set }
|
|
47
|
+
|
|
48
|
+
func play()
|
|
49
|
+
|
|
50
|
+
func pause()
|
|
51
|
+
|
|
52
|
+
func togglePlaying()
|
|
53
|
+
|
|
54
|
+
func stop()
|
|
55
|
+
|
|
56
|
+
func seek(to seconds: TimeInterval)
|
|
57
|
+
|
|
58
|
+
func seek(by offset: TimeInterval)
|
|
59
|
+
|
|
60
|
+
func load(from url: URL, playWhenReady: Bool, options: [String: Any]?)
|
|
61
|
+
|
|
62
|
+
func load(from url: URL, playWhenReady: Bool, initialTime: TimeInterval?, options: [String: Any]?)
|
|
63
|
+
|
|
64
|
+
func load(from url: String, type: SourceType, playWhenReady: Bool, initialTime: TimeInterval?, options: [String: Any]?)
|
|
65
|
+
|
|
66
|
+
func unload()
|
|
67
|
+
|
|
68
|
+
func reload(startFromCurrentTime: Bool)
|
|
69
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AVPlayerWrapperState.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 10/03/2018.
|
|
6
|
+
// Copyright © 2018 Jørgen Henrichsen. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
The current state of the AudioPlayer.
|
|
14
|
+
*/
|
|
15
|
+
public enum AVPlayerWrapperState: String {
|
|
16
|
+
|
|
17
|
+
/// An asset is being loaded for playback.
|
|
18
|
+
case loading
|
|
19
|
+
|
|
20
|
+
/// The current item is loaded, and the player is ready to start playing.
|
|
21
|
+
case ready
|
|
22
|
+
|
|
23
|
+
/// The current item is playing, but are currently buffering.
|
|
24
|
+
case buffering
|
|
25
|
+
|
|
26
|
+
/// The player is paused.
|
|
27
|
+
case paused
|
|
28
|
+
|
|
29
|
+
/// The player is stopped.
|
|
30
|
+
case stopped
|
|
31
|
+
|
|
32
|
+
/// The player is playing.
|
|
33
|
+
case playing
|
|
34
|
+
|
|
35
|
+
/// No item loaded, the player is stopped.
|
|
36
|
+
case idle
|
|
37
|
+
|
|
38
|
+
/// Failed
|
|
39
|
+
case failed
|
|
40
|
+
|
|
41
|
+
/// Playback has reached the end.
|
|
42
|
+
case ended
|
|
43
|
+
}
|