在进行视频转码时报错如下:
Error Domain=AVFoundationErrorDomain Code=-11800 "这项操作无法完成
" UserInfo={NSLocalizedFailureReason=发生未知错误(-12769),
NSLocalizedDescription=这项操作无法完成, NSUnderlyingError=0x283fe7990
{Error Domain=NSOSStatusErrorDomain Code=-12769 "(null)"}}
原因:
生成该视频时编码器出现了问题,可以通过下面方式让AVAssetExportSession重新编码来解决。
解决办法:重新编码
// 对视频重新编码
func resetComposition(avAsset: AVAsset) -> AVAsset {
let mainComposition = AVMutableComposition()
let compositionVideoTrack = mainComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
let timeScale:Double = 100000
let seconds = CMTimeGetSeconds(avAsset.duration) - 0.001
let videoDurationI = UInt(seconds * timeScale)
let videoDuration = CMTimeMake(value: Int64(videoDurationI), timescale: Int32(timeScale))
let videoTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoDuration)
let videoTracks: [AVAssetTrack] = avAsset.tracks(withMediaType: AVMediaType.video)
let videoTrack = videoTracks.first
try? compositionVideoTrack?.insertTimeRange(videoTimeRange, of: videoTrack!, at: .zero)
return mainComposition
}
使用示例:
private func videoExportMp4(assetItem:PHAsset){
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
PHCachingImageManager().requestAVAsset(forVideo: assetItem, options:options, resultHandler: { (asset, audioMix, info)in
// 重新编码视频
let avAsset = self.resetComposition(avAsset: asset!)
//以当前时间来为文件命名
let date = Date()
let formatter = DateFormatter.init()
formatter.dateFormat = "yyyyMMddHHmmss"
let fileName = formatter.string(from: date) + ".mp4"
//保存址沙盒路径
let docPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0] as NSString
let videoSandBoxPath = (docPath as String) + "/ablumVideo" + fileName
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: avAsset)
if compatiblePresets.contains(AVAssetExportPresetHighestQuality) {
let exporter = AVAssetExportSession(asset: avAsset,
presetName:AVAssetExportPresetHighestQuality)!
exporter.outputURL = NSURL(fileURLWithPath: videoSandBoxPath as String) as URL
exporter.outputFileType = AVFileType.mp4
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously(completionHandler: {
switch (exporter.status) {
case .unknown:
break
case .waiting:
break
case .exporting:
break
case .completed:
print("转码成功" + videoSandBoxPath )
break
case .failed:
DispatchQueue.main.async {
print("\(String(describing: exporter.error))")
print("视频处理失败")
}
break
case .cancelled:
break
@unknown default:
break
}
})
}
})
}
网友评论