我试图通过禁用YouTube视频并在其上方放置一个可点击的清晰视图来覆盖YouTube默认的播放和暂停按钮.当点击清晰视图时,它会更改决定是否播放视频的绑定(此视频也会自动播放).
目前,isVideoPlaying变量确实正确地更改了,并且HTML确实接受了更改.现在的问题是,我添加了一个事件侦听器"onClick",这永远不会执行.我需要将此事件侦听器更改为更改isVideoPlaying.
但我不知道该怎么做.点击Clear View会暂停或播放视频的唯一原因是,当点击Clear View时,会迅速重新加载整个视频,从而使其通过onReady部分.这是另一个问题,我不希望YouTube视频在每次点击Clear View时都重新加载.我想让它简单地播放和暂停,而不需要重新加载.
作为参考,我正试着用YouTube短裤制作TikTok的克隆.
import SwiftUI
import WebKit
struct SingleVideoView: View {
let link: String
@State private var isVideoPlaying = true
var body: some View {
ZStack {
SmartReelView(link: link, isPlaying: $isVideoPlaying)
Button("", action: {}).disabled(true)//to disable YouTube video
Color.gray.opacity(0.001)
.onTapGesture {
isVideoPlaying.toggle()
}
}
.ignoresSafeArea()
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SingleVideoView(link: "-q6-DxWZnlQ")
}
}
struct SmartReelView: UIViewRepresentable {
let link: String
@Binding var isPlaying: Bool
@Environment(\.colorScheme) var colorScheme
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
return WKWebView(frame: .zero, configuration: webConfiguration)
}
func updateUIView(_ uiView: WKWebView, context: Context) {
let embedHTML = """
<style>
.iframe-container iframe {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
<div class="iframe-container">
<div id="player"></div>
</div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
width: '100%',
videoId: '\(link)',
playerVars: { 'autoplay': 1, 'playsinline': 1 },
events: {
'onReady': function(event) {
var isPlaying = \((isPlaying) ? "true" : "false");
if (isPlaying) {
event.target.mute();
if (isPlaying) {
event.target.playVideo();
}
}
}
}
});
}
function watchPlayingState() {
if (isPlaying) {
player.playVideo();
} else {
player.pauseVideo();
}
}
document.addEventListener('click', function() {
watchPlayingState();
});
</script>
"""
uiView.scrollView.isScrollEnabled = false
uiView.loadHTMLString(embedHTML, baseURL: nil)
}
}
更新
在提供以下答案后,我进一步修改了代码:
这段新代码收到错误"类型‘SmartReelView’不符合协议‘UIView’".
struct SmartReelView: UIViewRepresentable {
let link: String
@Binding var isPlaying: Bool
@Environment(\.colorScheme) var colorScheme
var webView: WKWebView?
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, WKNavigationDelegate {
var parent: SmartReelView
init(_ parent: SmartReelView) {
self.parent = parent
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
parent.webView = webView
}
}
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = context.coordinator
return webView
}
mutating func updateUIView(_ uiView: WKWebView, context: Context) {
if webView == nil {
webView = uiView
let embedHTML = """
<style>
.iframe-container iframe {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
<div class="iframe-container">
<div id="player"></div>
</div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
var isPlaying = true;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
width: '100%',
videoId: '\(link)',
playerVars: { 'autoplay': 1, 'playsinline': 1 },
events: {
'onReady': function(event) {
event.target.mute();
event.target.playVideo();
}
}
});
}
function watchPlayingState() {
if (isPlaying) {
player.playVideo();
} else {
player.pauseVideo();
}
}
</script>
"""
uiView.scrollView.isScrollEnabled = false
uiView.loadHTMLString(embedHTML, baseURL: nil)
}
let jsString = "isPlaying = \((isPlaying) ? "true" : "false"); watchPlayingState();"
webView?.evaluateJavaScript(jsString, completionHandler: nil)
}
}