你好,我一直在想一种方法,当用户执行放大手势,将YouTube视频全屏输入时,执行一项功能.我try 了几种不同的方法进入全屏,但都没有奏效.我很感激你们的帮助.

以下是我try 过的:

 webView.evaluateJavaScript("document.querySelector('.iframe-container iframe').requestFullscreen()") { object, error in
                    print(error?.localizedDescription ?? "")
                }
   webView.evaluateJavaScript("document.getElementById('player').contentDocument.getElementsByClassName('video-stream')[0].webkitEnterFullScreen()") { object, error in
                       print(error?.localizedDescription ?? "")
                   }

下面是我的html:

    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: 'es5Ct9flpIg',
                    playerVars: { 'playsinline': 1, 'controls': 0},
                    events: {
                        'onStateChange': function(event) {
                            if (event.data === YT.PlayerState.ENDED) {
                                player.seekTo(0);
                                player.playVideo();
                            }
                        }
                    }
                });
            }
        </script>
        """
        
        web.scrollView.isScrollEnabled = false
        web.loadHTMLString(embedHTML, baseURL: nil)
    }

推荐答案

为了以编程方式控制YouTube播放和处理全屏模式,我建议使用YouTube's Iframe API,它提供了一系列事件和函数来控制YouTube播放器.既然您已经将YouTube iframe API集成到了您的HTML中,那么您可以使用player对象来控制视频播放和其他设置.

请注意,由于安全性和可用性问题,在没有用户手势的情况下,JavaScript无法强制使用全屏模式.浏览器对此进行限制,以保持用户对浏览体验的控制.(请参见Element: requestFullscreen() method).

但是,您可以做的是确保当用户单击YouTube播放器控件中的全屏按钮时,YouTube播放器进入全屏模式.为此,您应该在YT.Player初始化中更新playerVars以允许控件,并删除'playsinline' parameter或将其设置为0,如下所示:

playerVars: { 'playsinline': 0, 'controls': 1 }

通过设置'playsinline': 0,您应该会看到视频在iOS设备上播放时进入全屏模式.

如果您想要在用户将视频切换到全屏模式时执行操作,您可以监听onFullscreenChange事件,但这需要浏览器支持,并不是所有浏览器都可以使用.

虽然你可以将YouTube iframe设置为更自然地进入全屏模式,但到目前为止,在没有用户直接操作的情况下以编程方式触发全屏似乎仍然受到限制.


这种进入全屏的操作将是放大手势的结果.我不想使用YouTube全屏按钮.有没有其他方法可以覆盖该按钮,而使用放大手势来执行嵌入的HTML中的函数?

我试着保持‘playsinline: 1’,然后当用户执行放大手势时,Swift执行webView.evaluateJavaScript("changePlayInline()", completionHandler: nil).changePlayInline()函数将其调用为player.getOptions().playsinline = 0;,但这不起作用.

我认为在创建播放器后动态更改playsinline参数是不起作用的,因为它是在播放器初始化时定义的设置,不能动态更新.

要实现通过放大手势进入全屏,您需要在SWIFT中创建自定义手势识别器,该识别器在识别放大手势后,触发一个JavaScript函数来切换YouTube视频播放器的全屏模式.

一种可能的解决方案可能涉及当检测到放大手势时用更新的playsinline参数重新加载播放器:

  • 在您的SWIFT代码中创建自定义手势识别器以检测放大手势.
  • 检测到放大手势后,使用webView.evaluateJavaScript调用一个JavaScript函数.
  • 在JavaScript函数中,重新加载YouTube播放器,并将playsinline参数设置为0以启用全屏模式.
let magnificationGesture = UIPinchGestureRecognizer(target: self, action: #selector(didMagnify(_:)))
webView.addGestureRecognizer(magnificationGesture)

@objc func didMagnify(_ gesture: UIPinchGestureRecognizer) {
    if gesture.state == .ended {
        webView.evaluateJavaScript("enterFullscreenMode()", completionHandler: nil)
    }
}

在您的HTML/JavaScript中:

function enterFullscreenMode() {
    player.destroy(); // Destroy the current player instance
    player = new YT.Player('player', {
        width: '100%',
        videoId: 'es5Ct9flpIg',
        playerVars: { 'playsinline': 0, 'controls': 0},
        events: {
            'onStateChange': function(event) {
                if (event.data === YT.PlayerState.ENDED) {
                    player.seekTo(0);
                    player.playVideo();
                }
            }
        }
    });
}

That would destroy the existing player and creates a new one with the updated playsinline parameter, effectively entering fullscreen mode.
But... this would result in the video reloading, and potentially creating a non-seamless experience for the user. It is a limitation imposed by the inability to change the playsinline parameter dynamically.


这当然是有效的,但正如您所说,首先重新加载视频.您在回答中提到使用requestFullscreen()方法.

这是一种无需重新加载视频即可进入全屏的可行方法吗?我试过用它,但没有成功.

是的,使用requestFullscreen方法可能会允许在不重新加载视频的情况下进入全屏模式.然而,由于浏览器的安全策略,通过JavaScript以编程方式触发全屏通常需要由用户操作(如单击事件)启动.

假设您在SWIFT中检测到放大手势,然后try 通过执行JavaScript执行requestFullscreen方法,浏览器可能会阻止它,将其解释为不是由用户操作发起的.

尽管有这些限制,您仍然可以try 直接在视频元素上执行requestFullscreen.为此,您首先需要获取对表示YouTube视频播放器的正确DOM元素的引用,然后对其调用requestFullscreen方法.

@objc func didMagnify(_ gesture: UIPinchGestureRecognizer) {
    if gesture.state == .ended {
        webView.evaluateJavaScript("document.querySelector('iframe').requestFullscreen();", completionHandler: nil)
    }
}

如果上面的方法不起作用,很可能是由于浏览器在没有用户在网页内直接操作的情况下以编程方式进入全屏的限制.

为了避免这一点,另一种方法可能涉及创建自定义的"全屏"体验,通过调整iframe的css来占据整个视图,从而有效地模拟全屏行为.从技术上讲,这不是全屏,但这可能是一个足够的变通办法,可以在不重新加载视频的情况下创造更身临其境的观看体验.

Html相关问答推荐

Chrome中是否有一个本地显示密码功能,用于`input type = password/`?""<"">

CSS复选框并排

Font Awesome 6插入符号未显示

CSS自定义特性中的URL是否可以相对于定义的CSS文件?

禁用与行分开的边框折叠span

如何让QML`Text`元素内的链接在悬停时显示鼠标指针?

如何使我的组织 struct 图的连接线响应?

使用css第n个子元素,如何迭代Y组中的X个元素?

现代网络浏览器可以并行下载哪些类型的网络资源?还有,什么东西不能并行下载?

如何在网格中拥有离散的行

Web 组件 #shadow-root css 泄漏到文档

无法在 CSS 中将 h1 标签居中

如何将内容放置在侧边栏旁边?

Angular中如何向单选按钮添加验证

使用flex wrap时,如何设置另一个元素的宽度与换行后的元素对齐?

如何配置 prettier 使其以 Vue.js 模板语法的特定方式运行?

如何清除html输入中的文本

防止按钮溢出到新行

样式不适用于来自 tailwindcss 的网络

如何使用 html 和 css 添加超链接功能