You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WebView2中的YouTube原生播放器支持全屏显示?

WebView2嵌入YouTube视频全屏失效问题修复方案

核心问题与修复步骤:

  1. 开启WebView2全屏权限
    WebView2默认可能禁用全屏功能,初始化时必须手动开启:

    webView21.CoreWebView2.Settings.IsFullscreenEnabled = true;
    
  2. YouTube iframe添加全屏允许参数
    在嵌入视频的iframe地址中加入fs=1参数,允许播放器触发全屏操作:

    src='https://www.youtube.com/embed/QgMnE1No_6A?enablejsapi=1&fs=1'
    
  3. 修正JS与C#的消息通信逻辑
    原代码中fullscreenchange事件发送的消息与C#端判断的内容不匹配,且全屏状态判断逻辑有误,修改JS部分:

    document.addEventListener('fullscreenchange', function () {
        // 判断当前是否处于全屏状态
        const isFullscreen = document.fullscreenElement !== null;
        // 向C#发送对应状态消息
        window.chrome.webview.postMessage(isFullscreen ? 'enteredFullscreen' : 'exitedFullscreen');
    });
    

    同时移除onPlayerStateChange中错误的external调用逻辑,该逻辑不仅未注册external对象,还颠倒了全屏触发的流程。

  4. 修复C#中player对象未赋值的错误
    原代码中C#的dynamic player未初始化,直接调用player.playVideo()会抛出异常。改为通过WebView2执行JS脚本控制播放:

    // RequestFullscreen方法改为async
    public async void RequestFullscreen()
    {
        this.BeginInvoke(new Action(async () =>
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.TopMost = true;
            
            await webView21.ExecuteScriptAsync("player.playVideo();");
        }));
    }
    

    同理,ExitFullscreen中的player.pauseVideo()也改为执行JS脚本:

    await webView21.ExecuteScriptAsync("player.pauseVideo();");
    
  5. 修正C#语法错误
    原代码中BeginInvoke的Lambda表达式语法错误,(() =需改为(() =>。


完整修正后的代码:

public partial class HowToViewSites : CMBaseDialog
{
    public HowToViewSites()
    {
        InitializeComponent();
        InitializeWebView2();
    }

    private async void InitializeWebView2()
    {
        await webView21.EnsureCoreWebView2Async(null);

        webView21.CoreWebView2.Settings.IsScriptEnabled = true;
        // 开启全屏权限
        webView21.CoreWebView2.Settings.IsFullscreenEnabled = true;

        webView21.CoreWebView2InitializationCompleted += WebView2_CoreWebView2InitializationCompleted;

        string htmlContent = @"
            <html>
            <head>
            <script src='https://www.youtube.com/iframe_api'></script>
            </head>
            <body>
            <iframe id='player' type='text/html' width='840' height='560'
                src='https://www.youtube.com/embed/QgMnE1No_6A?enablejsapi=1&fs=1'
                frameborder='0'></iframe>

            <script>
            let player;
            function onYouTubeIframeAPIReady() {
                player = new YT.Player('player', {
                    events: {
                        'onReady': onPlayerReady
                    }
                });
            }

            function onPlayerReady(event) {
                // 播放器就绪后的操作
            }

            document.addEventListener('fullscreenchange', function () {
                const isFullscreen = document.fullscreenElement !== null;
                window.chrome.webview.postMessage(isFullscreen ? 'enteredFullscreen' : 'exitedFullscreen');
            });
            </script>
            </body>
            </html>
        ";
        webView21.NavigateToString(htmlContent);

        webView21.CoreWebView2.Settings.IsWebMessageEnabled = true;
        webView21.WebMessageReceived += CoreWebView2_WebMessageReceived;
    }

    private void WebView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
    {
        if (!e.IsSuccess)
        {
            MessageBox.Show("WebView2初始化失败。");
        }
    }

    private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
    {
        string message = e.TryGetWebMessageAsString();
        if (message == "enteredFullscreen")
        {
            RequestFullscreen();
        }
        else if (message == "exitedFullscreen")
        {
            ExitFullscreen();
        }
    }

    public async void RequestFullscreen()
    {
        this.BeginInvoke(new Action(async () =>
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.TopMost = true;

            await webView21.ExecuteScriptAsync("player.playVideo();");
        }));
    }

    public async void ExitFullscreen()
    {
        this.BeginInvoke(new Action(async () =>
        {
            this.FormBorderStyle = FormBorderStyle.Sizable;
            this.WindowState = FormWindowState.Normal;
            this.TopMost = false;

            await webView21.ExecuteScriptAsync("player.pauseVideo();");
        }));
    }
}

内容的提问来源于stack exchange,提问作者RobbGarner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:17:02