Ich verwende AVCaptureSession
, um Videos von einer Gerätekamera aufzunehmen und dann AVAssetWriterInput
und AVAssetTrack
zu verwenden, um das Video zu komprimieren/zu skalieren, bevor es auf einen Server hochgeladen wird. Die endgültigen Videos werden im Web über ein html5-Videoelement angezeigt.AVFoundation - Warum kann ich die Videoausrichtung nicht richtig einstellen?
Ich habe mehrere Probleme, die versuchen, die richtige Ausrichtung des Videos zu erhalten. Meine App unterstützt nur die Ausrichtung im Querformat und alle aufgenommenen Videos sollten im Querformat ausgerichtet sein. Jedoch möchte ich dem Benutzer erlauben, sein Gerät in beiden Querformat-Richtungen zu halten (d. H. Home-Taste auf der linken oder der rechten Seite).
Ich bin die Lage, die Video-Vorschau zeigt in der richtigen Ausrichtung mit der folgenden Codezeile
_previewLayer.connection.videoOrientation = UIDevice.currentDevice.orientation;
Die Probleme beginnen zu machen, wenn das Video über AVAssetWriterInput
und Freunde zu verarbeiten. Das Ergebnis scheint nicht für den linken oder rechten Landschaftsmodus zu sein, in dem das Video aufgenommen wurde. IOW, manchmal erscheint das Video auf dem Kopf stehend. Nach einigen googeln fand ich viele Leute darauf hindeutet, dass die folgende Codezeile dieses Problem lösen würde
writerInput.transform = videoTrack.preferredTransform;
... aber das scheint nicht zu funktionieren. Nach einem wenig Debuggen fand ich, dass videoTrack.preferredTransform
immer der gleiche Wert ist, unabhängig von der Orientierung wurde das Video in eingefangen.
versuchte Tracking I manuell welche Orientierung wurde das Video aufgenommen und in den zu writerInput.transform
CGAffineTransformMakeRotation(M_PI)
nach Bedarf einstellen. Was hat das Problem gelöst !!!
... sorta
Als ich gesehen die Ergebnisse auf dem Gerät diese Lösung wie erwartet funktioniert. Die Videos waren während der Aufnahme unabhängig von linker und rechter Ausrichtung rechts oben. Leider, als ich die gleichen Videos in einem anderen Browser (Chrome auf einem Mac-Buch) angesehen habe, waren sie alle auf dem Kopf stehend!?!?!?
Was mache ich falsch?
EDIT
Hier ist ein Code, falls hilfreich es ist ...
-(void)compressFile:(NSURL*)inUrl;
{
NSString* fileName = [@"compressed." stringByAppendingString:inUrl.lastPathComponent];
NSError* error;
NSURL* outUrl = [PlatformHelper getFilePath:fileName error:&error];
NSDictionary* compressionSettings = @{ AVVideoProfileLevelKey: AVVideoProfileLevelH264Main31,
AVVideoAverageBitRateKey: [NSNumber numberWithInt:2500000],
AVVideoMaxKeyFrameIntervalKey: [NSNumber numberWithInt: 30] };
NSDictionary* videoSettings = @{ AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: [NSNumber numberWithInt:1280],
AVVideoHeightKey: [NSNumber numberWithInt:720],
AVVideoScalingModeKey: AVVideoScalingModeResizeAspectFill,
AVVideoCompressionPropertiesKey: compressionSettings };
NSDictionary* videoOptions = @{ (id)kCVPixelBufferPixelFormatTypeKey: [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] };
AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
writerInput.expectsMediaDataInRealTime = YES;
AVAssetWriter* assetWriter = [AVAssetWriter assetWriterWithURL:outUrl fileType:AVFileTypeMPEG4 error:&error];
assetWriter.shouldOptimizeForNetworkUse = YES;
[assetWriter addInput:writerInput];
AVURLAsset* asset = [AVURLAsset URLAssetWithURL:inUrl options:nil];
AVAssetTrack* videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
// !!! this line does not work as expected and causes all sorts of issues (videos display sideways in some cases) !!!
//writerInput.transform = videoTrack.preferredTransform;
AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:videoOptions];
AVAssetReader* assetReader = [AVAssetReader assetReaderWithAsset:asset error:&error];
[assetReader addOutput:readerOutput];
[assetWriter startWriting];
[assetWriter startSessionAtSourceTime:kCMTimeZero];
[assetReader startReading];
[writerInput requestMediaDataWhenReadyOnQueue:_processingQueue usingBlock:
^{
/* snip */
}];
}
Vielen Dank. – herbrandson