Es ist ein gut dokumentiertes Problem auf SO, wo AVAsets nach dem Schreiben in eine Datei gedreht werden, entweder AVAssetWriter
oder AVComposition
. Und es gibt Lösungen, wie zum Beispiel die Transformation der Videospur zu betrachten und zu sehen, wie das Asset gedreht wird, so dass es für Ihren speziellen Anwendungsfall in die gewünschte Ausrichtung gedreht werden kann.AVAsset Rotation
Was ich jedoch wissen möchte ist, warum dies passiert und ob es möglich ist, dies zu verhindern. Ich stolperte nicht nur beim Schreiben von benutzerdefinierten Videodateien, sondern auch beim Umwandeln von Videos in Gifs mithilfe von CGImageDestination
, wobei das Ausgabegif gut aussieht, außer dass es gedreht wird.
Um einen schnellen Bezugspunkt für meinen Code zu geben, der eine Bereicherung für Datei schreibt:
let destinationURL = url ?? NSURL(fileURLWithPath: "\(NSTemporaryDirectory())\(String.random()).mp4")
if let writer = try? AVAssetWriter(URL: destinationURL, fileType: AVFileTypeMPEG4),
videoTrack = self.asset.tracksWithMediaType(AVMediaTypeVideo).last,
firstBuffer = buffers.first {
let videoCompressionProps = [AVVideoAverageBitRateKey: videoTrack.estimatedDataRate]
let outputSettings: [String: AnyObject] = [
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: width,
AVVideoHeightKey: height,
AVVideoCompressionPropertiesKey: videoCompressionProps
]
let writerInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: outputSettings, sourceFormatHint: (videoTrack.formatDescriptions.last as! CMFormatDescription))
writerInput.expectsMediaDataInRealTime = false
let rotateTransform = CGAffineTransformMakeRotation(Utils.degreesToRadians(-90))
writerInput.transform = CGAffineTransformScale(rotateTransform, -1, 1)
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: nil)
writer.addInput(writerInput)
writer.startWriting()
writer.startSessionAtSourceTime(CMSampleBufferGetPresentationTimeStamp(firstBuffer))
for (sample, newTimestamp) in Array(Zip2Sequence(buffers, timestamps)) {
if let imageBuffer = CMSampleBufferGetImageBuffer(sample) {
while !writerInput.readyForMoreMediaData {
NSThread.sleepForTimeInterval(0.1)
}
pixelBufferAdaptor.appendPixelBuffer(imageBuffer, withPresentationTime: newTimestamp)
}
}
writer.finishWritingWithCompletionHandler {
// completion code
}
Wie Sie oben sehen, das ausgegebene Video Portrait zurück eine einfache Transformation dreht können. Wenn ich jedoch ein Landschaftsvideo habe, funktioniert diese Transformation nicht mehr. Und wie ich bereits erwähnt habe, führt die Umwandlung des Videos in ein gif genau die gleiche 90-Grad-Drehung auf meinem Asset durch.
Meine Gefühle können in diesen beiden Gifs zusammengefasst werden:
http://giphy.com/gifs/jon-stewart-why-lYKvaJ8EQTzCU
http://giphy.com/gifs/the-office-no-steve-carell-12XMGIWtrHBl5e
ich gefragt wurde, warum es passiert, nicht, wie es zu beheben. – barndog