如何在OS X上用Swift调整大小、裁剪和导出AVAsset



我正在尝试调整和裁剪AVAsset的大小,并将其导出到OS X上Swift中的电影文件中。

我正在使用AVAssetExportSession导出AVAsset,如果videoComposition未设置为AVassetExport Session,它可以正常工作。下面的代码导出资产没有问题,但由于videoComposition行被注释掉,它没有调整大小和裁剪。

self.asset = AVAsset( URL: validURL )!
if let exportSession = AVAssetExportSession( asset: self.asset,
                                        presetName: AVAssetExportPresetAppleProRes422LPCM ) {
        exportSession.outputURL = exportURL
        exportSession.outputFileType = AVFileTypeQuickTimeMovie
//      exportSession.videoComposition = self.videoComposition   // *** problematic line
        exportSession.timeRange = CMTimeRangeMake( kCMTimeZero, self.asset.duration )
        exportSession.exportAsynchronouslyWithCompletionHandler( { () -> Void in
            print( "[export completed]" )       
        })
}

但是,如果我将videoComposition设置为AVAssetExportSession,通过删除注释来调整和裁剪资产的大小,则导出的文件只有调整大小和裁剪的视频的第一帧,第二帧和后面的帧都是黑帧,而音频导出时没有问题。

我设置的视频组成如下。(在这个例子中,渲染大小和仿射变换是固定的,以简化代码)

var videoComposition: AVVideoComposition {
    //---------------
    //  composition
    //---------------
    let composition = AVMutableVideoComposition()
    composition.renderSize = NSMakeSize( 720, 480 )  // fixed size in this example
    composition.frameDuration = self.asset.duration
    //---------------
    //  instruction
    //---------------
    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake( kCMTimeZero, self.asset.duration )
    //-------------------------
    //  transform instruction
    //-------------------------
    let videoTracks = self.asset.tracksWithMediaType( AVMediaTypeVideo )
    let assetTrack = videoTracks[0]
    let layerInstruction = AVMutableVideoCompositionLayerInstruction( assetTrack: assetTrack )
    let transform = CGAffineTransformMake( 1.5,  // fixed transform in this example
        0.0,
        0.0,
        2.0,
        -100.0,
        -100.0 )
    layerInstruction.setTransformRampFromStartTransform( transform,
                                         toEndTransform: transform,
                                              timeRange: CMTimeRangeMake( kCMTimeZero, self.asset.duration ) )
    instruction.layerInstructions = [ layerInstruction ]
    composition.instructions = [ instruction ]
    return composition
}

如何避免第二帧和后面的帧为黑色,并成功导出所有调整大小和裁剪的帧?

构图的frameDuration属性是每帧的时间间隔,也就是视频的每秒帧数。您当前已将其设置为整个资源轨迹的长度,因此一帧将持续整个轨迹的长度。

例如,下面的代码将您的合成设置为每秒30帧的帧速率:

composition.frameDuration = CMTimeMake(1, 30)

理想情况下,您应该使用视频轨道的帧速率(AVAssetTrack具有nominalFrameRate属性),如下所示:

composition.frameDuration = CMTimeMake(1, assetTrack.nominalFrameRate)

最新更新