@javascriptcommon/react-native-track-player 1.2.23 → 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/README.md +8 -0
- package/android/build.gradle +80 -63
- package/android/proguard-rules.txt +0 -3
- package/android/src/main/AndroidManifest.xml +10 -11
- 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/{guichaguri → doublesymmetry}/trackplayer/extensions/AudioPlayerStateExt.kt +3 -3
- 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/{guichaguri → doublesymmetry}/trackplayer/model/MetadataAdapter.kt +20 -17
- package/android/src/main/java/com/doublesymmetry/trackplayer/model/NowPlayingMetadata.kt +16 -0
- package/android/src/main/java/com/{guichaguri/trackplayer/kotlinaudio/models → doublesymmetry/trackplayer/model}/PlaybackMetadata.kt +31 -28
- package/android/src/main/java/com/{guichaguri → doublesymmetry}/trackplayer/model/State.kt +1 -1
- 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/{guichaguri → doublesymmetry}/trackplayer/module/MusicEvents.kt +10 -9
- 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/{guichaguri/trackplayer/service → doublesymmetry/trackplayer/utils}/BundleUtils.kt +50 -20
- 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/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/event/EventHolder.kt +7 -7
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/event/PlayerEventHolder.kt +22 -9
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioContentType.kt +1 -1
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/AudioItem.kt +118 -0
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioItemTransitionReason.kt +3 -3
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/AudioPlayerState.kt +2 -2
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/BufferConfig.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/CacheConfig.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/Capability.kt +1 -1
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/CustomButton.kt +19 -0
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/FocusChangeData.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/MediaSessionCallback.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlayWhenReadyChangeData.kt +1 -3
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlaybackEndedReason.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlaybackError.kt +1 -1
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PlayerConfig.kt +8 -5
- package/android/src/main/java/com/lovegaoshi/kotlinaudio/models/PlayerOptions.kt +40 -0
- package/android/src/main/java/com/{guichaguri/trackplayer → lovegaoshi}/kotlinaudio/models/PositionChangedReason.kt +1 -1
- 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/{guichaguri/trackplayer/kotlinaudio/players → lovegaoshi/kotlinaudio/player}/QueuedAudioPlayer.kt +68 -58
- 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 +3 -4
- 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/ic_home-playstore.png +0 -0
- package/android/src/main/ic_repeat-playstore.png +0 -0
- package/android/src/main/ic_repeat_50-playstore.png +0 -0
- package/android/src/main/ic_shuffle-playstore.png +0 -0
- package/android/src/main/ic_shuffle_50-playstore.png +0 -0
- package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
- package/android/src/main/ic_stop-playstore.png +0 -0
- package/android/src/main/ic_test-playstore.png +0 -0
- package/android/src/main/java/com/guichaguri/trackplayer/HeadlessJsMediaService.java +0 -225
- package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +0 -25
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +0 -20
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +0 -10
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +0 -66
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +0 -43
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +0 -8
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +0 -8
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +0 -9
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +0 -49
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +0 -678
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +0 -10
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +0 -864
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +0 -35
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +0 -26
- package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +0 -12
- package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +0 -120
- package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +0 -19
- package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +0 -11
- package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +0 -151
- package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +0 -1177
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +0 -31
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +0 -347
- package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +0 -1254
- package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +0 -228
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +0 -141
- package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +0 -396
- package/android/src/main/res/drawable-hdpi/ic_forward.png +0 -0
- package/android/src/main/res/drawable-hdpi/ic_home.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_home.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_home.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_home.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_home.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/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
- package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
- package/android/src/main/res/strings.xml +0 -6
- package/index.d.ts +0 -235
- 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 -178
- /package/ios/{TrackPlayer.xcodeproj → Example/SwiftAudio.xcodeproj}/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RemoteCommand.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 20/03/2018.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import MediaPlayer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
public typealias RemoteCommandHandler = (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus
|
|
13
|
+
|
|
14
|
+
public protocol RemoteCommandProtocol {
|
|
15
|
+
associatedtype Command: MPRemoteCommand
|
|
16
|
+
|
|
17
|
+
var id: String { get }
|
|
18
|
+
var commandKeyPath: KeyPath<MPRemoteCommandCenter, Command> { get }
|
|
19
|
+
var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler> { get }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public struct PlayBackCommand: RemoteCommandProtocol {
|
|
23
|
+
|
|
24
|
+
public static let play = PlayBackCommand(id: "Play", commandKeyPath: \MPRemoteCommandCenter.playCommand, handlerKeyPath: \RemoteCommandController.handlePlayCommand)
|
|
25
|
+
|
|
26
|
+
public static let pause = PlayBackCommand(id: "Pause", commandKeyPath: \MPRemoteCommandCenter.pauseCommand, handlerKeyPath: \RemoteCommandController.handlePauseCommand)
|
|
27
|
+
|
|
28
|
+
public static let stop = PlayBackCommand(id: "Stop", commandKeyPath: \MPRemoteCommandCenter.stopCommand, handlerKeyPath: \RemoteCommandController.handleStopCommand)
|
|
29
|
+
|
|
30
|
+
public static let togglePlayPause = PlayBackCommand(id: "TogglePlayPause", commandKeyPath: \MPRemoteCommandCenter.togglePlayPauseCommand, handlerKeyPath: \RemoteCommandController.handleTogglePlayPauseCommand)
|
|
31
|
+
|
|
32
|
+
public static let nextTrack = PlayBackCommand(id: "NextTrackCommand", commandKeyPath: \MPRemoteCommandCenter.nextTrackCommand, handlerKeyPath: \RemoteCommandController.handleNextTrackCommand)
|
|
33
|
+
|
|
34
|
+
public static let previousTrack = PlayBackCommand(id: "PreviousTrack", commandKeyPath: \MPRemoteCommandCenter.previousTrackCommand, handlerKeyPath: \RemoteCommandController.handlePreviousTrackCommand)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
public typealias Command = MPRemoteCommand
|
|
38
|
+
|
|
39
|
+
public let id: String
|
|
40
|
+
|
|
41
|
+
public var commandKeyPath: KeyPath<MPRemoteCommandCenter, MPRemoteCommand>
|
|
42
|
+
|
|
43
|
+
public var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler>
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public struct ChangePlaybackPositionCommand: RemoteCommandProtocol {
|
|
48
|
+
|
|
49
|
+
public static let changePlaybackPosition = ChangePlaybackPositionCommand(id: "ChangePlaybackPosition", commandKeyPath: \MPRemoteCommandCenter.changePlaybackPositionCommand, handlerKeyPath: \RemoteCommandController.handleChangePlaybackPositionCommand)
|
|
50
|
+
|
|
51
|
+
public typealias Command = MPChangePlaybackPositionCommand
|
|
52
|
+
|
|
53
|
+
public let id: String
|
|
54
|
+
|
|
55
|
+
public var commandKeyPath: KeyPath<MPRemoteCommandCenter, MPChangePlaybackPositionCommand>
|
|
56
|
+
|
|
57
|
+
public var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler>
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public struct SkipIntervalCommand: RemoteCommandProtocol {
|
|
62
|
+
|
|
63
|
+
public static let skipForward = SkipIntervalCommand(id: "SkipForward", commandKeyPath: \MPRemoteCommandCenter.skipForwardCommand, handlerKeyPath: \RemoteCommandController.handleSkipForwardCommand)
|
|
64
|
+
|
|
65
|
+
public static let skipBackward = SkipIntervalCommand(id: "SkipBackward", commandKeyPath: \MPRemoteCommandCenter.skipBackwardCommand, handlerKeyPath: \RemoteCommandController.handleSkipBackwardCommand)
|
|
66
|
+
|
|
67
|
+
public typealias Command = MPSkipIntervalCommand
|
|
68
|
+
|
|
69
|
+
public let id: String
|
|
70
|
+
|
|
71
|
+
public var commandKeyPath: KeyPath<MPRemoteCommandCenter, MPSkipIntervalCommand>
|
|
72
|
+
|
|
73
|
+
public var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler>
|
|
74
|
+
|
|
75
|
+
func set(preferredIntervals: [NSNumber]) -> SkipIntervalCommand {
|
|
76
|
+
MPRemoteCommandCenter.shared()[keyPath: commandKeyPath].preferredIntervals = preferredIntervals
|
|
77
|
+
return self
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public struct FeedbackCommand: RemoteCommandProtocol {
|
|
83
|
+
|
|
84
|
+
public static let like = FeedbackCommand(id: "Like", commandKeyPath: \MPRemoteCommandCenter.likeCommand, handlerKeyPath: \RemoteCommandController.handleLikeCommand)
|
|
85
|
+
|
|
86
|
+
public static let dislike = FeedbackCommand(id: "Dislike", commandKeyPath: \MPRemoteCommandCenter.dislikeCommand, handlerKeyPath: \RemoteCommandController.handleDislikeCommand)
|
|
87
|
+
|
|
88
|
+
public static let bookmark = FeedbackCommand(id: "Bookmark", commandKeyPath: \MPRemoteCommandCenter.bookmarkCommand, handlerKeyPath: \RemoteCommandController.handleBookmarkCommand)
|
|
89
|
+
|
|
90
|
+
public typealias Command = MPFeedbackCommand
|
|
91
|
+
|
|
92
|
+
public let id: String
|
|
93
|
+
|
|
94
|
+
public var commandKeyPath: KeyPath<MPRemoteCommandCenter, MPFeedbackCommand>
|
|
95
|
+
|
|
96
|
+
public var handlerKeyPath: KeyPath<RemoteCommandController, RemoteCommandHandler>
|
|
97
|
+
|
|
98
|
+
func set(isActive: Bool, localizedTitle: String, localizedShortTitle: String) -> FeedbackCommand {
|
|
99
|
+
MPRemoteCommandCenter.shared()[keyPath: commandKeyPath].isActive = isActive
|
|
100
|
+
MPRemoteCommandCenter.shared()[keyPath: commandKeyPath].localizedTitle = localizedTitle
|
|
101
|
+
MPRemoteCommandCenter.shared()[keyPath: commandKeyPath].localizedShortTitle = localizedShortTitle
|
|
102
|
+
return self
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public enum RemoteCommand: CustomStringConvertible {
|
|
107
|
+
|
|
108
|
+
case play
|
|
109
|
+
|
|
110
|
+
case pause
|
|
111
|
+
|
|
112
|
+
case stop
|
|
113
|
+
|
|
114
|
+
case togglePlayPause
|
|
115
|
+
|
|
116
|
+
case next
|
|
117
|
+
|
|
118
|
+
case previous
|
|
119
|
+
|
|
120
|
+
case changePlaybackPosition
|
|
121
|
+
|
|
122
|
+
case skipForward(preferredIntervals: [NSNumber])
|
|
123
|
+
|
|
124
|
+
case skipBackward(preferredIntervals: [NSNumber])
|
|
125
|
+
|
|
126
|
+
case like(isActive: Bool, localizedTitle: String, localizedShortTitle: String)
|
|
127
|
+
|
|
128
|
+
case dislike(isActive: Bool, localizedTitle: String, localizedShortTitle: String)
|
|
129
|
+
|
|
130
|
+
case bookmark(isActive: Bool, localizedTitle: String, localizedShortTitle: String)
|
|
131
|
+
|
|
132
|
+
public var description: String {
|
|
133
|
+
switch self {
|
|
134
|
+
case .play: return "play"
|
|
135
|
+
case .pause: return "pause"
|
|
136
|
+
case .stop: return "stop"
|
|
137
|
+
case .togglePlayPause: return "togglePlayPause"
|
|
138
|
+
case .next: return "nextTrack"
|
|
139
|
+
case .previous: return "previousTrack"
|
|
140
|
+
case .changePlaybackPosition: return "changePlaybackPosition"
|
|
141
|
+
case .skipForward(_): return "skipForward"
|
|
142
|
+
case .skipBackward(_): return "skipBackward"
|
|
143
|
+
case .like(_, _, _): return "like"
|
|
144
|
+
case .dislike(_, _, _): return "dislike"
|
|
145
|
+
case .bookmark(_, _, _): return "bookmark"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
All values in an array for convenience.
|
|
151
|
+
Don't use for associated values.
|
|
152
|
+
*/
|
|
153
|
+
static func all() -> [RemoteCommand] {
|
|
154
|
+
return [
|
|
155
|
+
.play,
|
|
156
|
+
.pause,
|
|
157
|
+
.stop,
|
|
158
|
+
.togglePlayPause,
|
|
159
|
+
.next,
|
|
160
|
+
.previous,
|
|
161
|
+
.changePlaybackPosition,
|
|
162
|
+
.skipForward(preferredIntervals: []),
|
|
163
|
+
.skipBackward(preferredIntervals: []),
|
|
164
|
+
.like(isActive: false, localizedTitle: "", localizedShortTitle: ""),
|
|
165
|
+
.dislike(isActive: false, localizedTitle: "", localizedShortTitle: ""),
|
|
166
|
+
.bookmark(isActive: false, localizedTitle: "", localizedShortTitle: "")
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
}
|
package/ios/SwiftAudioEx/Sources/SwiftAudioEx/RemoteCommandController/RemoteCommandController.swift
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
//
|
|
2
|
+
// File.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 20/03/2018.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import MediaPlayer
|
|
10
|
+
|
|
11
|
+
public protocol RemoteCommandable {
|
|
12
|
+
func getCommands() -> [RemoteCommand]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public class RemoteCommandController {
|
|
16
|
+
|
|
17
|
+
private let center: MPRemoteCommandCenter
|
|
18
|
+
|
|
19
|
+
weak var audioPlayer: AudioPlayer?
|
|
20
|
+
|
|
21
|
+
var commandTargetPointers: [String: Any] = [:]
|
|
22
|
+
private var enabledCommands: [RemoteCommand] = []
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
Create a new RemoteCommandController.
|
|
26
|
+
|
|
27
|
+
- parameter remoteCommandCenter: The MPRemoteCommandCenter used. Default is `MPRemoteCommandCenter.shared()`
|
|
28
|
+
*/
|
|
29
|
+
public init(remoteCommandCenter: MPRemoteCommandCenter = MPRemoteCommandCenter.shared()) {
|
|
30
|
+
center = remoteCommandCenter
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
internal func enable(commands: [RemoteCommand]) {
|
|
34
|
+
let commandsToDisable = enabledCommands.filter { command in
|
|
35
|
+
!commands.contains(where: { $0.description == command.description })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
enabledCommands = commands
|
|
39
|
+
commands.forEach { self.enable(command: $0) }
|
|
40
|
+
disable(commands: commandsToDisable)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
internal func disable(commands: [RemoteCommand]) {
|
|
44
|
+
commands.forEach { self.disable(command: $0) }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private func enableCommand<Command: RemoteCommandProtocol>(_ command: Command) {
|
|
48
|
+
center[keyPath: command.commandKeyPath].isEnabled = true
|
|
49
|
+
center[keyPath: command.commandKeyPath].removeTarget(commandTargetPointers[command.id])
|
|
50
|
+
commandTargetPointers[command.id] = center[keyPath: command.commandKeyPath].addTarget(handler: self[keyPath: command.handlerKeyPath])
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private func disableCommand<Command: RemoteCommandProtocol>(_ command: Command) {
|
|
54
|
+
center[keyPath: command.commandKeyPath].isEnabled = false
|
|
55
|
+
center[keyPath: command.commandKeyPath].removeTarget(commandTargetPointers[command.id])
|
|
56
|
+
commandTargetPointers.removeValue(forKey: command.id)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private func enable(command: RemoteCommand) {
|
|
60
|
+
switch command {
|
|
61
|
+
case .play: self.enableCommand(PlayBackCommand.play)
|
|
62
|
+
case .pause: self.enableCommand(PlayBackCommand.pause)
|
|
63
|
+
case .stop: self.enableCommand(PlayBackCommand.stop)
|
|
64
|
+
case .togglePlayPause: self.enableCommand(PlayBackCommand.togglePlayPause)
|
|
65
|
+
case .next: self.enableCommand(PlayBackCommand.nextTrack)
|
|
66
|
+
case .previous: self.enableCommand(PlayBackCommand.previousTrack)
|
|
67
|
+
case .changePlaybackPosition: self.enableCommand(ChangePlaybackPositionCommand.changePlaybackPosition)
|
|
68
|
+
case .skipForward(let preferredIntervals): self.enableCommand(SkipIntervalCommand.skipForward.set(preferredIntervals: preferredIntervals))
|
|
69
|
+
case .skipBackward(let preferredIntervals): self.enableCommand(SkipIntervalCommand.skipBackward.set(preferredIntervals: preferredIntervals))
|
|
70
|
+
case .like(let isActive, let localizedTitle, let localizedShortTitle):
|
|
71
|
+
self.enableCommand(FeedbackCommand.like.set(isActive: isActive, localizedTitle: localizedTitle, localizedShortTitle: localizedShortTitle))
|
|
72
|
+
case .dislike(let isActive, let localizedTitle, let localizedShortTitle):
|
|
73
|
+
self.enableCommand(FeedbackCommand.dislike.set(isActive: isActive, localizedTitle: localizedTitle, localizedShortTitle: localizedShortTitle))
|
|
74
|
+
case .bookmark(let isActive, let localizedTitle, let localizedShortTitle):
|
|
75
|
+
self.enableCommand(FeedbackCommand.bookmark.set(isActive: isActive, localizedTitle: localizedTitle, localizedShortTitle: localizedShortTitle))
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private func disable(command: RemoteCommand) {
|
|
80
|
+
switch command {
|
|
81
|
+
case .play: self.disableCommand(PlayBackCommand.play)
|
|
82
|
+
case .pause: self.disableCommand(PlayBackCommand.pause)
|
|
83
|
+
case .stop: self.disableCommand(PlayBackCommand.stop)
|
|
84
|
+
case .togglePlayPause: self.disableCommand(PlayBackCommand.togglePlayPause)
|
|
85
|
+
case .next: self.disableCommand(PlayBackCommand.nextTrack)
|
|
86
|
+
case .previous: self.disableCommand(PlayBackCommand.previousTrack)
|
|
87
|
+
case .changePlaybackPosition: self.disableCommand(ChangePlaybackPositionCommand.changePlaybackPosition)
|
|
88
|
+
case .skipForward(_): self.disableCommand(SkipIntervalCommand.skipForward)
|
|
89
|
+
case .skipBackward(_): self.disableCommand(SkipIntervalCommand.skipBackward)
|
|
90
|
+
case .like(_, _, _): self.disableCommand(FeedbackCommand.like)
|
|
91
|
+
case .dislike(_, _, _): self.disableCommand(FeedbackCommand.dislike)
|
|
92
|
+
case .bookmark(_, _, _): self.disableCommand(FeedbackCommand.bookmark)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// MARK: - Handlers
|
|
97
|
+
|
|
98
|
+
public lazy var handlePlayCommand: RemoteCommandHandler = handlePlayCommandDefault
|
|
99
|
+
public lazy var handlePauseCommand: RemoteCommandHandler = handlePauseCommandDefault
|
|
100
|
+
public lazy var handleStopCommand: RemoteCommandHandler = handleStopCommandDefault
|
|
101
|
+
public lazy var handleTogglePlayPauseCommand: RemoteCommandHandler = handleTogglePlayPauseCommandDefault
|
|
102
|
+
public lazy var handleSkipForwardCommand: RemoteCommandHandler = handleSkipForwardCommandDefault
|
|
103
|
+
public lazy var handleSkipBackwardCommand: RemoteCommandHandler = handleSkipBackwardDefault
|
|
104
|
+
public lazy var handleChangePlaybackPositionCommand: RemoteCommandHandler = handleChangePlaybackPositionCommandDefault
|
|
105
|
+
public lazy var handleNextTrackCommand: RemoteCommandHandler = handleNextTrackCommandDefault
|
|
106
|
+
public lazy var handlePreviousTrackCommand: RemoteCommandHandler = handlePreviousTrackCommandDefault
|
|
107
|
+
public lazy var handleLikeCommand: RemoteCommandHandler = handleLikeCommandDefault
|
|
108
|
+
public lazy var handleDislikeCommand: RemoteCommandHandler = handleDislikeCommandDefault
|
|
109
|
+
public lazy var handleBookmarkCommand: RemoteCommandHandler = handleBookmarkCommandDefault
|
|
110
|
+
|
|
111
|
+
private func handlePlayCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
112
|
+
if let audioPlayer = audioPlayer {
|
|
113
|
+
audioPlayer.play()
|
|
114
|
+
return MPRemoteCommandHandlerStatus.success
|
|
115
|
+
}
|
|
116
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private func handlePauseCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
120
|
+
if let audioPlayer = audioPlayer {
|
|
121
|
+
audioPlayer.pause()
|
|
122
|
+
return MPRemoteCommandHandlerStatus.success
|
|
123
|
+
}
|
|
124
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private func handleStopCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
128
|
+
if let audioPlayer = audioPlayer {
|
|
129
|
+
audioPlayer.stop()
|
|
130
|
+
return .success
|
|
131
|
+
}
|
|
132
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private func handleTogglePlayPauseCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
136
|
+
if let audioPlayer = audioPlayer {
|
|
137
|
+
audioPlayer.togglePlaying()
|
|
138
|
+
return MPRemoteCommandHandlerStatus.success
|
|
139
|
+
}
|
|
140
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private func handleSkipForwardCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
144
|
+
if let command = event.command as? MPSkipIntervalCommand,
|
|
145
|
+
let interval = command.preferredIntervals.first,
|
|
146
|
+
let audioPlayer = audioPlayer {
|
|
147
|
+
audioPlayer.seek(to: audioPlayer.currentTime + Double(truncating: interval))
|
|
148
|
+
return MPRemoteCommandHandlerStatus.success
|
|
149
|
+
}
|
|
150
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private func handleSkipBackwardDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
154
|
+
if let command = event.command as? MPSkipIntervalCommand,
|
|
155
|
+
let interval = command.preferredIntervals.first,
|
|
156
|
+
let audioPlayer = audioPlayer {
|
|
157
|
+
audioPlayer.seek(to: audioPlayer.currentTime - Double(truncating: interval))
|
|
158
|
+
return MPRemoteCommandHandlerStatus.success
|
|
159
|
+
}
|
|
160
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private func handleChangePlaybackPositionCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
164
|
+
if let event = event as? MPChangePlaybackPositionCommandEvent,
|
|
165
|
+
let audioPlayer = audioPlayer {
|
|
166
|
+
audioPlayer.seek(to: event.positionTime)
|
|
167
|
+
return MPRemoteCommandHandlerStatus.success
|
|
168
|
+
}
|
|
169
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private func handleNextTrackCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
173
|
+
if let player = audioPlayer as? QueuedAudioPlayer {
|
|
174
|
+
player.next()
|
|
175
|
+
return MPRemoteCommandHandlerStatus.success
|
|
176
|
+
}
|
|
177
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private func handlePreviousTrackCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
181
|
+
if let player = audioPlayer as? QueuedAudioPlayer {
|
|
182
|
+
player.previous()
|
|
183
|
+
return MPRemoteCommandHandlerStatus.success
|
|
184
|
+
}
|
|
185
|
+
return MPRemoteCommandHandlerStatus.commandFailed
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private func handleLikeCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
189
|
+
MPRemoteCommandHandlerStatus.success
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private func handleDislikeCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
193
|
+
MPRemoteCommandHandlerStatus.success
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private func handleBookmarkCommandDefault(event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
|
|
197
|
+
MPRemoteCommandHandlerStatus.success
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private func getRemoteCommandHandlerStatus(forError error: Error) -> MPRemoteCommandHandlerStatus {
|
|
201
|
+
return error is AudioPlayerError.QueueError
|
|
202
|
+
? MPRemoteCommandHandlerStatus.noSuchContent
|
|
203
|
+
: MPRemoteCommandHandlerStatus.commandFailed
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RepeatMode.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by David Chavez on 29.05.21.
|
|
6
|
+
// Copyright © 2021 Double Symmmery. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
public enum RepeatMode: Int {
|
|
12
|
+
case off
|
|
13
|
+
case track
|
|
14
|
+
case queue
|
|
15
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// TimeEventFrequency.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by Jørgen Henrichsen on 11/03/2018.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import AVFoundation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
public enum TimeEventFrequency {
|
|
13
|
+
case everySecond
|
|
14
|
+
case everyHalfSecond
|
|
15
|
+
case everyQuarterSecond
|
|
16
|
+
case custom(time: CMTime)
|
|
17
|
+
|
|
18
|
+
func getTime() -> CMTime {
|
|
19
|
+
switch self {
|
|
20
|
+
case .everySecond: return CMTime(value: 1, timescale: 1)
|
|
21
|
+
case .everyHalfSecond: return CMTime(value: 1, timescale: 2)
|
|
22
|
+
case .everyQuarterSecond: return CMTime(value: 1, timescale: 4)
|
|
23
|
+
case .custom(let time): return time
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//
|
|
2
|
+
// DispatchQueueType.swift
|
|
3
|
+
// SwiftAudio
|
|
4
|
+
//
|
|
5
|
+
// Created by David Chavez on 29.05.21.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
public protocol DispatchQueueType {
|
|
11
|
+
func async(flags: DispatchWorkItemFlags, execute work: @escaping @convention(block) () -> Void)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
extension DispatchQueue: DispatchQueueType {
|
|
15
|
+
public func async(flags: DispatchWorkItemFlags, execute work: @escaping @convention(block) () -> Void) {
|
|
16
|
+
async(group: nil, qos: .unspecified, flags: flags, execute: work)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
//
|
|
2
|
+
// WaveformAudioTap.swift
|
|
3
|
+
// SwiftAudioEx
|
|
4
|
+
//
|
|
5
|
+
// Created by Rachel on 8/11/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import CoreAudio
|
|
10
|
+
import Accelerate
|
|
11
|
+
|
|
12
|
+
struct AudioAnalysis {
|
|
13
|
+
let amplitude: Float // Overall amplitude (0-1)
|
|
14
|
+
let eqBands: [Float] // Normalized energy in each frequency band (0-1)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public class WaveformAudioTap: AudioTap {
|
|
18
|
+
static var outputs = [String]()
|
|
19
|
+
|
|
20
|
+
// Frequency ranges for EQ bands (in Hz)
|
|
21
|
+
// HACK: i dont think this works; need to review, but it compiles nonetheless
|
|
22
|
+
private let frequencyRanges = [
|
|
23
|
+
(20, 60), // Sub bass
|
|
24
|
+
(60, 250), // Bass
|
|
25
|
+
(250, 500), // Low mids
|
|
26
|
+
(500, 2000), // Mids
|
|
27
|
+
(2000, 4000), // Upper mids
|
|
28
|
+
(4000, 20000) // Highs
|
|
29
|
+
]
|
|
30
|
+
private let fftLength: Int
|
|
31
|
+
|
|
32
|
+
private let emit: (_ data: Any?) -> Void
|
|
33
|
+
private var fftSetup: vDSP_DFT_Setup?
|
|
34
|
+
|
|
35
|
+
let tapIndex: Int
|
|
36
|
+
|
|
37
|
+
public init(
|
|
38
|
+
mFFTLength: Int = 1024,
|
|
39
|
+
mEmit: @escaping (_ data: Any) -> Void = { print($0) }
|
|
40
|
+
){
|
|
41
|
+
self.tapIndex = 0
|
|
42
|
+
self.fftLength = mFFTLength
|
|
43
|
+
self.emit = mEmit
|
|
44
|
+
fftSetup = vDSP_DFT_zop_CreateSetup(
|
|
45
|
+
nil,
|
|
46
|
+
UInt(mFFTLength),
|
|
47
|
+
vDSP_DFT_Direction.FORWARD
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
deinit {
|
|
52
|
+
if let setup = fftSetup {
|
|
53
|
+
vDSP_DFT_DestroySetup(setup)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public override func initialize() {
|
|
58
|
+
Self.outputs.append("audioTap \(tapIndex): initialize")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public override func finalize() {
|
|
62
|
+
Self.outputs.append("audioTap \(tapIndex): finalize")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public override func prepare(description: AudioStreamBasicDescription) {
|
|
66
|
+
Self.outputs.append("audioTap \(tapIndex): prepare")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public override func unprepare() {
|
|
70
|
+
Self.outputs.append("audioTap \(tapIndex): unprepare")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public override func process(numberOfFrames: Int, buffer: UnsafeMutableAudioBufferListPointer) {
|
|
74
|
+
Self.outputs.append("audioTap \(tapIndex): process")
|
|
75
|
+
// Get the first buffer (assuming mono/first channel of stereo)
|
|
76
|
+
let firstBuffer = buffer[0]
|
|
77
|
+
guard firstBuffer.mData != nil else {
|
|
78
|
+
self.emit([
|
|
79
|
+
"amplitude": 0,
|
|
80
|
+
"data": Array(repeating: 0, count: frequencyRanges.count)
|
|
81
|
+
])
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Convert buffer data to array of floats
|
|
86
|
+
let frameLength = Int(firstBuffer.mDataByteSize) / MemoryLayout<Float>.size
|
|
87
|
+
let audioData = UnsafeBufferPointer<Float>(
|
|
88
|
+
start: firstBuffer.mData?.assumingMemoryBound(to: Float.self),
|
|
89
|
+
count: frameLength
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
// Calculate RMS amplitude
|
|
93
|
+
var rms: Float = 0
|
|
94
|
+
vDSP_rmsqv(audioData.baseAddress!, 1, &rms, UInt(frameLength))
|
|
95
|
+
|
|
96
|
+
// Prepare for FFT
|
|
97
|
+
var realPart = [Float](repeating: 0, count: fftLength)
|
|
98
|
+
var imagPart = [Float](repeating: 0, count: fftLength)
|
|
99
|
+
|
|
100
|
+
// Copy audio data to real part, zero-padding if necessary
|
|
101
|
+
let copyLength = min(frameLength, fftLength)
|
|
102
|
+
realPart.withUnsafeMutableBufferPointer { realPtr in
|
|
103
|
+
_ = audioData.prefix(copyLength).enumerated().map { realPtr[$0.0] = $0.1 }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Apply Hanning window
|
|
107
|
+
var window = [Float](repeating: 0, count: fftLength)
|
|
108
|
+
vDSP_hann_window(&window, UInt(fftLength), Int32(vDSP_HANN_NORM))
|
|
109
|
+
vDSP_vmul(realPart, 1, window, 1, &realPart, 1, UInt(fftLength))
|
|
110
|
+
|
|
111
|
+
// Perform FFT
|
|
112
|
+
realPart.withUnsafeMutableBufferPointer { realPtr in
|
|
113
|
+
imagPart.withUnsafeMutableBufferPointer { imagPtr in
|
|
114
|
+
var splitComplex = DSPSplitComplex(
|
|
115
|
+
realp: realPtr.baseAddress!,
|
|
116
|
+
imagp: imagPtr.baseAddress!
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if let fftSetup = fftSetup {
|
|
120
|
+
vDSP_DFT_Execute(fftSetup,
|
|
121
|
+
realPtr.baseAddress!,
|
|
122
|
+
imagPtr.baseAddress!,
|
|
123
|
+
splitComplex.realp,
|
|
124
|
+
splitComplex.imagp)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Calculate magnitude spectrum
|
|
128
|
+
var magnitudes = [Float](repeating: 0, count: fftLength/2)
|
|
129
|
+
vDSP_zvmags(&splitComplex, 1, &magnitudes, 1, UInt(fftLength/2))
|
|
130
|
+
|
|
131
|
+
// Calculate frequency resolution
|
|
132
|
+
let sampleRate: Float = 44100 // Adjust based on your audio format
|
|
133
|
+
let frequencyResolution = sampleRate / Float(fftLength)
|
|
134
|
+
|
|
135
|
+
// Calculate energy in each frequency band
|
|
136
|
+
var eqBands: [Float] = []
|
|
137
|
+
|
|
138
|
+
for (lowFreq, highFreq) in frequencyRanges {
|
|
139
|
+
let lowBin = Int(Float(lowFreq) / frequencyResolution)
|
|
140
|
+
let highBin = min(Int(Float(highFreq) / frequencyResolution), magnitudes.count)
|
|
141
|
+
|
|
142
|
+
let bandMagnitudes = Array(magnitudes[lowBin..<highBin])
|
|
143
|
+
var bandEnergy: Float = 0
|
|
144
|
+
vDSP_meanv(bandMagnitudes, 1, &bandEnergy, UInt(bandMagnitudes.count))
|
|
145
|
+
|
|
146
|
+
// Convert to dB scale and normalize
|
|
147
|
+
let dbValue = 20 * log10(bandEnergy + 1e-6)
|
|
148
|
+
let normalizedValue = (dbValue + 60) / 60 // Normalize to 0-1 range
|
|
149
|
+
eqBands.append(max(0, min(1, normalizedValue)))
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
self.emit([
|
|
153
|
+
"amplitude": rms,
|
|
154
|
+
"data": eqBands
|
|
155
|
+
])
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|