我正在尝试调整和裁剪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)