Назад в Центр знаний
Платформа

Проверки возможностей DRM: система ключей, стойкость, вывод

Обзор проверки возможностей DRM для Widevine и EME: четыре контрольные точки по порядку, какое значение фиксировать на каждой и где заканчиваются доказательства браузера.

BotBrowser Team

Документация

Нужна структурированная документация по теме Платформа?

Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.

Зашифрованные медиа дают сбой по четырём разным причинам, и команда, которая спрашивает только о том, работает ли DRM, не может их различить. Этот обзор упорядочивает четыре контрольные точки проверки возможностей DRM и связывает каждую с материалом, который разбирает её подробно: согласование модуля, согласованная стойкость, защищённый вывод и решение по лицензии.

BotBrowser может поддерживать согласованность объявленного профиля и его медиаполитики на уровне контекста в авторизованном сценарии, когда это позволяют сборка и права по лицензии. Он не может создать модуль расшифровки контента, отменить решение провайдера по аккаунту или обещать, что конкретный фильм будет воспроизводиться на любом хосте.

Четыре контрольные точки DRM по порядку: доступ к системе ключей, согласованная стойкость, защищённый вывод и решение по лицензии, с указанием значения для записи

Кратко

  • Задавайте по одному вопросу на каждую контрольную точку. Отказ на шаге доступа и отказ на шаге лицензии это разные сбои с разными владельцами, и если сообщить о любом из них как «DRM не работает», обращение попадёт не к той команде.
  • Фиксируйте принятую строку стойкости (SW_SECURE_DECODE, HW_SECURE_ALL), а не превращайте её в ответ да или нет.
  • Считайте headless и headed режимами представления. Виртуальный дисплей не означает более низкий уровень безопасности, а физический монитор не доказывает наличие аппаратно защищённого пути.
  • Храните код статуса провайдера в отдельном поле. Это решение политики об аккаунте и фильме, а не свойство браузера.

Содержание

Четыре контрольные точки за одним вопросом

Четыре контрольные точки идут последовательно, и каждая отвечает на свой вопрос об одной и той же сессии. Их смешение это самая частая причина, по которой расследование DRM заходит в тупик, потому что поиск причины начинается не в том слое и никогда не доходит до слоя, где произошёл отказ.

Первая контрольная точка отвечает на вопрос, будет ли браузер вообще согласовывать систему ключей. Вторая: какой уровень стойкости он принимает. Третья: разрешено ли пути вывода переносить защищённые кадры. Четвёртая: выдаёт ли сервер лицензий ключ для этого аккаунта, региона и фильма.

Порядок важен для диагностики, а не только для аккуратности. Отказ на первой контрольной точке останавливает цепочку, поэтому всё последующее не проверялось. Успех на первой контрольной точке и отказ на четвёртой доказывают, что сторона браузера согласовала всё успешно, а решение принял провайдер. Эти два результата указывают на разных владельцев, и обращение в поддержку с формулировкой «DRM не работает» не позволяет их различить.

Контрольная точкаВызов браузера или событиеЗначение для записи
1 ДоступrequestMediaKeySystemAccess()supported или NotSupportedError
2 СтойкостьgetConfiguration() после запросапринятая строка стойкости
3 Выводkeystatuseschange на сессииusable, output-restricted, expired
4 Лицензияответ HTTP на сообщение лицензиикод статуса и категория ошибки провайдера

Каждая строка это отдельный эксперимент со своей категорией отказа. Проверяющий, который держит их раздельно, может назвать первую сломанную строку и передать её владельцу этой части, вместо того чтобы заново открывать всю конфигурацию.

У каждой строки есть также предел, который стоит указать рядом со значением. Успех на первой контрольной точке доказывает, что браузер согласует систему ключей; он не доказывает, что ключ можно расшифровать или что фильм воспроизведётся. Успех на второй контрольной точке доказывает, что модуль принял уровень; он не доказывает, что путь дисплея может переносить защищённые кадры. Статус usable на третьей контрольной точке доказывает, что ключи были выданы сессии; он не доказывает, что провайдер авторизовал аккаунт. HTTP 200 на четвёртой контрольной точке доказывает, что пришёл один ответ с лицензией; он не доказывает, что следующий запрос, другой фильм или другой регион увенчаются успехом. Именно запись этих пределов в протокол не даёт цепочке из четырёх успехов читаться как гарантия воспроизведения.

Сначала назовите границу модуля

Модуль это вход, от которого зависит всё остальное, и при автоматизированном запуске его часто нет, причём без единой ошибки, где он упомянут. Браузер без модуля отклоняет любую конфигурацию для системы ключей, поэтому проверка сообщает об отказе возможности, который выглядит как проблема конфигурации, а на деле является проблемой поставки.

