如何摆脱此警告
await exportSession.export()
:
代码:
func extractAudioFromImportedVideo(videoURL: URL, success: @escaping ((URL) -> Void), failure: @escaping ((Error?) -> Void)) async {
do {
let asset = AVURLAsset(url: videoURL)
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
guard !audioTracks.isEmpty else {
failure(NSError(domain: "Audio Extraction Error", code: 0, userInfo: [NSLocalizedDescriptionKey: "Video does not contain audio"]))
return
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
failure(NSError(domain: "Audio Extraction Error", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create export session"]))
return
}
guard let audioURL = makeFileOutputURL(fileName: "ExtractedAudio.m4a") else {
failure(NSError(domain: "Audio Extraction Error", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create output URL"]))
return
}
print("audioTracks", audioTracks)
exportSession.outputURL = audioURL
exportSession.outputFileType = .m4a
await exportSession.export()
print("exportSession.status", exportSession.status.rawValue)
if exportSession.status == .completed {
// Audio extraction succeeded
print("Audio extraction succeeded")
success(audioURL)
} else {
// Audio extraction failed
print("Audio extraction failed: \(exportSession.error?.localizedDescription ?? "")")
failure(exportSession.error)
}
}
catch {
print("extractAudioFromImportedVideo Error:", error.localizedDescription)
}
}
避免此错误的简单方法是使您的函数
nonisolated
:
nonisolated func extractAudioFromImportedVideo(videoURL: URL, success: @escaping ((URL) -> Void), failure: @escaping ((Error?) -> Void)) async {
…
}
就我个人而言,我会消除这些关闭并遵循
async
模式:
nonisolated func extractAudioFromImportedVideo(videoURL: URL) async throws -> URL {
do {
let asset = AVURLAsset(url: videoURL)
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
guard !audioTracks.isEmpty else {
throw AudioExtractionError.noAudio
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
throw AudioExtractionError.exportFailed
}
guard let audioURL = makeFileOutputURL(fileName: "ExtractedAudio.m4a") else {
throw AudioExtractionError.outputUrlFailed
}
print("audioTracks", audioTracks)
exportSession.outputURL = audioURL
exportSession.outputFileType = .m4a
await exportSession.export()
print("exportSession.status", exportSession.status.rawValue)
if let error = exportSession.error {
throw error
}
print("Audio extraction succeeded")
return audioURL
} catch {
print("extractAudioFromImportedVideo Error:", error.localizedDescription)
throw error
}
}
注意,我也退休了
NSError
,替换为:
enum AudioExtractionError: LocalizedError {
case noAudio
case exportFailed
case outputUrlFailed
nonisolated var errorDescription: String? {
return switch self {
case .noAudio: NSLocalizedString("Video does not contain audio", comment: "AudioExtractionError")
case .exportFailed: NSLocalizedString("Failed to create export session", comment: "AudioExtractionError")
case .outputUrlFailed: NSLocalizedString("Failed to create output URL", comment: "AudioExtractionError")
}
}
}
这实际上是本地化的,将细节与该函数隔离,并且枚举错误支持更丰富的错误处理。
FWIW,一旦你完成了这项工作,你就可以消除很多麻烦,进一步简化:
nonisolated func extractAudioFromImportedVideo(videoURL: URL) async throws -> URL {
let asset = AVURLAsset(url: videoURL)
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
guard !audioTracks.isEmpty else {
throw AudioExtractionError.noAudio
}
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
throw AudioExtractionError.exportFailed
}
guard let audioURL = makeFileOutputURL(fileName: "ExtractedAudio.m4a") else {
throw AudioExtractionError.outputUrlFailed
}
exportSession.outputURL = audioURL
exportSession.outputFileType = .m4a
await exportSession.export()
if let error = exportSession.error {
throw error
}
return audioURL
}