我有一个嵌入滚动视图内的基本视频播放器。由于视频位于滚动视图内,因此无法保持其原始宽高比,因此我必须获取其宽高比并手动应用它。对于某些视频,应用宽高比会导致视频控件(静音、全屏)不被隐藏。这种情况发生在宽高比较窄的视频中,所以我假设这些控件被删除了。有什么解决办法可以让(静音、全屏)始终显示?
struct HustleVideoPlayerR: View {
let url: URL
@State var player = AVPlayer(url: URL(string: "https://www.google.com")!)
@State var value: Float = 0
@State var viewID = false
@State var aspect: CGSize = CGSize(width: 16, height: 9)
@State private var currentTime: Double = 0.0
@State private var totalLength: Double = 1.0
var body: some View {
VideoPlayer(player: $player, showControls: true)
.id(viewID)
.aspectRatio(aspect, contentMode: .fit)
.background(Color.black.edgesIgnoringSafeArea(.all))
.onAppear {
player = AVPlayer(url: url)
viewID.toggle()
Task {
do {
if let final = try await getVideoResolution(url: url.absoluteString) {
self.aspect = final
}
} catch { }
}
self.player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1.0, preferredTimescale: 1), queue: .main) { (_) in
self.value = self.getSliderValue()
if self.value == 1.0 {
self.player.seek(to: CMTime(seconds: 0, preferredTimescale: 1))
self.player.play()
}
if let total = self.player.currentItem?.duration.seconds, totalLength == 1.0 && total > 0.0 {
totalLength = total
}
}
}
.onDisappear {
self.player.pause()
player = AVPlayer(url: URL(string: "https://www.google.com")!)
viewID.toggle()
}
}
func getSliderValue() -> Float {
if let total = self.player.currentItem?.duration.seconds, self.player.currentTime().seconds > 0.0, total > 0.0 {
currentTime = self.player.currentTime().seconds
return Float(currentTime / total)
} else {
return 0.0
}
}
}
struct VideoPlayer : UIViewControllerRepresentable {
@Binding var player : AVPlayer
let showControls: Bool
func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPlayer>) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
controller.showsPlaybackControls = showControls
controller.allowsVideoFrameAnalysis = false
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayer>) { }
}
VideoPlayer
始终有足够的空间来显示其控件,无论视频内容的宽高比如何。ScrollView
留出足够的垂直空间。
struct HustleVideoPlayerR: View {
// your existing properties
var body: some View {
ScrollView {
VStack {
Spacer()
VideoPlayer(player: $player, showControls: true)
.id(viewID)
.aspectRatio(aspect, contentMode: .fit)
.background(Color.black.edgesIgnoringSafeArea(.all))
// Add the rest of your .onAppear and other modifiers here
Spacer()
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width / aspect.width * aspect.height)
}
.onAppear {
// your existing onAppear code
}
// any other modifiers and functions
}
}
通过用
VideoPlayer
和
VStack
包裹
Spacer()
,您可以确保它居中并约束在尊重宽高比的框架内,但也允许 ScrollView
如果需要,请滚动。