AVMutableComposition视频开头黑屏

6
我正在使用AVMutableCompositionAVAssetExportSession来剪辑视频。奇怪的是,有时候(我无法一致地复现)用户的视频在开始被裁剪后会有几个黑帧。音频没有受到影响。我可以百分之百确认,被剪辑的视频与此无关,因为这种情况发生在各种不同来源的视频中。
如果您能提供任何关于为什么这些视频在开头加上黑帧的见解,将不胜感激。谢谢!
以下是一些相关代码(很抱歉长度有点长):
// AVURLAssetPreferPreciseDurationAndTimingKey added in attempt to solve issue
let videoAsset = AVURLAsset(URL: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
var mixComposition = AVMutableComposition()

let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(
    AVMediaTypeVideo,
    preferredTrackID: Int32(kCMPersistentTrackID_Invalid)
)
let clipVideoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] as! AVAssetTrack
let videoSize = clipVideoTrack.naturalSize
// startTime and duration are NSTimeInterval types
let start = startTime == 0 ? kCMTimeZero : CMTimeMakeWithSeconds(startTime, videoAsset.duration.timescale)
var dur = CMTimeMakeWithSeconds(duration, videoAsset.duration.timescale)
if dur.value >= videoAsset.duration.value {

    dur = videoAsset.duration

}
compositionVideoTrack.insertTimeRange(
    CMTimeRange(start: start, duration: dur),
    ofTrack:clipVideoTrack,
    atTime: kCMTimeZero,
    error:nil
)

compositionVideoTrack.preferredTransform = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0].preferredTransform

let compositionAudioTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let clipAudioTrack = videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0] as! AVAssetTrack
compositionAudioTrack.insertTimeRange(
    CMTimeRange(start: start, duration: dur),
    ofTrack: clipAudioTrack,
    atTime: kCMTimeZero,
    error: nil
)

let parentLayer = CALayer()
parentLayer.backgroundColor = UIColor.blackColor().CGColor
let videoLayer = CALayer()
videoLayer.backgroundColor = UIColor.blackColor().CGColor
var parentFrame = CGRect(
    x: 0,
    y: 0,
    width: videoSize.width,
    height: videoSize.height
)
if parentFrame.width % 2 > 0 {
    parentFrame.size.width = parentFrame.size.width - 1
}
// Fix crop frame height
if parentFrame.size.height % 2 > 0 {
    parentFrame.size.height = parentFrame.size.height - 1
}
parentLayer.frame = parentFrame
videoLayer.frame = CGRect(
    x: 0,
    y: 0,
    width: videoSize.width,
    height: videoSize.height
)
parentLayer.addSublayer(videoLayer)

let videoComp = AVMutableVideoComposition()
videoComp.renderSize = parentLayer.frame.size
videoComp.frameDuration = CMTimeMake(1, Int32(clipVideoTrack.nominalFrameRate))
videoComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)

let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(start: kCMTimeZero, duration: mixComposition.duration)
let videoTrack = mixComposition.tracksWithMediaType(AVMediaTypeVideo)[0] as! AVAssetTrack
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

layerInstruction.setTransform(CGAffineTransformMakeScale(parentLayer.frame.size.width / videoSize.width, parentLayer.frame.size.height / videoSize.height), atTime: kCMTimeZero)
instruction.layerInstructions = [layerInstruction]
videoComp.instructions = [instruction]

// Export
let exportSession = AVAssetExportSession(
    asset: mixComposition,
    presetName: AVAssetExportPresetHighestQuality
)
exportSession.videoComposition = videoComp
let renderFileName = "video.mp4"
let renderURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingPathComponent(renderFileName))
exportSession.outputURL = renderURL
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.exportAsynchronouslyWithCompletionHandler { ... }

你找到解决方案了吗? - Tien Nguyen
1个回答

0
对于我们来说,解决这个问题的方法是不要在同一操作中尝试裁剪和修剪视频。我仍然没有答案为什么会发生这种情况,但我们能够通过先将视频按时间修剪,然后在获得正确持续时间的视频后执行裁剪操作来解决它。
不幸的是,我认为这只是框架中的一个错误,但至少在我们的情况下,我们能够通过在每个操作中做更少的事情并将操作串联起来来解决它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接