import Foundation import UIKit import AVFoundation final class ResultPreviewView: UIView { let composition: AVComposition let player: AVPlayer let playerLayer: AVPlayerLayer var didPlayToEndTimeObserver: NSObjectProtocol? var trimRange: Range? { didSet { if let trimRange = self.trimRange { self.player.currentItem?.forwardPlaybackEndTime = CMTime(seconds: trimRange.upperBound, preferredTimescale: CMTimeScale(1000)) } else { self.player.currentItem?.forwardPlaybackEndTime = .invalid } } } init(composition: AVComposition) { self.composition = composition self.player = AVPlayer(playerItem: AVPlayerItem(asset: composition)) self.player.isMuted = true self.playerLayer = AVPlayerLayer(player: self.player) super.init(frame: .zero) self.layer.addSublayer(self.playerLayer) self.didPlayToEndTimeObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: nil, using: { [weak self] notification in guard let self else { return } var start: Double = 0.0 if let trimRange = self.trimRange { start = trimRange.lowerBound } self.player.pause() self.seek(to: start, andPlay: true) }) self.player.play() } required public init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } deinit { if let didPlayToEndTimeObserver = self.didPlayToEndTimeObserver { NotificationCenter.default.removeObserver(didPlayToEndTimeObserver) } } func updateTrimRange(start: Double, end: Double, updatedEnd: Bool, apply: Bool) { if !apply { self.player.pause() } else { self.trimRange = start..