diff --git a/AVPlayerFade.xcodeproj/project.pbxproj b/AVPlayerFade.xcodeproj/project.pbxproj index 71aeb7c..81f70ed 100644 --- a/AVPlayerFade.xcodeproj/project.pbxproj +++ b/AVPlayerFade.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 78629A462ABB716F00A29C2A /* sample.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 78629A452ABB716F00A29C2A /* sample.mp3 */; }; 943BC86A24764A7400249743 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943BC86924764A7400249743 /* AppDelegate.swift */; }; 943BC86C24764A7400249743 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943BC86B24764A7400249743 /* SceneDelegate.swift */; }; 943BC86E24764A7400249743 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943BC86D24764A7400249743 /* ViewController.swift */; }; @@ -17,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 78629A452ABB716F00A29C2A /* sample.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = sample.mp3; sourceTree = ""; }; 943BC86624764A7400249743 /* AVPlayerFade.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AVPlayerFade.app; sourceTree = BUILT_PRODUCTS_DIR; }; 943BC86924764A7400249743 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 943BC86B24764A7400249743 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -62,6 +64,7 @@ 943BC86B24764A7400249743 /* SceneDelegate.swift */, 943BC86D24764A7400249743 /* ViewController.swift */, 94BB669C247693EF00B79C21 /* AVPlayerExtensions.swift */, + 78629A452ABB716F00A29C2A /* sample.mp3 */, 943BC86F24764A7400249743 /* Main.storyboard */, 943BC87224764A7600249743 /* Assets.xcassets */, 943BC87424764A7600249743 /* LaunchScreen.storyboard */, @@ -130,6 +133,7 @@ files = ( 943BC87624764A7600249743 /* LaunchScreen.storyboard in Resources */, 943BC87324764A7600249743 /* Assets.xcassets in Resources */, + 78629A462ABB716F00A29C2A /* sample.mp3 in Resources */, 943BC87124764A7400249743 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/AVPlayerFade.xcodeproj/project.xcworkspace/xcuserdata/tushar.xcuserdatad/UserInterfaceState.xcuserstate b/AVPlayerFade.xcodeproj/project.xcworkspace/xcuserdata/tushar.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..4bb9c36 Binary files /dev/null and b/AVPlayerFade.xcodeproj/project.xcworkspace/xcuserdata/tushar.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..ff682cf --- /dev/null +++ b/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcschemes/xcschememanagement.plist b/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..77cb2db --- /dev/null +++ b/AVPlayerFade.xcodeproj/xcuserdata/tushar.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + AVPlayerFade.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/AVPlayerFade/AVPlayerExtensions.swift b/AVPlayerFade/AVPlayerExtensions.swift index e47743e..2bb64d2 100644 --- a/AVPlayerFade/AVPlayerExtensions.swift +++ b/AVPlayerFade/AVPlayerExtensions.swift @@ -17,7 +17,7 @@ extension AVPlayer { /// - duration: duration in seconds for the fade /// - completion: callback indicating completion /// - Returns: Timer? - func fadeVolume(from: Float, to: Float, duration: Float, completion: (() -> Void)? = nil) -> Timer? { + func fadeInVolume(from: Float, to: Float, duration: Float, completion: (() -> Void)? = nil) -> Timer? { // 1. Set Initial volume volume = from @@ -63,4 +63,48 @@ extension AVPlayer { } }) } + + func fadeOutVolume(from: Float, to: Float, duration: Double, completion: (() -> Void)? = nil) -> Timer? { + + volume = from + guard from != to else { return nil } + + let interval: Float = 0.1 + let range = from - to + let step = (range*interval) / Float(duration) + + func reachedTarget() -> Bool { + + guard volume >= 0, volume <= 1 else { + volume = from + return true + } + + if from > to { + return volume <= to + } + return volume >= to + } + + return Timer.scheduledTimer(withTimeInterval: Double(interval), repeats: true, block: { [weak self] (timer) in + guard let self = self else { return } + + DispatchQueue.main.async { + + if !reachedTarget() { + if let currentItem = self.currentItem { + let totalDuration = CMTimeGetSeconds(currentItem.duration) + let currentTime = CMTimeGetSeconds(currentItem.currentTime()) + let fadeOutTime = totalDuration - duration + if currentTime >= fadeOutTime { + self.volume -= step + } + } + } else { + timer.invalidate() + completion?() + } + } + }) + } } diff --git a/AVPlayerFade/ViewController.swift b/AVPlayerFade/ViewController.swift index 531ec2d..ecd8e73 100644 --- a/AVPlayerFade/ViewController.swift +++ b/AVPlayerFade/ViewController.swift @@ -22,14 +22,16 @@ class ViewController: UIViewController { private func setupPlayer() { // Setup player - let url = URL(string: "https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3")! + guard let url = Bundle.main.url(forResource: "sample", withExtension: "mp3") else { return } let item = AVPlayerItem(url: url) player.replaceCurrentItem(with: item) player.volume = 0 player.play() // Fade player volume from 0 to 1 in 5 seconds - fadeTimer = player.fadeVolume(from: 0, to: 1, duration: 5) + fadeTimer = player.fadeInVolume(from: 0, to: 1, duration: 5) + // or + // fadeTimer = player.fadeOutVolume(from: 1, to: 0, duration: 5) } } diff --git a/AVPlayerFade/sample.mp3 b/AVPlayerFade/sample.mp3 new file mode 100644 index 0000000..36b4be0 Binary files /dev/null and b/AVPlayerFade/sample.mp3 differ