2011-02-14 148 views
3

在iphone上调整用户录制视频的最佳方式是什么?iOS:调整大小/裁剪录制的视频

我目前有两种方式获取视频数据的能力:

1)UIImagePickerController获取文件URL的视频已被记录

2后)获取的视频帧作为其正发送由AVCaptureSession

对于1)我会需要的东西,可以读取.mov h.264文件和吐出个别帧。有这样的事吗?

对于2)我想为每个帧获取UIImage,调整图像大小,然后重新编译一个像AVAssetWriter这样的视频。但是,这似乎是一个非常密集的操作,我想知道是否有更好的方法来解决这个问题。

是否调整视频大小以调整每个单独帧的大小然后重新编译视频?或者有没有办法直接调整整个视频的大小?

我只是基本上需要用户录制一段视频,然后将该视频的大小调整为320x320,没有花哨的编辑。

感谢您提供的任何帮助。

编辑:也许'调整大小'是错误的词。我真的只需要作物视频,以便它从480x360到320x320。另外这种裁剪不需要实时发生,我可以在录制视频后进行裁剪。

回答

3

方案2不会实时工作。

对于替代方案1,使用AVAssetExportSession用所需的预设之一进行初始化 - 例如AVAssetExportPreset640x480

实验AVAssetExportPresetLowQuality,AVAssetExportPresetMediumQuality,AVAssetExportPresetHighestQuality其他决议。

请注意,视频文件通常具有16:9(或4:3)的纵横比,因此320x320不是有效的选项。除了支持的分辨率以外,没有什么理由调整其大小,除非您计划分发给其他手机,在这种情况下,可以使用服务器端转码。

+0

我能够将视频直接录制到其中一个预设中。我正在寻找的是一种将视频裁剪为不属于这些预设的自定义大小的方法。是否有可能将视频裁剪为自定义维度,就像您将图像一样? – nebs 2011-02-15 15:02:23

3

如果有人跑过这个,我发现你可以用AVFoundation做到这一点,如果你我们AVMutableVideoComposition以及AVMutableComposition。然后,您在视频合成上设置渲染大小,这将影响视频的输出大小。然后,您可以使用AVMutableVideoCompositionLayerInstruction将视频放在您想要的位置。关于开始使用所有这些类的文章,有一篇很好的文章here,他的示例项目已经在最后注释掉了用于导出它的代码。

2

完美的方法是使用AVAssetReader来读取视频文件并使用AVAssetWriter将该视频文件再次写入新的视频文件。你可以设置一个outputSetting为作家输入:

NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys: 
            AVVideoCodecH264, AVVideoCodecKey, 
            [NSNumber numberWithInt: 480], AVVideoWidthKey, 
            [NSNumber numberWithInt: 480], AVVideoHeightKey, 
             AVVideoScalingModeResizeAspectFill,AVVideoScalingModeKey, 
            nil]; 
     NSLog(@"%@",[assetVideoTrack mediaType]); 
assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType: [assetVideoTrack mediaType] 
                    outputSettings:settings]; 
     [assetWriter addInput:assetWriterVideoInput]; 

你搜索苹果开发者文档,找到AVAssetReader

0

你需要采取视频的方向考虑GUID线。这是一个Swift 2解决方案。这两种作物和缩放视频

extension AVAsset { 

    private var g_naturalSize: CGSize { 
    return tracksWithMediaType(AVMediaTypeVideo).first?.naturalSize ?? .zero 
    } 

    var g_correctSize: CGSize { 
    return g_isPortrait ? CGSize(width: g_naturalSize.height, height: g_naturalSize.width) : g_naturalSize 
    } 

    var g_isPortrait: Bool { 
    let portraits: [UIInterfaceOrientation] = [.Portrait, .PortraitUpsideDown] 
    return portraits.contains(g_orientation) 

    // Same as UIImageOrientation 
    var g_orientation: UIInterfaceOrientation { 
    guard let transform = tracksWithMediaType(AVMediaTypeVideo).first?.preferredTransform else { 
     return .Portrait 
    } 

    switch (transform.tx, transform.ty) { 
    case (0, 0): 
     return .LandscapeRight 
    case (g_naturalSize.width, g_naturalSize.height): 
     return .LandscapeLeft 
    case (0, g_naturalSize.width): 
     return .PortraitUpsideDown 
    default: 
     return .Portrait 
    } 
    } 
} 

这里是如何得到改造

func transform(avAsset: AVAsset, scaleFactor: CGFloat) -> CGAffineTransform { 
    let offset: CGPoint 
    let angle: Double 

    switch avAsset.g_orientation { 
    case .LandscapeLeft: 
     offset = CGPoint(x: avAsset.g_correctSize.width, y: avAsset.g_correctSize.height) 
     angle = M_PI 
    case .LandscapeRight: 
     offset = CGPoint.zero 
     angle = 0 
    case .PortraitUpsideDown: 
     offset = CGPoint(x: 0, y: avAsset.g_correctSize.height) 
     angle = -M_PI_2 
    default: 
     offset = CGPoint(x: avAsset.g_correctSize.width, y: 0) 
     angle = M_PI_2 
    } 

    let scale = CGAffineTransformMakeScale(scaleFactor, scaleFactor) 
    let translation = CGAffineTransformTranslate(scale, offset.x, offset.y) 
    let rotation = CGAffineTransformRotate(translation, CGFloat(angle)) 

    return rotation 
    } 

而如何在层指令

let layer = AVMutableVideoCompositionLayerInstruction(assetTrack: track) 
layer.setTransform(transform(avAsset, scaleFactor: 0.8), atTime: kCMTimeZero) 

使用参考