为何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
相关产品推荐
相关产品推荐

