forked from shadowfacts/Tusker
84 lines
2.8 KiB
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)
|
|
}
|
|
}
|
|
|
|
}
|