Last active
April 11, 2025 15:13
-
-
Save kshivang/4c213ec85adf911d30f1305722e7129d to your computer and use it in GitHub Desktop.
Revisions
-
kshivang revised this gist
Mar 11, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ import Combine // simply use // player.periodicTimePublisher() // .receive(on: RunLoop.main) // .assign(to: \SomeClass.elapsedTime, on: someInstance) // .store(in: &cancelBag) -
kshivang revised this gist
Mar 11, 2020 . No changes.There are no files selected for viewing
-
kshivang revised this gist
Mar 11, 2020 . No changes.There are no files selected for viewing
-
kshivang created this gist
Mar 11, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,65 @@ import AVFoundation import Combine // simply use // player.periodicTimePublisher() // .receive(on: RunLoop.main) // .assign(to: elapsedSec) // .store(in: &cancelBag) extension AVPlayer { func periodicTimePublisher(forInterval interval: CMTime = CMTime(seconds: 0.5, preferredTimescale: CMTimeScale(NSEC_PER_SEC))) -> AnyPublisher<CMTime, Never> { Publisher(self, forInterval: interval) .eraseToAnyPublisher() } } fileprivate extension AVPlayer { private struct Publisher: Combine.Publisher { typealias Output = CMTime typealias Failure = Never var player: AVPlayer var interval: CMTime init(_ player: AVPlayer, forInterval interval: CMTime) { self.player = player self.interval = interval } func receive<S>(subscriber: S) where S : Subscriber, Publisher.Failure == S.Failure, Publisher.Output == S.Input { let subscription = CMTime.Subscription(subscriber: subscriber, player: player, forInterval: interval) subscriber.receive(subscription: subscription) } } } fileprivate extension CMTime { final class Subscription<SubscriberType: Subscriber>: Combine.Subscription where SubscriberType.Input == CMTime, SubscriberType.Failure == Never { var player: AVPlayer? = nil var observer: Any? = nil init(subscriber: SubscriberType, player: AVPlayer, forInterval interval: CMTime) { self.player = player observer = player.addPeriodicTimeObserver(forInterval: interval, queue: nil) { time in _ = subscriber.receive(time) } } func request(_ demand: Subscribers.Demand) { // We do nothing here as we only want to send events when they occur. // See, for more info: https://developer.apple.com/documentation/combine/subscribers/demand } func cancel() { if let observer = observer { player?.removeTimeObserver(observer) } observer = nil player = nil } } }