From 7b2bd1a7af61514d15a7df402c7382a66d4442e1 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 31 Mar 2024 20:56:20 -0400 Subject: [PATCH] Apply grayscale attachments preference to videos in gallery --- .../VideoGalleryContentViewController.swift | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift b/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift index 18984f68..1f44e4f6 100644 --- a/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift +++ b/Tusker/Screens/Gallery/VideoGalleryContentViewController.swift @@ -9,16 +9,19 @@ import UIKit import GalleryVC import AVFoundation +import CoreImage class VideoGalleryContentViewController: UIViewController, GalleryContentViewController { private let url: URL let caption: String? - private let item: AVPlayerItem + private var item: AVPlayerItem let player: AVPlayer @available(iOS, obsoleted: 16.0, message: "Use AVPlayer.defaultRate") @Box private var playbackSpeed: Float = 1 + private var isGrayscale: Bool + private var presentationSizeObservation: NSKeyValueObservation? private var statusObservation: NSKeyValueObservation? private var rateObservation: NSKeyValueObservation? @@ -29,8 +32,10 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon self.url = url self.caption = caption + self.isGrayscale = Preferences.shared.grayscaleImages + let asset = AVAsset(url: url) - self.item = AVPlayerItem(asset: asset) + self.item = VideoGalleryContentViewController.createItem(asset: asset) self.player = AVPlayer(playerItem: item) super.init(nibName: nil, bundle: nil) @@ -40,6 +45,25 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon fatalError("init(coder:) has not been implemented") } + private static func createItem(asset: AVAsset) -> AVPlayerItem { + let item = AVPlayerItem(asset: asset) + if Preferences.shared.grayscaleImages { + #if os(visionOS) + #warning("Use async AVVideoComposition CIFilter initializer") + #else + let filter = CIFilter(name: "CIColorMonochrome")! + filter.setValue(CIColor(red: 0.85, green: 0.85, blue: 0.85), forKey: "inputColor") + filter.setValue(1.0, forKey: "inputIntensity") + + item.videoComposition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in + filter.setValue(request.sourceImage, forKey: "inputImage") + request.finish(with: filter.outputImage!, context: nil) + }) + #endif + } + return item + } + override func viewDidLoad() { super.viewDidLoad() @@ -55,20 +79,9 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) - presentationSizeObservation = item.observe(\.presentationSize, changeHandler: { [unowned self] item, _ in - MainActor.runUnsafely { - self.preferredContentSize = item.presentationSize - self.container?.galleryContentChanged() - } - }) - statusObservation = item.observe(\.status, changeHandler: { [unowned self] item, _ in - MainActor.runUnsafely { - if item.status == .readyToPlay { - self.container?.setGalleryContentLoading(false) - statusObservation = nil - } - } - }) + preferredContentSize = item.presentationSize + + updateItemObservations() rateObservation = player.observe(\.rate, options: .old, changeHandler: { [unowned self] player, info in hideControlsWorkItem?.cancel() if player.rate > 0 && info.oldValue == 0 { @@ -84,7 +97,37 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon } }) - preferredContentSize = item.presentationSize + NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil) + } + + private func updateItemObservations() { + presentationSizeObservation = item.observe(\.presentationSize, changeHandler: { [unowned self] item, _ in + MainActor.runUnsafely { + self.preferredContentSize = item.presentationSize + self.container?.galleryContentChanged() + } + }) + statusObservation = item.observe(\.status, changeHandler: { [unowned self] item, _ in + MainActor.runUnsafely { + if item.status == .readyToPlay { + self.container?.setGalleryContentLoading(false) + statusObservation = nil + } + } + }) + } + + @objc private func preferencesChanged() { + if isGrayscale != Preferences.shared.grayscaleImages { + let isPlaying = player.rate > 0 + isGrayscale = Preferences.shared.grayscaleImages + item = VideoGalleryContentViewController.createItem(asset: item.asset) + player.replaceCurrentItem(with: item) + updateItemObservations() + if isPlaying { + player.rate = playbackSpeed + } + } } // MARK: GalleryContentViewController