her*_*son 5 objective-c avfoundation
我AVCaptureSession用来从设备摄像头捕获视频,然后使用AVAssetWriterInput和AVAssetTrack压缩/调整视频大小,然后再将其上传到服务器.最终视频将通过html5视频元素在网上观看.
我遇到了多个问题,试图让视频的方向正确.我的应用程序仅支持横向,所有捕获的视频都应横向显示.但是,我想允许用户将设备保持在横向方向(即左侧或右侧的主页按钮).
我可以使用以下代码行以正确的方向显示视频预览
_previewLayer.connection.videoOrientation = UIDevice.currentDevice.orientation;
Run Code Online (Sandbox Code Playgroud)
通过AVAssetWriterInput和朋友处理视频时问题就开始了.结果似乎并未考虑视频捕获的左右横向模式.IOW,有时视频会颠倒过来.经过一些谷歌搜索后,我发现许多人建议以下代码行可以解决这个问题
writerInput.transform = videoTrack.preferredTransform;
Run Code Online (Sandbox Code Playgroud)
......但这似乎不起作用.经过一些调试后videoTrack.preferredTransform,无论视频被捕获的方向如何,我都发现它始终是相同的值.
我试图手动跟踪什么方位的视频在拍摄和设置writerInput.transform,以CGAffineTransformMakeRotation(M_PI)根据需要.哪解决了问题!!!
...八九不离十
当我在设备上查看结果时,此解决方案按预期工作.录制时,无论左右方向如何,视频都是正面向上的.不幸的是,当我在另一个浏览器中观看完全相同的视频时(Mac书上的chrome),它们都是颠倒的!?!?!?
我究竟做错了什么?
编辑
这是一些代码,万一它有用...
-(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 */
}];
}
Run Code Online (Sandbox Code Playgroud)
小智 8
问题是修改writerInput.transform属性只会在视频文件元数据中添加一个标记,指示视频播放器在播放期间旋转文件.这就是为什么视频在你的设备上以正确的方向播放的原因(我猜他们也可以在Quicktime播放器中正确播放).
相机捕获的像素缓冲区仍然以捕获它们的方向布局.许多视频播放器不会检查首选方向元数据标签,只会以原始像素方向播放文件.
如果您希望用户能够以横向模式录制持有手机的视频,则需要AVCaptureSession在压缩前通过对每个视频帧的CVPixelBuffer执行变换来纠正此问题.这个Apple Q&A涵盖了它(查看AVCaptureVideoOutput文档):https:
//developer.apple.com/library/ios/qa/qa1744/_index.html
调查上面的链接是解决问题的正确方法.解决相同问题的另一种快速解决方法是将应用程序的录制UI锁定为仅一个横向,然后使用ffmpeg旋转服务器端的所有视频.
| 归档时间: |
|
| 查看次数: |
4181 次 |
| 最近记录: |