Tusker/Tusker/Screens/Gallery/GrayscalableVideoGalleryContentViewController.swift

84 lines
2.8 KiB
Swift

//
// GrayscalableVideoGalleryContentViewController.swift
// Tusker
//
// Created by Shadowfacts on 11/21/24.
// Copyright © 2024 Shadowfacts. All rights reserved.
//
import UIKit
import GalleryVC
import AVFoundation
class GrayscalableVideoGalleryContentViewController: GalleryVC.VideoGalleryContentViewController {
private var audioSessionToken: AudioSessionCoordinator.Token?
private var isGrayscale: Bool
private var isFirstAppearance = true
override init(url: URL, caption: String?) {
self.isGrayscale = Preferences.shared.grayscaleImages
super.init(url: url, caption: caption)
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override class 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
}
@objc private func preferencesChanged() {
if isGrayscale != Preferences.shared.grayscaleImages {
let isPlaying = player.rate > 0
isGrayscale = Preferences.shared.grayscaleImages
replaceCurrentItem(with: Self.createItem(asset: item.asset))
if isPlaying {
player.play()
}
}
}
override func galleryContentDidAppear() {
super.galleryContentDidAppear()
let wasFirstAppearance = isFirstAppearance
isFirstAppearance = false
audioSessionToken = AudioSessionCoordinator.shared.beginPlayback(mode: .video) {
if wasFirstAppearance {
DispatchQueue.main.async {
self.player.play()
}
}
}
}
override func galleryContentWillDisappear() {
super.galleryContentWillDisappear()
if let audioSessionToken {
AudioSessionCoordinator.shared.endPlayback(token: audioSessionToken)
}
}
}