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

为何WKWebView的requestMediaPlaybackState在视频未播放时返回Playing状态?

解决WKWebView提前返回WKMediaPlaybackStatePlaying的问题

问题根源

部分网站会预先加载视频并处于缓冲就绪状态,或是存在隐藏的自动播放背景视频,导致requestMediaPlaybackStateWithCompletionHandler误将这类状态判定为播放中。

可行解决方案

1. 注入JS监听真实播放事件

通过WKWebView注入JavaScript,直接监听页面视频元素的play、pause原生事件,将真实状态同步到原生层:

// 初始化WKWebView时注入监听脚本
WKUserScript *videoStateScript = [[WKUserScript alloc] initWithSource:@"(function() {
    // 监听全局play事件
    document.addEventListener('play', function(e) {
        if (e.target.tagName === 'VIDEO') {
            window.webkit.messageHandlers.videoState.postMessage('playing');
        }
    }, true);
    // 监听全局pause事件
    document.addEventListener('pause', function(e) {
        if (e.target.tagName === 'VIDEO') {
            window.webkit.messageHandlers.videoState.postMessage('paused');
        }
    }, true);
})()" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addUserScript:videoStateScript];
[config.userContentController addScriptMessageHandler:self name:@"videoState"];

WKWebView *website = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];

在WKScriptMessageHandler代理方法中接收状态:

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"videoState"]) {
        NSString *state = message.body;
        if ([state isEqualToString:@"playing"]) {
            // 处理真实播放逻辑
        } else if ([state isEqualToString:@"paused"]) {
            // 处理暂停逻辑
        }
    }
}

2. 增加多维度状态校验

不要仅依赖requestMediaPlaybackState的返回值,结合视频可见性、播放时长等维度二次校验:

if (@available(iOS 15.0, *)) {
    [website requestMediaPlaybackStateWithCompletionHandler:^(WKMediaPlaybackState result) {
        if (result == WKMediaPlaybackStatePlaying) {
            // 注入JS检查视频是否可见且有实际播放时长
            [website evaluateJavaScript:@"Array.from(document.querySelectorAll('video')).some(v => !v.paused && v.offsetParent !== null && v.currentTime > 0.5)" completionHandler:^(id _Nullable checkResult, NSError * _Nullable error) {
                if ([checkResult boolValue]) {
                    // 确认是用户触发的真实播放
                }
            }];
        }
    }];
}

3. 禁用网页自动播放

通过配置限制网页自动播放,减少误判场景:

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
if (@available(iOS 10.0, *)) {
    config.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:47:30