我正在使用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 { ... }
答案 0 :(得分:0)
我们的解决方案是不要尝试在同一操作中裁剪和修剪视频。我仍然没有回答为什么会这样,但我们能够通过首先修剪视频一段时间来解决它,然后我们让视频在适当的持续时间内执行裁剪操作。
不幸的是我认为这只是框架中的一个错误,但至少在我们的情况下,我们能够通过在每个操作中做更少的操作并将操作串联起来来解决它。