Reputation: 83
I am trying to make a video player in my app (with swiftUI) that playes videos from youtube when the user creates a URL string. To practise I have seperated this into a new project to see that it works. But the screen is just black with a play button. Nothing happends when I press the play button or the screen. This is my code:
import SwiftUI
import AVKit
struct ContentView: View {
let url = URL(string: "https://youtu.be/Wlf1T5nrO50")!
var body: some View {
VStack{
VideoPlayer(player: AVPlayer(url: url))
.scaledToFit()
}
}
I found another video with how to make embedded youtube videos but then you need to just copy the video ID and my user is not that advanced. I want the user to be able to just copy the URL.
Thankful for any help.
Upvotes: 3
Views: 9287
Reputation: 1660
An alternative slightly different that I came up with and looks more clean is the following:
import SwiftUI
import WebKit
struct YouTubePlayerView: UIViewRepresentable {
private let url: URL
init?(videoID: String) {
guard let url = URL(string: "https://www.youtube.com/embed/\(videoID)") else { return nil }
self.init(url: url)
}
init(url: URL) {
self.url = url
}
// MARK: Functions
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
let request = URLRequest(url: url)
uiView.load(request)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: YouTubePlayerView
init(_ parent: YouTubePlayerView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
}
}
It supports the initialisation through URL or just by VideoID. updateUIView seems a better place to load the url and the coordinator allows you do perform extra actions if needed upon loading, finishing etc
Upvotes: 0
Reputation: 1002
A better Solution I made
struct YoutubeVideoView: UIViewRepresentable {
var youtubeVideoID: String
func makeUIView(context: Context) -> WKWebView {
WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
let path = "https://www.youtube.com/embed/\(youtubeVideoID)"
guard let url = URL(string: path) else { return }
uiView.scrollView.isScrollEnabled = false
uiView.load(.init(url: url))
}
}
Upvotes: 9
Reputation: 5084
A YouTube url is not a valid video URL. You have to either add youtube's library or play it using a WKWebView.
Also check out this package, it's awesome!
Using WKWebView:
struct LinkView: View {
var link: String
var body: some View {
WebView(url: URL(string: link.embed)!)
}
}
struct WebView: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
let request = URLRequest(url: url)
webView.load(request)
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
extension String {
var embed: String {
var strings = self.components(separatedBy: "/")
let videoId = strings.last ?? ""
strings.removeLast()
let embedURL = strings.joined(separator: "/") + "embed/\(videoId)"
return embedURL
}
}
Usage:
LinkView(link: "https://youtube.com/videoid")
Remember, this is a very basic WebView that does not handle errors and loading.
Upvotes: 0