You need to enable JavaScript to run this app. AVPlayer使用Firebase Firestore视频链接切屏刷新重启如何解决
优惠活动
大模型
产品
解决方案
定价
更多

AVPlayer使用Firebase Firestore视频链接切屏刷新重启如何解决

问题根因定位

播放重置和Firestore数据库请求无关联,核心触发逻辑是AVPlayer实例的创建位置完全嵌套在SwiftUI的body渲染流程内。当设备方向切换时,iOS会触发当前视图的body重新求值,每次重绘都会执行全屏播放页内的let avPlayer = AVPlayer(url: ...)代码,生成一个全新的播放器实例替换掉原有正在播放的对象,最终表现为视频重新加载、从头播放。整个过程不会重新发起Firebase数据请求,因为视频链接是已经加载完成的本地缓存值。

基于init()的修复实现

核心改造逻辑:

  • 将AVPlayer实例从即时渲染的视图闭包中抽离为独立的存储属性,保证整个播放会话全程仅存在唯一的播放器实例,不会被视图重绘流程覆盖
  • 在视图的init()初始化阶段完成播放器实例的创建,复用已经获取到的Firebase视频链接,不重复发起网络请求
  • 调整自动播放的触发逻辑,避免重复调用play()接口打断当前播放进度
import SwiftUI
import AVKit
import AVFoundation

struct MoviePlayerView: View {
    // 保留原有业务逻辑
    @State var firebasedb: Movies
    @ObservedObject var movies = GetMoviesData()
    @State private var isPlayed = false
    
    // 独立存储的全局唯一AVPlayer实例,不随视图重绘销毁
    private let avPlayer: AVPlayer
    
    // 按需求在init阶段完成播放器初始化
    init(firebasedb: Movies) {
        self.firebasedb = firebasedb
        // 初始化时直接读取已缓存的Firebase视频地址,仅创建一次实例
        guard let validURL = URL(string: firebasedb.video) else {
            // 无效链接兜底
            self.avPlayer = AVPlayer()
            return
        }
        self.avPlayer = AVPlayer(url: validURL)
    }
    
    var body: some View {
        VStack {
            Button(action: {
                self.isPlayed.toggle()
            }) {
                Image(systemName: "play.circle")
                    .font(.system(size: 50, weight: .light))
            }
        }
        .fullScreenCover(isPresented: $isPlayed) {
            // 直接复用全局唯一的avPlayer实例,不再重复创建
            VideoPlayer(player: avPlayer)
                .onAppear {
                    // 仅在首次进入播放页、进度为0时触发自动播放
                    if avPlayer.currentTime() == .zero {
                        avPlayer.play()
                    }
                }
                .edgesIgnoringSafeArea(.all)
        }
    }
}
关键注意事项
  • 禁止在body的即时作用域、fullScreenCover内容闭包、onAppear回调中创建作为UI绑定值的AVPlayer实例,这类临时变量的生命周期和单次视图渲染强绑定,播放状态无法跨重绘周期保留
  • 方向切换触发视图重绘时,代码流程只会重新渲染UI结构,不会重复执行init()内的播放器创建逻辑,原有播放器的播放进度、缓冲状态会被完整保留
  • 整个修复流程不会触发额外的Firestore数据库请求,所有视频地址参数都是初始化时从已加载的本地数据中读取的,完全避免重复拉取数据的链路

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 05:54:03