DRM Widevine L1 在 Android Webview 的支持情况

最近在开发中遇到了 Android TV 无法通过 L1 的检测。代码检测如下:

async function checkWidevineL1Support() {
    const keySystem = 'com.widevine.alpha';

    // Robustness levels to test, from most secure (L1 equivalent) to least secure (L3 equivalent)
    const robustnessLevels = [
        'HW_SECURE_DECODE', // Likely L1: decryption and decoding in TEE
        'HW_SECURE_CRYPTO', // Likely L2: decryption in TEE, decoding in software
        'SW_SECURE_DECODE', // Likely L3: software-based, with decode in software
        'SW_SECURE_CRYPTO'  // Likely L3: software-based, with crypto in software
    ];

    for (const level of robustnessLevels) {
        const config = [{
            initDataTypes: ['cenc'], // Common Encryption
            videoCapabilities: [{
                contentType: 'video/mp4; codecs="avc1.42E01E"', // Example codec
                // You might need to add other properties like robustness
                robustness: level
            }],
            audioCapabilities: [{
                contentType: 'audio/mp4; codecs="mp4a.40.2"', // Example codec
                robustness: level // Audio often doesn't need L1
            }]
            // persistentState: 'required', // Only if you need offline playback
            // distinctiveIdentifier: 'optional' // Optional, not usually required for L1 check
        }];

        try {
            console.log(`Attempting to request Widevine with robustness: ${level}`);
            const keySystemAccess = await navigator.requestMediaKeySystemAccess(keySystem, config);

            // If we reach here, this robustness level is supported.
            // Check the exact configuration that was negotiated.
            const negotiatedConfig = keySystemAccess.getConfiguration();
            console.log(`Widevine supported with negotiated robustness:`, negotiatedConfig);

            // If the highest level (HW_SECURE_DECODE) was successfully negotiated,
            // or a sufficiently high hardware-backed level, you can infer L1 support.
            if (negotiatedConfig.videoCapabilities && negotiatedConfig.videoCapabilities[0].robustness === 'HW_SECURE_DECODE') {
                console.log('🎉 Widevine L1 (or equivalent hardware-backed decoding) is likely supported!');
                return 'L1 Supported';
            } else if (negotiatedConfig.videoCapabilities && negotiatedConfig.videoCapabilities[0].robustness === 'HW_SECURE_CRYPTO') {
                 console.log('💡 Widevine L2 (hardware-backed crypto) is likely supported.');
                 return 'L2 Supported';
            } else {
                console.log(`⚠️ Widevine L3 (software-based) is likely supported with robustness: ${negotiatedConfig.videoCapabilities ? negotiatedConfig.videoCapabilities[0].robustness : 'unknown'}.`);
                return 'L3 Supported';
            }

        } catch (error) {
            console.warn(`Widevine with robustness ${level} NOT supported:`, error.message);
        }
    }

    console.log('❌ Widevine is not supported with any tested robustness level.');
    return 'Not Supported';
}

// Call the function to check
checkWidevineL1Support().then(result => {
    console.log("Overall Widevine L1 check result:", result);
});

自己第一时间怀疑的是,Android TV 作为盒子,难道天生不就应该有更好的视频播放支持么?

目前可以确认的是桌面端,Chrome 确实不支持 L1, 只支持到 L3 级别: https://www.vdocipher.com/blog/widevine-drm-hollywood-video/#:~:text=system in use.-,Widevine DRM Compatibility,higher security features than L3.

然而原生确实是支持 L1,Android TV 很早就开始支持了 Widevine L1 的播放。 这里有个疑问点其实就是 WebView 的播放和原生播放是不是存在一些限制?

WebView VS Chrome in Android

Android 开发中的 WebView 组件 和 Chrome 浏览器 都是基于 Chromium 开源项目,因此它们共享相同的渲染引擎(Blink)。这意味着在大多数情况下,同一个网页在 WebView 和 Chrome 中会有相似的渲染效果。然而,它们在功能、用途和独立性方面存在显著区别。

特性 Android WebView 组件 Chrome 浏览器
类型 Android 应用内的 UI 组件 独立的 完整浏览器应用
UI 内置的浏览器UI(需开发者实现) 完整的浏览器UI和功能
用途 在应用内嵌入显示网页内容 独立的网页浏览体验
控制 通过 API 由应用开发者编程控制 用户直接交互和控制
数据 与Chrome共享数据 可以 与Google账号同步数据
更新 通常随系统或“Android System WebView”应用更新 独立通过应用商店更新,更频繁
功能 功能相对 受限 功能 齐全,提供高级浏览体验

在 DRM 上差异:

Chrome 浏览器 在 DRM 支持方面通常更全面、稳定且更新及时,因为它是一个旨在提供完整浏览体验的独立应用。它默认启用了对 Widevine DRM 的支持,并且会随着浏览器更新而不断提升兼容性。

Android WebView 组件虽然基于相同的 Chromium 内核,但作为嵌入式组件,它需要应用开发者进行额外的配置和权限处理才能启用 DRM 支持。在某些高级 DRM 功能(如持久性许可)方面,或者对于对播放环境有严格要求的服务,WebView 可能存在限制或兼容性问题。

所以这里会有两个问题:

  • 我们是否做好相应的 WebView 配置
  • WebView 支持 L1 这块限制是不是本身就一直存在

我们尝试做过一些配置的更改,但是都没能达到效果。目前我们的数据采集给出的结论是,目前都不支持 L1。支持到 L3 级别。所以我更倾向于这块被限制了。

也欢迎评论分享有没有别的解法?