AVMutableComposition Video Black при запуске

Я использую AVMutableComposition и AVAssetExportSession, чтобы обрезать видео вниз. Случайно, и я имею в виду случайное (я не могу последовательно воспроизводить) видео пользователей имеют несколько черных кадров в начале обрезанного видео. Звук не изменяется. Я могу подтвердить 100%, что обрезанные видео не имеют к этому никакого отношения, так как это происходит для самых разных видеороликов из разных источников.

Любое понимание того, почему эти видео экспортируются черными рамками в начале, было бы очень желанным. Спасибо!

Некоторый соответствующий код (извините за длину):

// 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 { ... }
1 ответ

Решение для этого было не пытаться обрезать и обрезать видео в одной и той же операции. У меня все еще нет ответа о том, почему это происходит, но мы смогли разрешить его, предварительно обрезав видео на время, а затем после того, как у нас было видео с надлежащей продолжительностью, выполняющей операцию обрезки на нем.

К сожалению, я считаю, что это всего лишь ошибка в структуре, но, по крайней мере, в нашем случае мы смогли решить ее, сделав меньше в каждой операции и просто навязывая операции вместе.

licensed under cc by-sa 3.0 with attribution.