add video import duration limit
This commit is contained in:
1 parent
38c6d06a0e
commit
2148a348da
4 files changed
+61
-38
No files matched your search
@@ -8,44 +8,6 @@
|
||||
import Foundation
|
||||
import ZIPFoundation
|
||||
import UIKit
|
||||
import CoreTransferable
|
||||
|
||||
struct Movie: Transferable {
|
||||
let url: URL
|
||||
|
||||
static var transferRepresentation: some TransferRepresentation {
|
||||
FileRepresentation(contentType: .movie) { movie in
|
||||
SentTransferredFile(movie.url)
|
||||
} importing: { received in
|
||||
let videoFolder = SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory)
|
||||
if !FileManager.default.fileExists(atPath: videoFolder.path()) {
|
||||
try? FileManager.default.createDirectory(at: videoFolder, withIntermediateDirectories: true)
|
||||
}
|
||||
let copy = videoFolder.appending(path: "\(UUID()).mp4")
|
||||
|
||||
if FileManager.default.fileExists(atPath: copy.path()) {
|
||||
try FileManager.default.removeItem(at: copy)
|
||||
}
|
||||
|
||||
try FileManager.default.copyItem(at: received.file, to: copy)
|
||||
return Self.init(url: copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum LoadState {
|
||||
case unknown, loading, loaded(Movie), failed
|
||||
}
|
||||
|
||||
struct LoadInfo: Identifiable, Equatable {
|
||||
static func == (lhs: LoadInfo, rhs: LoadInfo) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
var id = UUID()
|
||||
var autoReverses: Bool = false
|
||||
var loadState: LoadState
|
||||
}
|
||||
|
||||
class PosterBoardManager: ObservableObject {
|
||||
static let ShortcutURL = "https://www.icloud.com/shortcuts/a28d2c02ca11453cb5b8f91c12cfa692"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import Foundation
|
||||
import AVFoundation
|
||||
import UIKit
|
||||
import CoreTransferable
|
||||
|
||||
extension CGImage {
|
||||
var png: Data? {
|
||||
@@ -23,7 +24,55 @@ extension CGImage {
|
||||
}
|
||||
}
|
||||
|
||||
struct Movie: Transferable {
|
||||
let url: URL
|
||||
|
||||
static var transferRepresentation: some TransferRepresentation {
|
||||
FileRepresentation(contentType: .movie) { movie in
|
||||
SentTransferredFile(movie.url)
|
||||
} importing: { received in
|
||||
let videoFolder = SymHandler.getDocumentsDirectory().appendingPathComponent("Videos", conformingTo: .directory)
|
||||
if !FileManager.default.fileExists(atPath: videoFolder.path()) {
|
||||
try? FileManager.default.createDirectory(at: videoFolder, withIntermediateDirectories: true)
|
||||
}
|
||||
let copy = videoFolder.appending(path: "\(UUID()).mp4")
|
||||
|
||||
if FileManager.default.fileExists(atPath: copy.path()) {
|
||||
try FileManager.default.removeItem(at: copy)
|
||||
}
|
||||
|
||||
try FileManager.default.copyItem(at: received.file, to: copy)
|
||||
return Self.init(url: copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum LoadState {
|
||||
case unknown, loading, loaded(Movie), failed
|
||||
}
|
||||
|
||||
struct LoadInfo: Identifiable, Equatable {
|
||||
static func == (lhs: LoadInfo, rhs: LoadInfo) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
var id = UUID()
|
||||
var autoReverses: Bool = false
|
||||
var loadState: LoadState
|
||||
}
|
||||
|
||||
class VideoHandler {
|
||||
static let MaxDurationSecs = 12.0
|
||||
|
||||
static func isVideoTooLong(at url: URL) -> Bool {
|
||||
let asset = AVAsset(url: url)
|
||||
|
||||
let duration = asset.duration
|
||||
let durationTime = CMTimeGetSeconds(duration)
|
||||
|
||||
return durationTime > MaxDurationSecs
|
||||
}
|
||||
|
||||
static func createCaml(from url: URL, autoReverses: Bool) throws -> URL {
|
||||
// copy the resources
|
||||
let descrURL = SymHandler.getDocumentsDirectory().appendingPathComponent(UUID().uuidString, conformingTo: .directory)
|
||||
|
||||
@@ -706,6 +706,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Failed to Import Video" : {
|
||||
|
||||
},
|
||||
"Fallback Shortcut Creator" : {
|
||||
"localizations" : {
|
||||
@@ -1509,6 +1512,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"The video you imported is too long! Your video must be %@ seconds or less." : {
|
||||
|
||||
},
|
||||
"To apply, PosterBoard will need to open.\n\nYou can install an optional shortcut if the original method fails." : {
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import AVKit
|
||||
|
||||
struct VideoView: View {
|
||||
@ObservedObject var pbManager = PosterBoardManager.shared
|
||||
@AppStorage("ignoreDurationLimit") var ignoreDurationLimit: Bool = false
|
||||
|
||||
@State var selectedVideo: PhotosPickerItem?
|
||||
|
||||
@@ -103,8 +104,13 @@ struct VideoView: View {
|
||||
do {
|
||||
if let movie = try await selectedVideo?.loadTransferable(type: Movie.self) {
|
||||
await MainActor.run {
|
||||
if !ignoreDurationLimit && VideoHandler.isVideoTooLong(at: movie.url) {
|
||||
pbManager.videos.remove(at: id)
|
||||
UIApplication.shared.alert(title: NSLocalizedString("Failed to Import Video", comment: ""), body: String(format: NSLocalizedString("The video you imported is too long! Your video must be %@ seconds or less.", comment: ""), "\(Int(VideoHandler.MaxDurationSecs))"))
|
||||
} else {
|
||||
pbManager.videos[id].loadState = .loaded(movie)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await MainActor.run {
|
||||
pbManager.videos[id].loadState = .failed
|
||||
|
||||
Reference in new issue
Block a user