I was trying to load short videos from a URL and I found the best way is to use AVPlayer, I found the code below but it didn't show the activity indicator also if the user doesn't have an internet it won't play the video. Thanks in advance.
import SwiftUI
import AVKit
struct ContentView: View {
@State var player = AVPlayer(url: URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4")!)
@State var isplaying = false
@State var showcontrols = false
@State var value : Float = 0
var body: some View {
VStack{
ZStack{
VideoPlayer(player: $player)
if self.showcontrols{
Controls(player: self.$player, isplaying: self.$isplaying, pannel: self.$showcontrols,value: self.$value)
}
}
.frame(height: UIScreen.main.bounds.height / 3.5)
.onTapGesture {
self.showcontrols = true
}
GeometryReader{_ in
VStack{
Text("Custom Video Player").foregroundColor(.white)
}
}
}
.background(Color.black.edgesIgnoringSafeArea(.all))
.onAppear {
self.player.play()
self.isplaying = true
}
}
}
This is the main screen which is ContentView
struct Controls : View {
@Binding var player : AVPlayer
@Binding var isplaying : Bool
@Binding var pannel : Bool
@Binding var value : Float
var body : some View{
VStack{
Spacer()
HStack{
Button(action: {
if self.isplaying{
self.player.pause()
self.isplaying = false
}
else{
self.player.play()
self.isplaying = true
}
if self.player.currentItem?.duration.seconds == self.player.currentTime().seconds{
print("did it")
self.player.seek(to: CMTime.zero)
self.player.play()
self.isplaying = true
}
}) {
Image(systemName: self.isplaying ? "pause.fill" : "play.fill")
.font(.title)
.foregroundColor(.white)
.padding(20)
}
}
}.padding()
.onTapGesture {
self.pannel = false
}
}
func getSliderValue()->Float{
return Float(self.player.currentTime().seconds / (self.player.currentItem?.duration.seconds)!)
}
func getSeconds()->Double{
return Double(Double(self.value) * (self.player.currentItem?.duration.seconds)!)
}
}
The button for control the video.
class Host : UIHostingController<ContentView>{
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
}
struct VideoPlayer : UIViewControllerRepresentable {
@Binding var player : AVPlayer
func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPlayer>) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
controller.showsPlaybackControls = false
controller.videoGravity = .resize
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayer>) {
}
}