From 8aa4c9129171273e981cf7c580d91230ecbfe075 Mon Sep 17 00:00:00 2001 From: Philip Su <39933441+fivecar@users.noreply.github.com> Date: Mon, 31 Jul 2023 14:08:38 -0700 Subject: [PATCH] feat: support ramping-in of volume This is an RFC for supporting the idea of fading audio in when you play. The idea would be to support AVPlayerWrapper.rampSecs, which, if set to non-zero, fades audio in every time you play. The broader proposal would be to expose this through RNTP at some point so that people can implement players where audio ramps in whenever Play is hit. Eager to hear feedback on this. Alternatives to this include having clients just `setTimeout` themselves, manually calling `setVolume` a bunch of times with incrementally-increasing values, but: a) a native implementation ramps volume much more smoothly, and b) this makes it effortless to create players that always ramp sound in. --- Example/SwiftAudio.xcodeproj/project.pbxproj | 4 +-- .../AVPlayerWrapper/AVPlayerWrapper.swift | 32 +++++++++++++++++++ .../AVPlayerWrapperProtocol.swift | 2 ++ SwiftAudioEx/Classes/AudioPlayer.swift | 5 +++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Example/SwiftAudio.xcodeproj/project.pbxproj b/Example/SwiftAudio.xcodeproj/project.pbxproj index 8e21ba2..ad45747 100644 --- a/Example/SwiftAudio.xcodeproj/project.pbxproj +++ b/Example/SwiftAudio.xcodeproj/project.pbxproj @@ -536,7 +536,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 7U2TUNKNQX; INFOPLIST_FILE = SwiftAudio/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -555,7 +555,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 7U2TUNKNQX; INFOPLIST_FILE = SwiftAudio/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift b/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift index a3e1f22..07cad8a 100755 --- a/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift +++ b/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapper.swift @@ -141,6 +141,15 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol { applyAVPlayerRate() } } + + private var _rampSecs: Double = 0.0; + var rampSecs: Double { + get { _rampSecs } + set { + _rampSecs = newValue + applyRampSecs() + } + } weak var delegate: AVPlayerWrapperDelegate? = nil @@ -406,8 +415,31 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol { } private func applyAVPlayerRate() { + if (playWhenReady) { + applyRampSecs() + } avPlayer.rate = playWhenReady ? _rate : 0 } + + private func applyRampSecs() { + if let item = self.item { + let currentTime = item.currentTime() + let params = AVMutableAudioMixInputParameters(track: item.asset.tracks(withMediaType: .audio).first) + + if (self._rampSecs > 0.0) { + let rampDuration = CMTime(seconds: self._rampSecs, preferredTimescale: 1) + + params.setVolumeRamp(fromStartVolume: 0.0, toEndVolume: avPlayer.volume, timeRange: CMTimeRange(start: currentTime, duration: rampDuration)) + } else { + params.setVolume(avPlayer.volume, at: currentTime) + } + + let audioMix = AVMutableAudioMix() + audioMix.inputParameters = [params] + + item.audioMix = audioMix + } + } } extension AVPlayerWrapper: AVPlayerObserverDelegate { diff --git a/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapperProtocol.swift b/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapperProtocol.swift index 0903339..2450f07 100755 --- a/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapperProtocol.swift +++ b/SwiftAudioEx/Classes/AVPlayerWrapper/AVPlayerWrapperProtocol.swift @@ -30,6 +30,8 @@ protocol AVPlayerWrapperProtocol: AnyObject { var playbackError: AudioPlayerError.PlaybackError? { get } var rate: Float { get set } + + var rampSecs: Double { get set } var delegate: AVPlayerWrapperDelegate? { get set } diff --git a/SwiftAudioEx/Classes/AudioPlayer.swift b/SwiftAudioEx/Classes/AudioPlayer.swift index 08bbe82..59eb4ba 100755 --- a/SwiftAudioEx/Classes/AudioPlayer.swift +++ b/SwiftAudioEx/Classes/AudioPlayer.swift @@ -137,6 +137,11 @@ public class AudioPlayer: AVPlayerWrapperDelegate { get { wrapper.rate } set { wrapper.rate = newValue } } + + public var rampSecs: Double { + get { wrapper.rampSecs } + set { wrapper.rampSecs = newValue } + } // MARK: - Init