【问题标题】:AVPLayer in Swiftui resets when button is pressed按下按钮时,Swiftui 中的 AVPLayer 会重置
【发布时间】:2021-12-22 11:35:41
【问题描述】:

我有一个视频播放器,在它下面有一个标题文本。当您点击文本时,我会增加字体大小。但是,当您增加字体大小时,它会导致视频停止播放并重新启动。我不希望这种情况发生。我希望视频播放不受字体增加的影响。 我对 swiftUI 很陌生,仅供参考。

import SwiftUI

导入 AVKit

结构测试:查看 {

@State private var tapped: Bool = false
@State private var draggedOffset = CGSize.zero
@State private var fontSize: CGFloat = 20 // Change Font Size

var body: some View {
    
    VStack {
        
        VideoPlayer(player: AVPlayer(url: URL(string: "http://www.unisonprinting.com/0celot/dune/dune.mp4")!))
            .aspectRatio(3/2, contentMode: .fit)
        
        Text ("VIDEO TITLE")
            .foregroundColor(.white)
            .font(.system(size: fontSize))
            .onTapGesture {
                if self.fontSize < 44 {
                    self.fontSize = self.fontSize + 12
                } else {
                    self.fontSize = 20
                }
            }
    }//V

}

}

【问题讨论】:

    标签: swiftui avplayer


    【解决方案1】:

    现在,每个View 的主体被渲染,一个新 AVPlayer 被创建,导致视频停止播放并重新启动。

    您可以通过将AVPlayer 存储在@State 变量中来避免这种情况,该变量在渲染中持续存在:

    struct TEST: View {
        
        @State private var tapped: Bool = false
        @State private var draggedOffset = CGSize.zero
        @State private var fontSize: CGFloat = 20 // Change Font Size
        
        @State private var player = AVPlayer(url: URL(string: "https://www.unisonprinting.com/0celot/dune/dune.mp4")!)
        
        var body: some View {
            
            VStack {
                
                VideoPlayer(player: player)
                    .aspectRatio(3/2, contentMode: .fit)
                
                Text ("VIDEO TITLE")
                    .foregroundColor(.blue)
                    .font(.system(size: fontSize))
                    .onTapGesture {
                        if self.fontSize < 44 {
                            self.fontSize = self.fontSize + 12
                        } else {
                            self.fontSize = 20
                        }
                    }
            }
        }
    }
    
    

    基于 cmets 的更新显示了一种可能的解决方案,即如何让 VideoPlayer 根据不断变化的 URL 参数加载不同的 AVPlayer:

    struct ContentView: View {
        
        var url : String = "https://www.unisonprinting.com/0celot/dune/dune.mp4"
        
        @State private var tapped: Bool = false
        @State private var draggedOffset = CGSize.zero
        @State private var fontSize: CGFloat = 20 // Change Font Size
        
        @State private var player : AVPlayer?
        
        var body: some View {
            
            VStack {
                if let player = player {
                    VideoPlayer(player: player)
                        .aspectRatio(3/2, contentMode: .fit)
                }
                
                Text ("VIDEO TITLE")
                    .foregroundColor(.blue)
                    .font(.system(size: fontSize))
                    .onTapGesture {
                        if self.fontSize < 44 {
                            self.fontSize = self.fontSize + 12
                        } else {
                            self.fontSize = 20
                        }
                    }
            }
            .onAppear {
                setPlayerToUrl(url)
            }
            .onChange(of: url) { url in
                setPlayerToUrl(url)
            }
        }
        
        func setPlayerToUrl(_ url: String) {
            player = AVPlayer(url: URL(string: url)!)
        }
    }
    

    【讨论】:

    • 谢谢。这可行,但如果我希望 URL 是一个变量,所以它可以是不同的 URL?
    • 有很多可能的解决方案——我添加了一个作为更新。您还可以考虑将您的 URL 和 AVPlayer 存储在带有@Published 属性的ObservableObject 中,并使用Combine 来查看更改/控制更新等
    • 好的。如果我想使用 ForEach 遍历 URL 怎么办?我有一个模型,其中一个属性是 URL 字符串
    • @ReneRobles 我不太清楚你的意思——这个视图绝对可以在ForEach 中使用。除此之外,我需要更多细节。话虽如此,我相信我已经回答了原始问题,以及更改 URL 的附加要求。如果您认为原始问题已得到解答,请考虑使用绿色复选标记将其标记为正确。如果你觉得它有帮助,你也可以投票。我也很乐意回答其他实施问题,但似乎ForEach 一个可能适合一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    相关资源
    最近更新 更多