共享扩展中的 AVAssetExportSession
AVAssetExportSession in share extension
我正在尝试对共享扩展中选择的视频使用 AVAssetExportSession 并获得
Error Domain=NSURLErrorDomain Code=-3000 "Cannot create file"
UserInfo={NSLocalizedDescription=Cannot create file,
NSUnderlyingError=0x14811fdb0 {Error Domain=NSOSStatusErrorDomain
Code=-12124 "(null)"}}
但我可以在同一个 NSURL 手动创建文件而不会出错。这是我正在使用的函数
func reencodeVideo() {
let videoAsset = AVURLAsset(URL: video.url)
let videoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
print(videoTrack.estimatedDataRate)
let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPreset1920x1080)
guard let outputURL = uploadableFileURL else {
return
}
let fileManager = NSFileManager.defaultManager()
// let created = fileManager.createFileAtPath(outputURL.path!, contents: nil, attributes: nil)
if let path = outputURL.path where fileManager.fileExistsAtPath(path) {
print("file exists")
}
do {
try fileManager.removeItemAtURL(outputURL)
print("deleted")
} catch {
print(error)
}
exportSession?.outputURL = outputURL
exportSession?.outputFileType = AVFileTypeQuickTimeMovie
exportSession?.exportAsynchronouslyWithCompletionHandler{
print(exportSession?.status)
}
}
private var uploadableFileURL: NSURL? {
guard let tempFileName = video.url.lastPathComponent else {
return nil
}
let fileManager = NSFileManager.defaultManager()
guard let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier(Constants.appGroupIdentifier) else {
return nil
}
return containerURL.URLByAppendingPathComponent("videoFile.mov")
}
我已经在同一目录中成功创建了文件,但是 AVAssetExportSession returns 出现了错误。
知道我做错了什么吗?
我试过使用 AVAssetReader
和 AVAssetWriter
以及 AVAssetWriter
returns 尝试启动时出现相同的错误。如果我正在使用文档目录,编码过程会成功完成,只有在使用共享应用程序组容器时才会失败。
我无法从您的代码中找出您的 uploadableFileURL 的来源,但以下内容对我有用:
if let video = videoAsset {
let fm = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)
let url = fm[0].URLByAppendingPathComponent("\(NSDate())").URLByAppendingPathExtension("mp4")
let exporter = AVAssetExportSession(asset: video, presetName: AVAssetExportPreset3840x2160)
exporter?.outputURL = url
exporter?.outputFileType = AVFileTypeMPEG4
exporter?.exportAsynchronouslyWithCompletionHandler() { _ in
let data = NSData(contentsOfURL: url)
}
}
您的问题可能与文档文件夹和icloud 同步的使用有关。
参见 https://forums.developer.apple.com/message/77495#77495
如果你这样做:
guard let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier(Constants.appGroupIdentifier) else {
return nil
}
let libraryURL = containerURL.URLByAppendingPathComponent("Library", isDirectory: true)
let cachesURL = libraryURL.URLByAppendingPathComponent("Caches", isDirectory: true)
return cachesURL.URLByAppendingPathComponent("videoFile.mov")
我正在尝试对共享扩展中选择的视频使用 AVAssetExportSession 并获得
Error Domain=NSURLErrorDomain Code=-3000 "Cannot create file" UserInfo={NSLocalizedDescription=Cannot create file, NSUnderlyingError=0x14811fdb0 {Error Domain=NSOSStatusErrorDomain Code=-12124 "(null)"}}
但我可以在同一个 NSURL 手动创建文件而不会出错。这是我正在使用的函数
func reencodeVideo() {
let videoAsset = AVURLAsset(URL: video.url)
let videoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
print(videoTrack.estimatedDataRate)
let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPreset1920x1080)
guard let outputURL = uploadableFileURL else {
return
}
let fileManager = NSFileManager.defaultManager()
// let created = fileManager.createFileAtPath(outputURL.path!, contents: nil, attributes: nil)
if let path = outputURL.path where fileManager.fileExistsAtPath(path) {
print("file exists")
}
do {
try fileManager.removeItemAtURL(outputURL)
print("deleted")
} catch {
print(error)
}
exportSession?.outputURL = outputURL
exportSession?.outputFileType = AVFileTypeQuickTimeMovie
exportSession?.exportAsynchronouslyWithCompletionHandler{
print(exportSession?.status)
}
}
private var uploadableFileURL: NSURL? {
guard let tempFileName = video.url.lastPathComponent else {
return nil
}
let fileManager = NSFileManager.defaultManager()
guard let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier(Constants.appGroupIdentifier) else {
return nil
}
return containerURL.URLByAppendingPathComponent("videoFile.mov")
}
我已经在同一目录中成功创建了文件,但是 AVAssetExportSession returns 出现了错误。 知道我做错了什么吗?
我试过使用 AVAssetReader
和 AVAssetWriter
以及 AVAssetWriter
returns 尝试启动时出现相同的错误。如果我正在使用文档目录,编码过程会成功完成,只有在使用共享应用程序组容器时才会失败。
我无法从您的代码中找出您的 uploadableFileURL 的来源,但以下内容对我有用:
if let video = videoAsset {
let fm = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)
let url = fm[0].URLByAppendingPathComponent("\(NSDate())").URLByAppendingPathExtension("mp4")
let exporter = AVAssetExportSession(asset: video, presetName: AVAssetExportPreset3840x2160)
exporter?.outputURL = url
exporter?.outputFileType = AVFileTypeMPEG4
exporter?.exportAsynchronouslyWithCompletionHandler() { _ in
let data = NSData(contentsOfURL: url)
}
}
您的问题可能与文档文件夹和icloud 同步的使用有关。 参见 https://forums.developer.apple.com/message/77495#77495
如果你这样做:
guard let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier(Constants.appGroupIdentifier) else {
return nil
}
let libraryURL = containerURL.URLByAppendingPathComponent("Library", isDirectory: true)
let cachesURL = libraryURL.URLByAppendingPathComponent("Caches", isDirectory: true)
return cachesURL.URLByAppendingPathComponent("videoFile.mov")