diff --git a/wake/Assets/Images/Gif/BlindOpen.gif b/wake/Assets/Images/Gif/BlindOpen.gif index e4533ed..fcfdb50 100644 Binary files a/wake/Assets/Images/Gif/BlindOpen.gif and b/wake/Assets/Images/Gif/BlindOpen.gif differ diff --git a/wake/ContentView.swift b/wake/ContentView.swift index b37c578..77ea40e 100644 --- a/wake/ContentView.swift +++ b/wake/ContentView.swift @@ -501,6 +501,7 @@ struct BlindBoxView: View { self.displayImage = image self.aspectRatio = image.size.width / image.size.height self.isPortrait = image.size.height > image.size.width + self.showScalingOverlay = true // 确保显示媒体内容 } } }.resume() @@ -526,11 +527,53 @@ struct BlindBoxView: View { isPortrait = height > width } - // Update the video player + // 更新视频播放器 videoPlayer = player videoPlayer?.play() + showScalingOverlay = true // 确保显示媒体内容 } + private func prepareVideo() { + guard !videoURL.isEmpty, let url = URL(string: videoURL) else { + print("⚠️ 视频URL无效或为空") + return + } + + let asset = AVAsset(url: url) + let playerItem = AVPlayerItem(asset: asset) + let player = AVPlayer(playerItem: playerItem) + + let videoTracks = asset.tracks(withMediaType: .video) + if let videoTrack = videoTracks.first { + let size = videoTrack.naturalSize.applying(videoTrack.preferredTransform) + let width = abs(size.width) + let height = abs(size.height) + + aspectRatio = width / height + isPortrait = height > width + } + + // 更新视频播放器 + videoPlayer = player + } + + private func prepareImage() { + guard !imageURL.isEmpty, let url = URL(string: imageURL) else { + print("⚠️ 图片URL无效或为空") + return + } + + URLSession.shared.dataTask(with: url) { data, _, _ in + if let data = data, let image = UIImage(data: data) { + DispatchQueue.main.async { + self.displayImage = image + self.aspectRatio = image.size.width / image.size.height + self.isPortrait = image.size.height > image.size.width + } + } + }.resume() + } + private func startScalingAnimation() { self.scale = 0.1 self.showScalingOverlay = true @@ -822,15 +865,30 @@ struct BlindBoxView: View { .frame(width: 300, height: 300) case .opening: - GIFView(name: "BlindOpen") - .frame(width: 300, height: 300) - .onAppear { - self.loadMedia() - // Start animation after media is loaded - DispatchQueue.main.asyncAfter(deadline: .now() + 5) { - self.startScalingAnimation() + ZStack { + GIFView(name: "BlindOpen") + .frame(width: 300, height: 300) + .onAppear { + print("开始播放开启动画") + // 不在这里准备媒体,等待动画完成 + + // 2.5秒后开始显示媒体内容 + DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) { + // 准备并显示媒体 + if mediaType == .video { + loadVideo() + } else if mediaType == .image { + loadImage() + } + + // 开始缩放动画 + withAnimation(.easeInOut(duration: 0.5)) { + self.startScalingAnimation() + } + } } - } + } + .frame(width: 300, height: 300) case .none: SVGImage(svgName: "BlindNone") diff --git a/wake/View/Blind/BlindOutCome.swift b/wake/View/Blind/BlindOutCome.swift index b07430b..f4db1a5 100644 --- a/wake/View/Blind/BlindOutCome.swift +++ b/wake/View/Blind/BlindOutCome.swift @@ -162,6 +162,12 @@ struct BlindOutcomeView: View { } .padding(.bottom, 20) } + .onDisappear { + // Clean up video player when view disappears + if case .video = media { + isPlaying = false + } + } } .navigationBarHidden(true) // 确保隐藏系统导航栏 .navigationBarBackButtonHidden(true) // 确保隐藏系统返回按钮 @@ -169,6 +175,9 @@ struct BlindOutcomeView: View { } .navigationViewStyle(StackNavigationViewStyle()) // 确保在iPad上也能正确显示 .navigationBarHidden(true) // 额外确保隐藏导航栏 + .overlay( + JoinModal(isPresented: $showIPListModal) + ) } } @@ -293,14 +302,18 @@ struct VideoPlayerView: UIViewRepresentable { class PlayerView: UIView { private var player: AVPlayer? private var playerLayer: AVPlayerLayer? + private var playerItem: AVPlayerItem? + private var playerItemObserver: NSKeyValueObservation? func setupPlayer(url: URL) { - // Remove existing player if any - playerLayer?.removeFromSuperlayer() + // Clean up existing resources + cleanup() // Create new player let asset = AVAsset(url: url) let playerItem = AVPlayerItem(asset: asset) + self.playerItem = playerItem + player = AVPlayer(playerItem: playerItem) // Setup player layer @@ -329,6 +342,27 @@ class PlayerView: UIView { player?.pause() } + private func cleanup() { + // Remove observers + if let playerItem = playerItem { + NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: playerItem) + } + + // Pause and clean up player + player?.pause() + player?.replaceCurrentItem(with: nil) + player = nil + + // Remove player layer + playerLayer?.removeFromSuperlayer() + playerLayer = nil + + // Release player item + playerItem?.cancelPendingSeeks() + playerItem?.asset.cancelLoading() + playerItem = nil + } + @objc private func playerItemDidReachEnd() { player?.seek(to: .zero) player?.play() @@ -340,9 +374,7 @@ class PlayerView: UIView { } deinit { - player?.pause() - player?.replaceCurrentItem(with: nil) - NotificationCenter.default.removeObserver(self) + cleanup() } }