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

Swift中AVAsset.duration已废弃,同步函数中如何改用异步替代?

解决AVAsset异步加载属性后依赖代码的执行问题

由于AVAsset的同步属性(如duration、tracks)已被废弃,改用异步load(_:)方法后,核心问题是确保依赖这些属性的代码在加载完成后执行,以下是几种可行的处理方式:

1. 将依赖逻辑直接移入异步任务内部

把原本需要用到duration、fps的后续代码(比如文件完整性检查),直接放在异步加载成功的代码块中,这样能保证数据准备好后再执行逻辑:

Task {
    do {
        // 异步加载所需属性
        self.duration = try await avAsset.load(.duration)
        self.tracks = try await avAsset.load(.tracks)
        self.fps = try await self.tracks.first?.load(.nominalFrameRate) ?? 30
        
        // 这里执行依赖这些属性的后续逻辑,比如文件完整性检查
        checkFileIntegrity()
    } catch {
        Globals.logger.error("MoviePlayer - loadMovie error fetching metadata")
        // 可选:添加错误后的降级处理,比如标记文件无效
    }
}

// 定义文件完整性检查函数
private func checkFileIntegrity() {
    // 用已加载的属性执行检查逻辑
    if self.duration.seconds <= 0 || self.fps <= 0 {
        // 处理文件不完整的情况
    }
}

2. 将加载逻辑封装为异步函数,调用时等待完成

如果原同步函数可以改为异步函数,可将属性加载逻辑封装成单独的async throws方法,调用时通过await等待加载完成,再执行后续代码:

// 封装异步加载逻辑
private func loadMovieMetadata() async throws {
    self.duration = try await avAsset.load(.duration)
    self.tracks = try await avAsset.load(.tracks)
    self.fps = try await self.tracks.first?.load(.nominalFrameRate) ?? 30
}

// 调用时(非异步上下文用Task包裹)
Task {
    do {
        try await loadMovieMetadata()
        // 加载完成后执行依赖逻辑
        checkFileIntegrity()
    } catch {
        Globals.logger.error("MoviePlayer - loadMovie error fetching metadata")
    }
}

3. 确保主线程更新UI/属性

如果duration、fps等属性用于更新UI,需注意异步任务默认可能不在主线程执行,要通过MainActor确保UI更新在主线程:

方式一:直接在Task中指定MainActor

Task { @MainActor in
    do {
        self.duration = try await avAsset.load(.duration)
        self.tracks = try await avAsset.load(.tracks)
        self.fps = try await self.tracks.first?.load(.nominalFrameRate) ?? 30
        
        checkFileIntegrity()
        // 这里可以直接更新UI,比如刷新播放进度显示
    } catch {
        Globals.logger.error("MoviePlayer - loadMovie error fetching metadata")
    }
}

方式二:先加载数据,再在主线程更新属性

Task {
    do {
        // 先在后台加载数据
        let duration = try await avAsset.load(.duration)
        let tracks = try await avAsset.load(.tracks)
        let fps = try await tracks.first?.load(.nominalFrameRate) ?? 30
        
        // 切换到主线程更新属性和执行逻辑
        await MainActor.run {
            self.duration = duration
            self.tracks = tracks
            self.fps = fps
            checkFileIntegrity()
        }
    } catch {
        Globals.logger.error("MoviePlayer - loadMovie error fetching metadata")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:43:15