我正在使用YouTube短片创建TikTok克隆,我想获得视频长度。为此,我在嵌入式html中创建了一个函数,该函数使用WKScriptMessageHandler发布消息,userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){
函数应该拾取此消息并更新totalLength变量。
但目前这并不起作用。消息永远不会发送,因此上面的函数永远不会执行。但是html func sendCurrentTime()
会在WKWebView完成加载时执行。我怎么知道为什么这条消息没有发送?
据我所知,由于web视图配置不正确或html无法访问web视图对象,因此无法发送消息。
struct SmartReelView: UIViewRepresentable {
let link: String
@Binding var totalLength: Double
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
let webview = WKWebView(frame: .zero, configuration: webConfiguration)
webview.navigationDelegate = context.coordinator
let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name: "observe")
webview.configuration.userContentController = userContentController
loadInitialContent(web: webview)
return webview
}
func updateUIView(_ uiView: WKWebView, context: Context) { }
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var parent: SmartReelView
init(_ parent: SmartReelView) {
self.parent = parent
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){
if message.name == "observe", let Time = message.body as? Double {
parent.totalLength = Time
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("sendCurrentTime()", completionHandler: nil)
}
}
private func loadInitialContent(web: WKWebView) {
let embedHTML = """
<style>
body {
margin: 0;
background-color: black;
}
.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 = false;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
width: '100%',
videoId: '\(link)',
playerVars: { 'playsinline': 1, 'controls': 0},
events: {
'onStateChange': function(event) {
if (event.data === YT.PlayerState.ENDED) {
player.seekTo(0);
player.playVideo();
}
}
}
});
}
function sendCurrentTime() {
const length = player.getDuration();
window.webkit.messageHandlers.observe.postMessage(length);
}
</script>
"""
web.scrollView.isScrollEnabled = false
web.loadHTMLString(embedHTML, baseURL: nil)
}
}
1条答案
按热度按时间3pvhb19x1#
我在自己的项目上做了一个快速测试。似乎将配置传递给Webview的顺序很重要。
这行不通。如果在未设置userContentController的情况下首先初始化Web视图,则无法获取回调。
这很管用!