Два факта о модуле стоит явно записать в протокол проверки. Во-первых, двоичный файл важен раньше аргументов: сборка Chromium с открытым исходным кодом обычно не содержит модуль Widevine, а сборка Google Chrome содержит. Набор тестов, который запускает встроенную сборку Chromium, скорее всего сообщит об отсутствии поддержки, какие бы аргументы он ни передавал, и исправление состоит в запуске сборки, которая вообще способна нести модуль.

Во-вторых, собственные значения по умолчанию фреймворка автоматизации могут отключать компонент, который делает модуль доступным. Запуск Playwright по умолчанию включает --disable-component-update, что разумно для раннера, которому не нужен фоновый сетевой трафик, и это же означает, что только что созданный профиль в такой среде сообщил об отсутствии поддержки Widevine в измерении, опубликованном в этом кластере. Та же проверка без единственного аргумента сообщила SW_SECURE_CRYPTO и SW_SECURE_DECODE как поддерживаемые на той же машине, в headless и в headed режиме. Измерение проводилось на установленной сборке Google Chrome, а не на встроенном Chromium, поэтому оно ничего не говорит о сборке, которая вообще не содержит модуль.

Это измерение стоит читать как метод, а не как универсальное правило. Оно изолирует один аргумент, не меняет ничего другого и сравнивает одну и ту же проверку до и после. Компонентная система Chrome принадлежит самому Chrome, поэтому другая версия или другая операционная система может вести себя иначе, и воспроизводимой здесь является именно процедура сравнения, а не конкретный результат.

Для этого обзора следствие состоит в правиле размещения, а не в факте о Chrome: отсутствующий модуль никогда не доходит до первой контрольной точки, поэтому его нужно записывать в поле сборки заголовка, а не как отказавшую строку. Таблица, которая показывает красный NotSupportedError в первой строке против встроенной сборки Chromium, описывает заголовок, и читатель, который никогда не видит заголовок, прочтёт это как проблему модуля или провайдера.

const base = { executablePath: '/opt/google/chrome/chrome', headless: true };
await chromium.launch(base); // значения по умолчанию фреймворка, включая --disable-component-update
await chromium.launch({ ...base, ignoreDefaultArgs: ['--disable-component-update'] }); // единственное изменение

Записывайте рядом с результатом, был профиль новым или постоянным. Временный профиль повторяет регистрацию первого запуска при каждом старте, а результат с долгоживущего настольного профиля не является доказательством для контейнера CI, который создаёт новый каталог на каждую задачу. Сравнивайте сравнимое.

Внутристраничная половина проверки достаточно коротка, чтобы держать её рядом с записью. Запускайте её через page.evaluate после каждого запуска выше; она запрашивает одну конфигурацию, печатает, какие системы ключей разрешаются, и никогда не пытается воспроизводить поток:

const config = [
  {
    initDataTypes: ['cenc'],
    videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1.42E01E"', robustness: 'SW_SECURE_DECODE' }],
  },
];
for (const keySystem of ['com.widevine.alpha', 'org.w3.clearkey']) {
  try {
    const access = await navigator.requestMediaKeySystemAccess(keySystem, config);
    const c = access.getConfiguration();
    console.log(keySystem, 'supported', c.videoCapabilities[0].robustness, c.persistentState);
  } catch (error) {
    console.log(keySystem, error.name);
  }
}

Clear Key в этом цикле служит контролем, а не признаком платформы. Спецификация его определяет, поэтому каждый соответствующий стандарту браузер на него отвечает, и его задача здесь отделить проблему страницы или сети от проблемы DRM. Если Clear Key разрешается нормально, а платформенная система ключей отклоняет любую конфигурацию, искать нужно в слое CDM, а не на странице.

Читайте стойкость как диапазон, а не как приговор

Как только система ключей согласована, браузер и модуль договариваются об уровне стойкости. Эти строки это словарь, которым провайдер решает, что он будет отдавать: SW_SECURE_CRYPTO и SW_SECURE_DECODE оставляют криптографическую работу или декодирование в программном слое, а HW_SECURE_ALL требует доверенного аппаратного пути. Widevine называет чисто программный случай уровнем 3, а более высокие уровни зависят от аппаратуры, которой на хосте может не быть.

Отклонённый аппаратный уровень не является дефектом настройки. Во многих настольных и виртуальных средах нет аппаратно защищённого пути, и провайдер, который отдаёт обычный контент на программных уровнях, там работает. Поэтому полезная запись содержит строку, которая была фактически принята, вместе с запрошенной конфигурацией, потому что именно эта пара нужна следующему проверяющему, чтобы увидеть, что ответ изменился.

