Compare commits
3 Commits
f0ec372f50
...
7b2bd1a7af
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 7b2bd1a7af | |
Shadowfacts | f447150bbc | |
Shadowfacts | 08bd78d51b |
|
@ -9,16 +9,19 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import GalleryVC
|
import GalleryVC
|
||||||
import AVFoundation
|
import AVFoundation
|
||||||
|
import CoreImage
|
||||||
|
|
||||||
class VideoGalleryContentViewController: UIViewController, GalleryContentViewController {
|
class VideoGalleryContentViewController: UIViewController, GalleryContentViewController {
|
||||||
private let url: URL
|
private let url: URL
|
||||||
let caption: String?
|
let caption: String?
|
||||||
private let item: AVPlayerItem
|
private var item: AVPlayerItem
|
||||||
let player: AVPlayer
|
let player: AVPlayer
|
||||||
|
|
||||||
@available(iOS, obsoleted: 16.0, message: "Use AVPlayer.defaultRate")
|
@available(iOS, obsoleted: 16.0, message: "Use AVPlayer.defaultRate")
|
||||||
@Box private var playbackSpeed: Float = 1
|
@Box private var playbackSpeed: Float = 1
|
||||||
|
|
||||||
|
private var isGrayscale: Bool
|
||||||
|
|
||||||
private var presentationSizeObservation: NSKeyValueObservation?
|
private var presentationSizeObservation: NSKeyValueObservation?
|
||||||
private var statusObservation: NSKeyValueObservation?
|
private var statusObservation: NSKeyValueObservation?
|
||||||
private var rateObservation: NSKeyValueObservation?
|
private var rateObservation: NSKeyValueObservation?
|
||||||
|
@ -29,8 +32,10 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
|
||||||
self.url = url
|
self.url = url
|
||||||
self.caption = caption
|
self.caption = caption
|
||||||
|
|
||||||
|
self.isGrayscale = Preferences.shared.grayscaleImages
|
||||||
|
|
||||||
let asset = AVAsset(url: url)
|
let asset = AVAsset(url: url)
|
||||||
self.item = AVPlayerItem(asset: asset)
|
self.item = VideoGalleryContentViewController.createItem(asset: asset)
|
||||||
self.player = AVPlayer(playerItem: item)
|
self.player = AVPlayer(playerItem: item)
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
@ -40,6 +45,25 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
|
||||||
fatalError("init(coder:) has not been implemented")
|
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() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
@ -55,20 +79,9 @@ class VideoGalleryContentViewController: UIViewController, GalleryContentViewCon
|
||||||
playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||||
])
|
])
|
||||||
|
|
||||||
presentationSizeObservation = item.observe(\.presentationSize, changeHandler: { [unowned self] item, _ in
|
preferredContentSize = item.presentationSize
|
||||||
MainActor.runUnsafely {
|
|
||||||
self.preferredContentSize = item.presentationSize
|
updateItemObservations()
|
||||||
self.container?.galleryContentChanged()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
statusObservation = item.observe(\.status, changeHandler: { [unowned self] item, _ in
|
|
||||||
MainActor.runUnsafely {
|
|
||||||
if item.status == .readyToPlay {
|
|
||||||
self.container?.setGalleryContentLoading(false)
|
|
||||||
statusObservation = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
rateObservation = player.observe(\.rate, options: .old, changeHandler: { [unowned self] player, info in
|
rateObservation = player.observe(\.rate, options: .old, changeHandler: { [unowned self] player, info in
|
||||||
hideControlsWorkItem?.cancel()
|
hideControlsWorkItem?.cancel()
|
||||||
if player.rate > 0 && info.oldValue == 0 {
|
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
|
// MARK: GalleryContentViewController
|
||||||
|
|
|
@ -62,10 +62,14 @@ class GifvController {
|
||||||
@objc private func preferencesChanged() {
|
@objc private func preferencesChanged() {
|
||||||
if isGrayscale != Preferences.shared.grayscaleImages {
|
if isGrayscale != Preferences.shared.grayscaleImages {
|
||||||
isGrayscale = Preferences.shared.grayscaleImages
|
isGrayscale = Preferences.shared.grayscaleImages
|
||||||
|
let oldItem = item
|
||||||
item = GifvController.createItem(asset: asset)
|
item = GifvController.createItem(asset: asset)
|
||||||
player.replaceCurrentItem(with: item)
|
player.replaceCurrentItem(with: item)
|
||||||
self.updatePresentationSizeObservation()
|
self.updatePresentationSizeObservation()
|
||||||
player.play()
|
player.play()
|
||||||
|
|
||||||
|
NotificationCenter.default.removeObserver(self, name: AVPlayerItem.didPlayToEndTimeNotification, object: oldItem)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(restartItem), name: AVPlayerItem.didPlayToEndTimeNotification, object: item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,13 +79,12 @@ class GifvController {
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
#warning("Use async AVVideoComposition CIFilter initializer")
|
#warning("Use async AVVideoComposition CIFilter initializer")
|
||||||
#else
|
#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
|
item.videoComposition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { (request) in
|
||||||
let filter = CIFilter(name: "CIColorMonochrome")!
|
|
||||||
|
|
||||||
filter.setValue(request.sourceImage, forKey: "inputImage")
|
filter.setValue(request.sourceImage, forKey: "inputImage")
|
||||||
filter.setValue(CIColor(red: 0.85, green: 0.85, blue: 0.85), forKey: "inputColor")
|
|
||||||
filter.setValue(1.0, forKey: "inputIntensity")
|
|
||||||
|
|
||||||
request.finish(with: filter.outputImage!, context: nil)
|
request.finish(with: filter.outputImage!, context: nil)
|
||||||
})
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue