|
|
import CoreMedia
|
|
|
import DropTwoCore
|
|
|
import Foundation
|
|
|
|
|
|
// Prüfstein fürs Core-Framework (Schritt 3 der Umsetzungsreihenfolge):
|
|
|
// echte Dateien durchjagen und die Ausgabequalität von CropEngine bewerten.
|
|
|
// Nutzt dieselbe ConversionPipeline wie später die App, damit CLI und
|
|
|
// Oberfläche garantiert dasselbe tun.
|
|
|
|
|
|
let arguments = Array(CommandLine.arguments.dropFirst())
|
|
|
|
|
|
guard arguments.count >= 2 else {
|
|
|
print("Usage: droptwo <zielordner> <datei> [<datei> ...]")
|
|
|
exit(0)
|
|
|
}
|
|
|
|
|
|
let outputDirectory = URL(fileURLWithPath: arguments[0], isDirectory: true)
|
|
|
let sourcePaths = arguments.dropFirst()
|
|
|
|
|
|
func describe(_ info: VideoInfo) -> String {
|
|
|
let seconds = CMTimeGetSeconds(info.duration)
|
|
|
return "\(Int(info.pixelSize.width))×\(Int(info.pixelSize.height)), \(info.codec), "
|
|
|
+ "\(String(format: "%.2f", info.frameRate)) fps, \(String(format: "%.2f", seconds))s, "
|
|
|
+ "Audio: \(info.hasAudioTrack ? "ja" : "nein")"
|
|
|
}
|
|
|
|
|
|
func fileSizeInMB(_ url: URL) -> Double? {
|
|
|
guard let size = try? FileManager.default.attributesOfItem(atPath: url.path)[.size] as? Int else {
|
|
|
return nil
|
|
|
}
|
|
|
return Double(size) / 1_000_000
|
|
|
}
|
|
|
|
|
|
for sourcePath in sourcePaths {
|
|
|
let sourceURL = URL(fileURLWithPath: sourcePath)
|
|
|
let fileName = sourceURL.lastPathComponent
|
|
|
let start = Date()
|
|
|
|
|
|
let outcome = await ConversionPipeline.process(sourceURL: sourceURL, outputRootDirectory: outputDirectory)
|
|
|
|
|
|
switch outcome {
|
|
|
case .skipped(let fileName, let reason):
|
|
|
print("\(fileName): übersprungen (\(reason))")
|
|
|
case .rejected(let fileName, let reason):
|
|
|
print("\(fileName): abgelehnt (\(reason))")
|
|
|
case .failed(let fileName, let error):
|
|
|
print("\(fileName): Fehler — \(error)")
|
|
|
case .succeeded(let success):
|
|
|
let elapsed = Date().timeIntervalSince(start)
|
|
|
let sizeMB = fileSizeInMB(success.croppedDestination).map { String(format: "%.1f MB", $0) } ?? "?"
|
|
|
print(fileName)
|
|
|
print(" Quelle: \(describe(success.sourceInfo))")
|
|
|
print(" -> \(success.croppedDestination.lastPathComponent): \(describe(success.croppedInfo)), \(sizeMB), \(String(format: "%.1f", elapsed))s Renderzeit")
|
|
|
}
|
|
|
}
|