Две привычки делают эту строку надёжной. Повторяйте одну и ту же конфигурацию от запуска к запуску, чтобы разница в выводе была настоящей разницей, а не другим вопросом. И читайте возвращённый объект конфигурации, а не предполагайте, что запрос удовлетворён в точности как записан: Фингерпринтинг DRM перечисляет поля, которые несёт этот объект, и что каждое из них раскрывает о платформе, так что этот обзор их не повторяет.

Одна успешная конфигурация H.264 это одна ячейка матрицы, а не вся матрица, и Фингерпринтинг DRM объясняет, как читать эту матрицу. Здесь важно более узкое: записывать, какую ячейку вы запросили и какая ответила, потому что провайдер, который отдаёт более низкое разрешение на более низком уровне, принимает решение политики, которое видно здесь только как принятый уровень.

Отделяйте защиту вывода от режима дисплея

Воспроизведение может начаться, а затем остановиться, когда путь дисплея не соответствует требованию защищённого вывода. Сессия сообщает это состояние через keystatuseschange, часто как output-restricted, и приложение должно показать резервный вариант, а не непрозрачную ошибку. Эта контрольная точка относится к пути дисплея и не зависит от того, была ли согласована система ключей.

Частая ошибка состоит в том, чтобы свести эту строку к противопоставлению headless и headed. Headless это режим представления, а не уровень безопасности. Виртуальный дисплей может выполнить или не выполнить требование вывода по причинам, не связанным со сменой режима, а headed запуск на физическом мониторе не доказывает, что виртуальный дисплей потерпит неудачу. Выполняйте сравнение с тем же профилем, тем же кодеком и той же запрошенной стойкостью, и пусть режим дисплея будет единственной независимой переменной.

Этот обзор добавляет порядок чтения для изменения в третьей строке: сначала проверяйте поле режима дисплея в заголовке, затем поле кодека, затем запрошенную стойкость. Сдвиг в третьей строке, который совпадает с изменением режима дисплея, не требует дальнейшего расследования; сдвиг при неизменном режиме дисплея указывает на тестовый набор вывода.

Честный способ это записывать: фиксировать состояние вывода и резервный вариант, который показало приложение, и ничего о модели монитора или идентичности GPU. Браузер может сообщить, что произошло ограничение вывода. Он не может сообщить, что человек смотрит на конкретный экран, и вывод такого рода превращает запись о возможностях в утверждение, которого измерение не поддерживает.

Имена состояний, которые стоит записывать, берутся из карты статусов медиаключей, а не из собственных меток плеера. Сессия сообщает usable, когда ключ доступен, output-restricted, когда путь дисплея блокирует защищённые кадры, expired, когда окно лицензии закрылось, и released после очистки. Сопоставьте видимое пользователю сообщение приложения с одним из этих имён в записи, чтобы следующий проверяющий сравнивал статусы, а не переводил текст интерфейса с четырёх языков.

Негативный путь относится к набору тестовых случаев. Границы Widevine в headless перечисляет негативные случаи, которые набор должен проверять намеренно, и объясняет, почему проверенный резервный вариант ценнее задокументированного. На этой контрольной точке конкретный случай, который стоит добавить, это ограничение вывода, потому что это единственный отказ, который проявляется после успешного согласования.

Решите, кому принадлежит ответ по лицензии

Последняя контрольная точка это единственная, где браузер сообщает сообщение, а не принимает решение. Страница передаёт провайдеру непрозрачный запрос лицензии, провайдер отвечает, и сессия либо становится пригодной к использованию, либо нет. Ошибка HTTP на этом этапе может означать аккаунт, регион, лимит одновременных сессий, истёкшее право или сбой сервиса, и ничто из этого не является фактом совместимости браузера.

Разделение доказательств браузера и доказательств провайдера это то, что делает передачу задачи рабочей, а вклад этого хаба в разделении ответственности, а не в механике полей: первая строка принадлежит владельцу двоичного файла и запуска, четвёртая строка принадлежит владельцу провайдера. Границы Widevine в headless излагает, какое поле хранит какой результат; этот обзор добавляет, что обращение, в котором названо только «DRM не работает», не даёт принимающей команде отличить этих двух владельцев, поэтому строка должна ехать вместе с обращением.

Хранение следует тому же разделению. Сохраняйте идентификатор сборки, дату проверки, метку профиля, запрошенную конфигурацию, имя результата, статус и отметку времени. Удаляйте cookie, идентификаторы аккаунта, сообщения лицензии, токены доступа и исходный материал ключей. Запись, которая хранит только категории, всё равно позволяет сравнивать релизы, и именно ради этого её и стоит держать.

