forked from shadowfacts/Tusker
parent
82ad3b9fc4
commit
1c9b1b9ac3
|
@ -134,6 +134,8 @@
|
|||
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */; };
|
||||
D64D8CA92463B494006B0BAA /* CachedDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64D8CA82463B494006B0BAA /* CachedDictionary.swift */; };
|
||||
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
|
||||
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */; };
|
||||
D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */; };
|
||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
|
||||
D65A37F321472F300087646E /* SwiftSoup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; };
|
||||
D65F613423AEAB6600F3CFD3 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */; };
|
||||
|
@ -428,6 +430,8 @@
|
|||
D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
|
||||
D64D8CA82463B494006B0BAA /* CachedDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedDictionary.swift; sourceTree = "<group>"; };
|
||||
D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
|
||||
D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentView.swift; sourceTree = "<group>"; };
|
||||
D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifvAttachmentViewController.swift; sourceTree = "<group>"; };
|
||||
D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
|
||||
D65F612D23AE990C00F3CFD3 /* Embassy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Embassy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D65F613023AE99E000F3CFD3 /* Ambassador.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Ambassador.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -597,6 +601,7 @@
|
|||
children = (
|
||||
04D14BAE22B34A2800642648 /* GalleryViewController.swift */,
|
||||
D647D92724257BEB0005044F /* AttachmentPreviewViewController.swift */,
|
||||
D6531DEF246B867E000F9538 /* GifvAttachmentViewController.swift */,
|
||||
);
|
||||
path = "Attachment Gallery";
|
||||
sourceTree = "<group>";
|
||||
|
@ -1216,6 +1221,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */,
|
||||
D6531DED246B81C9000F9538 /* GifvAttachmentView.swift */,
|
||||
D6C7D27C22B6EBF800071952 /* AttachmentsContainerView.swift */,
|
||||
);
|
||||
path = Attachments;
|
||||
|
@ -1650,6 +1656,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D626493523BD94CE00612E6E /* CompositionAttachmentData.swift in Sources */,
|
||||
D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */,
|
||||
D6285B5321EA708700FE4B39 /* StatusFormat.swift in Sources */,
|
||||
D6DD353D22F28CD000A9563A /* ContentWarningCopyMode.swift in Sources */,
|
||||
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
||||
|
@ -1702,6 +1709,7 @@
|
|||
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */,
|
||||
04DACE8E212CC7CC009840C4 /* ImageCache.swift in Sources */,
|
||||
D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */,
|
||||
D6531DEE246B81C9000F9538 /* GifvAttachmentView.swift in Sources */,
|
||||
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */,
|
||||
D6A3BC8F2321FFB900FD64D5 /* StatusActionAccountListTableViewController.swift in Sources */,
|
||||
D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */,
|
||||
|
|
|
@ -75,6 +75,8 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
|||
let vc = AVPlayerViewController()
|
||||
vc.player = AVPlayer(url: $0.url)
|
||||
return vc
|
||||
case .gifv:
|
||||
return GifvAttachmentViewController(attachment: $0)
|
||||
default:
|
||||
fatalError()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// GifvAttachmentViewController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 5/12/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
import AVFoundation
|
||||
|
||||
class GifvAttachmentViewController: UIViewController {
|
||||
|
||||
private let attachment: Attachment
|
||||
|
||||
init(attachment: Attachment) {
|
||||
precondition(attachment.kind == .gifv)
|
||||
self.attachment = attachment
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
let asset = AVURLAsset(url: attachment.url)
|
||||
self.view = GifvAttachmentView(asset: asset, gravity: .resizeAspect)
|
||||
}
|
||||
|
||||
}
|
|
@ -81,6 +81,8 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
|||
loadVideo()
|
||||
case .audio:
|
||||
loadAudio()
|
||||
case .gifv:
|
||||
loadGifv()
|
||||
default:
|
||||
preconditionFailure("invalid attachment type")
|
||||
}
|
||||
|
@ -111,9 +113,9 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
|||
let asset = AVURLAsset(url: attachmentURL)
|
||||
let generator = AVAssetImageGenerator(asset: asset)
|
||||
generator.appliesPreferredTrackTransform = true
|
||||
guard let image = try? generator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 1), actualTime: nil) else { return }
|
||||
DispatchQueue.main.async {
|
||||
guard self.attachment.url == attachmentURL else { return }
|
||||
guard let image = try? generator.copyCGImage(at: .zero, actualTime: nil) else { return }
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self, self.attachment.url == attachmentURL else { return }
|
||||
self.image = UIImage(cgImage: image)
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +152,30 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
|||
])
|
||||
}
|
||||
|
||||
func loadGifv() {
|
||||
let attachmentURL = self.attachment.url
|
||||
let asset = AVURLAsset(url: attachmentURL)
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
let generator = AVAssetImageGenerator(asset: asset)
|
||||
generator.appliesPreferredTrackTransform = true
|
||||
guard let image = try? generator.copyCGImage(at: .zero, actualTime: nil) else { return }
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self, self.attachment.url == attachmentURL else { return }
|
||||
self.image = UIImage(cgImage: image)
|
||||
}
|
||||
}
|
||||
|
||||
let gifvView = GifvAttachmentView(asset: asset, gravity: .resizeAspectFill)
|
||||
gifvView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(gifvView)
|
||||
NSLayoutConstraint.activate([
|
||||
gifvView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
gifvView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
gifvView.topAnchor.constraint(equalTo: topAnchor),
|
||||
gifvView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
override func display(_ layer: CALayer) {
|
||||
updateImageIfNeeded()
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import Pachyderm
|
|||
|
||||
class AttachmentsContainerView: UIView {
|
||||
|
||||
static let supportedAttachmentTypes = [Attachment.Kind.image, .video, .audio]
|
||||
static let supportedAttachmentTypes = [Attachment.Kind.image, .video, .audio, .gifv]
|
||||
|
||||
weak var delegate: AttachmentViewDelegate?
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// GifvAttachmentView.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 5/12/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
class GifvAttachmentView: UIView {
|
||||
|
||||
override class var layerClass: AnyClass {
|
||||
return AVPlayerLayer.self
|
||||
}
|
||||
|
||||
private var playerLayer: AVPlayerLayer {
|
||||
layer as! AVPlayerLayer
|
||||
}
|
||||
|
||||
private let item: AVPlayerItem
|
||||
private let player: AVPlayer
|
||||
|
||||
init(asset: AVAsset, gravity: AVLayerVideoGravity) {
|
||||
item = AVPlayerItem(asset: asset)
|
||||
player = AVPlayer(playerItem: item)
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
playerLayer.player = player
|
||||
playerLayer.videoGravity = gravity
|
||||
player.play()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(restartItem), name: .AVPlayerItemDidPlayToEndTime, object: item)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc func restartItem() {
|
||||
item.seek(to: .zero) { (success) in
|
||||
guard success else { return }
|
||||
self.player.play()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue