You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift合并音频文件出现“建议使用异步替代函数”警告原因咨询

音频合并代码中AVAssetExportSession警告的原因及修复

警告产生的原因

苹果在iOS 15、macOS 12及以上系统中,为AVAssetExportSession新增了支持async/await的异步导出API(不带闭包的exportAsynchronously()重载)。而你当前使用的是旧版闭包回调方式,且你的函数本身已标记为async,编译器会提示你改用更适配Swift并发模型的新API——这样代码逻辑更连贯,还能避免嵌套回调带来的混乱。

代码修复方案

把闭包调用替换为async/await版本,同时优化函数结构,去掉冗余的completion闭包,直接返回结果或抛出错误:

func mergeAudios(recordings: [Recording]) async throws -> AVAssetExportSession {
    let composition = AVMutableComposition()
    var lastTime: CMTime = .zero
    
    guard let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) else {
        throw NSError(domain: "AudioMergeError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无法创建音频轨道"])
    }
    
    for recording in recordings {
        let asset = AVURLAsset(url: recording.fileURL)
        // 异步加载音频轨道和时长,统一处理错误
        let tracks = try await asset.loadTracks(withMediaType: .audio)
        guard let track = tracks.first else {
            throw NSError(domain: "AudioMergeError", code: -2, userInfo: [NSLocalizedDescriptionKey: "该音频文件无有效音频轨道"])
        }
        let duration = try await asset.load(.duration)
        
        try await audioTrack.insertTimeRange(CMTimeRange(start: .zero, duration: duration), of: track, at: lastTime)
        lastTime = CMTimeAdd(lastTime, duration)
    }
    
    // 用更安全的方式构造临时输出URL
    let tempDir = URL(fileURLWithPath: NSTemporaryDirectory())
    let tempURL = tempDir.appendingPathComponent("MergedAudio-\(Date()).m4a")
    
    guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else {
        throw NSError(domain: "AudioMergeError", code: -3, userInfo: [NSLocalizedDescriptionKey: "无法创建导出会话"])
    }
    exportSession.outputFileType = .m4a
    exportSession.outputURL = tempURL
    
    // 使用async/await版本的导出方法
    try await exportSession.exportAsynchronously()
    
    return exportSession
}

public struct Recording: Hashable {
    public let uid: UUID
    public var fileURL: URL
    
    public init(fileURL: URL) {
        uid = UUID()
        self.fileURL = fileURL
    }
}

额外优化说明

  • 统一错误处理:替换原有的打印错误逻辑为抛出错误,让调用方可针对性处理失败场景
  • 安全路径构造:用appendingPathComponent替代字符串拼接,避免路径格式错误
  • 简化回调逻辑:利用函数的async特性直接返回结果,更符合Swift并发范式
  • 合并异步操作:将加载轨道和时长的代码合并,减少重复的do-catch块

内容的提问来源于stack exchange,提问作者Ahmed Zaidan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:32:40