// // AssetPreviewViewController.swift // Tusker // // Created by Shadowfacts on 1/4/20. // Copyright © 2020 Shadowfacts. All rights reserved. // import UIKit import Photos import PhotosUI import AVKit class AssetPreviewViewController: UIViewController { let attachment: CompositionAttachmentData init(attachment: CompositionAttachmentData) { self.attachment = attachment super.init(nibName: nil, bundle: nil) } convenience init(asset: PHAsset) { self.init(attachment: .asset(asset)) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .black switch attachment { case let .image(image): showImage(image) case let .video(url): showVideo(asset: AVURLAsset(url: url)) case let .asset(asset): switch asset.mediaType { case .image: if asset.mediaSubtypes.contains(.photoLive) { showLivePhoto(asset) } else { showAssetImage(asset) } case .video: showAssetVideo(asset) default: fatalError("asset mediaType must be image or video") } case let .drawing(drawing): let image = drawing.imageInLightMode(from: drawing.bounds) showImage(image) } } func showImage(_ image: UIImage) { let imageView = UIImageView(image: image) imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFit view.addSubview(imageView) NSLayoutConstraint.activate([ imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), imageView.topAnchor.constraint(equalTo: view.topAnchor), imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) preferredContentSize = image.size } func showAssetImage(_ asset: PHAsset) { let options = PHImageRequestOptions() options.version = .current options.deliveryMode = .opportunistic options.resizeMode = .none options.isNetworkAccessAllowed = true PHImageManager.default().requestImage(for: asset, targetSize: view.bounds.size, contentMode: .aspectFit, options: options) { (image, _) in DispatchQueue.main.async { self.showImage(image!) } } } func showLivePhoto(_ asset: PHAsset) { let options = PHLivePhotoRequestOptions() options.deliveryMode = .opportunistic options.version = .current options.isNetworkAccessAllowed = true PHImageManager.default().requestLivePhoto(for: asset, targetSize: view.bounds.size, contentMode: .aspectFit, options: options) { (livePhoto, _) in guard let livePhoto = livePhoto else { fatalError("failed to get live photo") } DispatchQueue.main.async { let livePhotoView = PHLivePhotoView() livePhotoView.livePhoto = livePhoto livePhotoView.isMuted = true livePhotoView.startPlayback(with: .full) livePhotoView.translatesAutoresizingMaskIntoConstraints = false livePhotoView.contentMode = .scaleAspectFit self.view.addSubview(livePhotoView) NSLayoutConstraint.activate([ livePhotoView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), livePhotoView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), livePhotoView.topAnchor.constraint(equalTo: self.view.topAnchor), livePhotoView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) self.preferredContentSize = livePhoto.size } } } func showVideo(asset: AVAsset) { let playerController = AVPlayerViewController() let item = AVPlayerItem(asset: asset) let player = AVPlayer(playerItem: item) player.isMuted = true player.play() playerController.player = player self.embedChild(playerController) self.preferredContentSize = item.presentationSize } func showAssetVideo(_ asset: PHAsset) { let options = PHVideoRequestOptions() options.deliveryMode = .automatic options.isNetworkAccessAllowed = true options.version = .current PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, _, _) in guard let avAsset = avAsset else { fatalError("failed to get AVAsset") } DispatchQueue.main.async { self.showVideo(asset: avAsset) } } } }