AVMutableComposition 缺失帧记录器与 iPad 的不同相机
AVMutableComposition missing frames recorder with difference cameras of iPad
我使用众所周知的 PBJVision 来录制视频,然后必须将它们组合在一起。
我使用 AVMutableComposition 来组合视频
insertTimeRange(_:ofAsset:atTime:error:)。如果视频是用同一台相机拍摄的,效果会很好。但是例如,如果一个是用后置摄像头拍摄的,然后使用前置摄像头拍摄另一个,则后一个视频的视频丢失。看起来只添加了音频。这是我的代码:
var error: NSError? = nil
let composition = AVMutableComposition()
var currentTime = kCMTimeZero
for (index, videoURL) in enumerate(videoURLS) {
let asset = AVURLAsset.assetWithURL(videoURL) as! AVAsset
let success = composition.insertTimeRange(CMTimeRange(start: kCMTimeZero, duration: asset.duration),
ofAsset: asset,
atTime: currentTime,
error: &error)
if !success {
if error != nil {
println("timerange isnert error - \(error?.localizedDescription)")
}
}
// add time till we get to the last video
if index < videoURLS.count - 1 {
currentTime = CMTimeAdd(currentTime, asset.duration)
}
}
let outputURL = fileSystemHelper.temporaryStorageURLForExportSession()
let fileManager = NSFileManager.defaultManager()
fileManager.removeItemAtURL(outputURL, error: &error)
if error != nil {
println("export session file removal error - \(error?.localizedDescription)")
}
let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
exportSession.outputFileType = AVFileTypeMPEG4
exportSession.outputURL = outputURL
let start = CMTimeMake(0, 1)
let range = CMTimeRangeMake(start, composition.duration)
//exportSession.timeRange = range
exportSession.exportAsynchronouslyWithCompletionHandler { () -> Void in
switch exportSession.status {
case .Completed:
self.fileSystemHelper.copyFileAtURL(outputURL, toURL: finalURL)
self.appendURL = nil
// self.isRecording = false
completion()
case .Failed:
println("fail error - \(exportSession.error.localizedDescription)")
self.fileSystemHelper.removeFileAtURL(outputURL)
self.appendURL = nil
//self.isRecording = false
println("failed to mix")
// delegate?.videoCaptureDidFinishRecordingVideoAtURL(URL, appended: appendURL == nil)
default:
println("something else happened, check code")
}
}
在我问了这个问题之后,我在附近散步了一夜,自己找到了答案:) 所以不同的相机有不同的最大可能分辨率,从而产生不同大小的帧,混淆了合成对象。它使用第一个视频的大小并忽略具有不同大小的视频帧。
因此,测试并查看特定设备上两个摄像头支持的最佳分辨率 AVCaptureSessionPreset 是什么。然后在您的视频捕获代码中使用该预设,不要直接跳转到使用 AVCaptureSessionPresetHigh。
我希望这对其他人也有帮助:)
我使用众所周知的 PBJVision 来录制视频,然后必须将它们组合在一起。 我使用 AVMutableComposition 来组合视频 insertTimeRange(_:ofAsset:atTime:error:)。如果视频是用同一台相机拍摄的,效果会很好。但是例如,如果一个是用后置摄像头拍摄的,然后使用前置摄像头拍摄另一个,则后一个视频的视频丢失。看起来只添加了音频。这是我的代码:
var error: NSError? = nil
let composition = AVMutableComposition()
var currentTime = kCMTimeZero
for (index, videoURL) in enumerate(videoURLS) {
let asset = AVURLAsset.assetWithURL(videoURL) as! AVAsset
let success = composition.insertTimeRange(CMTimeRange(start: kCMTimeZero, duration: asset.duration),
ofAsset: asset,
atTime: currentTime,
error: &error)
if !success {
if error != nil {
println("timerange isnert error - \(error?.localizedDescription)")
}
}
// add time till we get to the last video
if index < videoURLS.count - 1 {
currentTime = CMTimeAdd(currentTime, asset.duration)
}
}
let outputURL = fileSystemHelper.temporaryStorageURLForExportSession()
let fileManager = NSFileManager.defaultManager()
fileManager.removeItemAtURL(outputURL, error: &error)
if error != nil {
println("export session file removal error - \(error?.localizedDescription)")
}
let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
exportSession.outputFileType = AVFileTypeMPEG4
exportSession.outputURL = outputURL
let start = CMTimeMake(0, 1)
let range = CMTimeRangeMake(start, composition.duration)
//exportSession.timeRange = range
exportSession.exportAsynchronouslyWithCompletionHandler { () -> Void in
switch exportSession.status {
case .Completed:
self.fileSystemHelper.copyFileAtURL(outputURL, toURL: finalURL)
self.appendURL = nil
// self.isRecording = false
completion()
case .Failed:
println("fail error - \(exportSession.error.localizedDescription)")
self.fileSystemHelper.removeFileAtURL(outputURL)
self.appendURL = nil
//self.isRecording = false
println("failed to mix")
// delegate?.videoCaptureDidFinishRecordingVideoAtURL(URL, appended: appendURL == nil)
default:
println("something else happened, check code")
}
}
在我问了这个问题之后,我在附近散步了一夜,自己找到了答案:) 所以不同的相机有不同的最大可能分辨率,从而产生不同大小的帧,混淆了合成对象。它使用第一个视频的大小并忽略具有不同大小的视频帧。 因此,测试并查看特定设备上两个摄像头支持的最佳分辨率 AVCaptureSessionPreset 是什么。然后在您的视频捕获代码中使用该预设,不要直接跳转到使用 AVCaptureSessionPresetHigh。
我希望这对其他人也有帮助:)