Одного статуса HTTP часто слишком мало, чтобы направить обращение. 403 может означать истёкшее право, несовпадение региона, уже достигнутый лимит одновременных сессий на том же аккаунте или истечение подписанного URL, и провайдер обычно возвращает рядом свой код или сообщение об ошибке. Записывайте этот код как категорию, а полное сообщение держите вне общего артефакта, потому что сообщения лицензии могут содержать идентификаторы, принадлежащие аккаунту, а не релизу. 429 и 503 от одного провайдера требуют одинаковой обработки и разных владельцев: первый говорит, что аккаунт достиг лимита, второй говорит, что сервис недоступен, и ни то, ни другое не исправляется сменой профиля.

Когда результат меняется, меняйте один объявленный вход за запуск и держите остальные фиксированными. Границы Widevine в headless уже излагает рекомендуемый порядок сравнения для четырёх строк; этот обзор добавляет только правило, что заголовок должен оставаться одинаковым в обоих запусках, чтобы сдвинувшуюся строку можно было прочитать как сдвинутый вход.

Записывайте по одной таблице на релиз

Артефакт, который переживает цикл релиза, это небольшая таблица со строкой на каждую контрольную точку, лежащая рядом с заголовком запуска, форма которого не меняется между релизами. Заголовок нужно зафиксировать один раз и переиспользовать, потому что заголовок, который меняет форму между релизами, делает две таблицы несравнимыми. Восемь полей покрывают случаи, которые сдвигают результат возможностей: продукт и полная строка сборки браузера, библиотека автоматизации и версия, операционная система и версия, режим дисплея, строка кодека под тестом, был ли профиль создан заново, имя системы ключей и запрошенная стойкость. Границы Widevine в headless перечисляет первые шесть для своей матрицы; последние два добавляет проверка возможностей.

Повторяйте таблицу после обновления браузера или автоматизации, после изменения схемы профиля и после смены раннера или дисплея, и держите предыдущую таблицу рядом с новой. Первая изменившаяся строка называет слой для расследования, поэтому заголовок должен оставаться фиксированным: строка, которая сдвинулась из-за изменения заголовка, ничего не говорит о браузере.

Разобранный пример делает сравнение конкретным. Пусть релиз A фиксирует supported на первой контрольной точке, SW_SECURE_DECODE на второй, usable на третьей и HTTP 200 на четвёртой с тестовым ресурсом. Релиз B фиксирует supported, SW_SECURE_DECODE, затем output-restricted на третьей, а строка лицензии не выполняется, потому что сессия непригодна. Сдвинулась только одна строка, и она сдвинулась на пути дисплея, поэтому следующее действие это сравнить настройку дисплея раннера, а не заново открывать вопрос о модуле или связываться с провайдером.

Обратный случай так же ясен. Если первая контрольная точка меняется с supported на NotSupportedError, а заголовок показывает ту же сборку и тот же жизненный цикл профиля, разница пришла от аргумента запуска или от обновления компонента, которое не выполнилось. Сравнение списка аргументов с обычным запуском отвечает на это за один шаг. Если же заголовок показывает другую сборку, список аргументов не первое, что нужно проверять.

Кластер даёт каждой контрольной точке подробное рассмотрение. Договор настройки для установки модуля и его сопоставления с профилем находится в Настройке Widevine DRM. Взгляд со стороны фингерпринтинга, который объясняет, какие части поверхности EME страница может прочитать, ничего не воспроизводя, находится в Фингерпринтинге DRM. Матрица, которая разделяет четыре границы по одному тестовому случаю на строку, находится в Границах Widevine в headless. Измерение, которое изолирует аргумент запуска, ответственный за отсутствующий модуль, находится в Доступности Widevine CDM в автоматизированных браузерах.

Читайте их в этом порядке, когда проверка начинается с нуля: настройка определяет входы, фингерпринтинг объясняет, что наблюдаемо, матрица границ превращает наблюдение в строки, а измерение доступности объясняет самый частый нулевой результат. Читайте только тот материал, который совпадает с отказавшей контрольной точкой, когда проверка уже идёт, потому что остальные ответят на вопросы, которых никто не задавал.

Практический итог

Проверка возможностей DRM это четыре вопроса, заданных по порядку, у каждого своё значение и свой владелец. Записывайте результат согласования, принятую строку стойкости, состояние вывода и статус провайдера как отдельные поля, затем сравнивайте релизы, ища первую изменившуюся строку. Пройденная строка доказывает, что один договор соблюдён; она не доказывает, что фильм воспроизводится, и назвать это ограничение частью результата.

Публичные источники

Что читать дальше

Начните с настройки Widevine DRM для входов, затем перейдите по ссылке кластера, которая совпадает с отказавшей контрольной точкой.

#Drm#Widevine#Eme#Media#Release Review

Переведите BotBrowser из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.