【发布时间】:2018-02-04 17:35:15
【问题描述】:
我的音频和视频将来自 Document 目录。当我将视频保存到照片中时,一切正常。但是后来发生了这个错误并且没有保存。
failed Optional(Error Domain=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo={NSUnderlyingError=0x17044a2f0 {Error Domain=NSOSStatusErrorDomain Code=-12842 "(null)"}, NSLocalizedFailureReason=发生未知错误(-12842), NSLocalizedDescription=操作无法完成})
这是我的功能
func getData(){
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: [])
print(directoryContents)
// if you want to filter the directory contents you can do like this:
videoUrlforMarge = directoryContents.filter{ $0.pathExtension == "mov" } as [AnyObject]
//videoUrlforMarge.append(directoryContents[1] as AnyObject)
print("this video \(videoUrlforMarge[0])")
audioUrl = directoryContents.filter{ $0.pathExtension == "caf" } as [AnyObject]
} catch let error as NSError {
print(error.localizedDescription)
}
}
这是我的合并函数
func mergeFilesWithUrl(videoUrl:NSURL, audioUrl:NSURL)
{
let mixComposition : AVMutableComposition = AVMutableComposition()
var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
//start merge
let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL)
let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL)
mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
mutableCompositionAudioTrack.append( mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
guard aVideoAsset.tracks(withMediaType: AVMediaTypeVideo).count > 0 && aAudioAsset.tracks(withMediaType: AVMediaTypeAudio).count > 0 else{
return
}
let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
do{
try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero)
try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero)
}catch{
}
totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration )
let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition()
mutableVideoComposition.frameDuration = CMTimeMake(1, 30)
mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720)
let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("mergeVideo\(arc4random()%1000)d")!.appendingPathExtension("mp4").absoluteString
if FileManager.default.fileExists(atPath: VideoFilePath)
{
do
{
try FileManager.default.removeItem(atPath: VideoFilePath)
}
catch { }
}
let tempfilemainurl = NSURL(string: VideoFilePath)!
let sourceAsset = AVURLAsset(url: tempfilemainurl as URL, options: nil)
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetMediumQuality)!
assetExport.outputFileType = AVFileTypeQuickTimeMovie
assetExport.outputURL = tempfilemainurl as URL
assetExport.exportAsynchronously { () -> Void in
switch assetExport.status
{
case AVAssetExportSessionStatus.completed:
DispatchQueue.main.async(execute: {
do
{
self.userreponsevideoData = try NSData(contentsOf: tempfilemainurl as URL, options: NSData.ReadingOptions())
print("MB - \(self.userreponsevideoData.length) byte")
let assetsLib = ALAssetsLibrary()
assetsLib.writeVideoAtPath(toSavedPhotosAlbum: tempfilemainurl as URL!, completionBlock: nil)
}
catch
{
print(error)
}
})
case AVAssetExportSessionStatus.failed:
print("failed \(String(describing: assetExport.error))")
case AVAssetExportSessionStatus.cancelled:
print("cancelled \(String(describing: assetExport.error))")
default:
print("complete")
}
}
}
和其他我称之为合并函数的函数
func Action(){
guard videoUrlforMarge.count > 0 && audioUrl.count > 0 else{
return
}
let videoUrl = videoUrlforMarge[0]
let url = NSURL(fileURLWithPath: videoUrl.absoluteString!!)
let audio = audioUrl[0]
let urla = NSURL(fileURLWithPath: audio.absoluteString!!)
self.mergeFilesWithUrl(videoUrl: url as NSURL , audioUrl:
urla as NSURL
}
【问题讨论】:
-
无重播。为什么为什么:(
-
您是否将所需的警告添加到 .plist 中? (隐私 - 照片库使用说明)用户是否批准您访问照片库?
-
是的..我添加了这个