Multi-DRM flag refactoring

- Added flag --additional_protection_systems to specify multi-DRM
  options.
- Deprecated old multi-DRM flags: --generate_widevine_pssh
                                  --generate_playready_pssh
                                  --generate_common_pssh

Issue: #245.

Change-Id: If926bc9d481e941aa2269b6672bf2ba5411c3a50
This commit is contained in:
KongQun Yang 2018-08-06 16:12:19 -07:00
parent b4e827e01b
commit 0fe31423cb
18 changed files with 138 additions and 94 deletions

View File

@ -16,7 +16,7 @@
## [2.1.0] - 2018-05-22
### Added
- Support Widevine and Playready PSSH generation internally in packager (#245).
- Support Widevine and PlayReady PSSH generation internally in packager (#245).
Documentation will be updated later.
- Support removing segments outside of live window in DASH and HLS (#223).
- Support UTCTiming for DASH (#311).

View File

@ -14,19 +14,8 @@ General encryption options
Clear lead in seconds if encryption is enabled.
--generate_widevine_pssh
--additional_protection_systems
Generate a Widevine PSSH box. This option is always true
when using :doc:`/tutorials/widevine` key source.
--generate_common_pssh
Generate a v1 PSSH box for the common system ID that includes
the key IDs. See https://goo.gl/s8RIhr. This option is default to be
true when using :doc:`/tutorials/raw_key` source and no other pssh
flag is specified.
--generate_playready_pssh
Generate a PlayReady PSSH box. This option is always
true when using :doc:`/tutorials/playready` key source.
Generate additional protection systems in addition to the native protection
system provided by the key source. Supported protection systems include
Widevine, PlayReady, and CommonSystem (https://goo.gl/s8RIhr).

View File

@ -3,7 +3,9 @@ PlayReady encryption options
--enable_playready_encryption
Enable encryption with playready key.
Enable encryption with PlayReady key. This generates PlayReady protection
system. Additional protection systems can be generated with
--additional_protection_systems option.
--playready_server_url <url>
@ -13,14 +15,6 @@ PlayReady encryption options
Program identifier for packaging request.
--playready_key_id <hex>
PlayReady key id in hex.
--playready_key <hex>
PlayReady key in hex.
--ca_file <file path>
Absolute path to the certificate authority file for the server cert.

View File

@ -3,7 +3,11 @@ Raw key encryption options
--enable_raw_key_encryption
Enable encryption with raw key (keys provided in command line)).
Enable encryption with raw key (keys provided in command line)). This
generates `Common protection system <https://goo.gl/s8RIhr>`_ if neither
--pssh nor --additional_protection_systems is specified. Use --pssh to
provide custom protection systems or use --additional_protection_systems to
generate protection systems automatically.
--enable_raw_key_decryption
@ -31,5 +35,6 @@ Raw key encryption options
--pssh <hex string>
One or more concatenated PSSH boxes in hex string format. If not specified,
a `v1 common PSSH box <https://goo.gl/s8RIhr>`_ will be generated.
One or more concatenated PSSH boxes in hex string format. If neither this
flag nor --additional_protection_systems is specified, a
`v1 common PSSH box <https://goo.gl/s8RIhr>`_ will be generated.

View File

@ -5,7 +5,9 @@ Widevine encryption options
Enable encryption with Widevine key server. User should provide either
AES signing key (--aes_signing_key, --aes_signing_iv) or RSA signing key
(--rsa_signing_key_path).
(--rsa_signing_key_path). This generates Widevine protection system by
default. Additional protection systems can be generated with
--additional_protection_systems option.
--enable_widevine_decryption

View File

@ -51,7 +51,7 @@ Common PSSH (different keys for different streams)::
--keys label=AUDIO:key_id=f3c5e0361e6654b28f8049c778b23946:key=a4631a153a443df9eed0593043db7519,label=SD:key_id=abba271e8bcf552bbd2e86a434a9a5d9:key=69eaa802a6763af979e8d1940fb88392,label=HD:key_id=6d76f25cb17f5e16b8eaef6bbf582d8e:key=cb541084c99731aef4fff74500c12ead \
--mpd_output h264.mpd
Widevine PSSH (with pre-generated Widevine PSSH)::
Widevine (with pre-generated Widevine PSSH)::
$ packager \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4,drm_label=AUDIO \
@ -64,7 +64,7 @@ Widevine PSSH (with pre-generated Widevine PSSH)::
--pssh 000000317073736800000000EDEF8BA979D64ACEA3C827DCD51D21ED00000011220F7465737420636F6E74656E74206964 \
--mpd_output h264.mpd
Widevine PSSH and PlayReady PSSH::
Widevine and PlayReady::
$ packager \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4,drm_label=AUDIO \
@ -74,12 +74,13 @@ Widevine PSSH and PlayReady PSSH::
in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4,drm_label=HD \
--enable_raw_key_encryption \
--keys label=AUDIO:key_id=f3c5e0361e6654b28f8049c778b23946:key=a4631a153a443df9eed0593043db7519,label=SD:key_id=abba271e8bcf552bbd2e86a434a9a5d9:key=69eaa802a6763af979e8d1940fb88392,label=HD:key_id=6d76f25cb17f5e16b8eaef6bbf582d8e:key=cb541084c99731aef4fff74500c12ead \
--generate_widevine_pssh \
--generate_playready_pssh \
--additional_protection_systems Widevine,PlayReady \
--mpd_output h264.mpd
Note that user is responsible for setting up Widevine and PlayReady license server
and managing keys there.
.. note::
User is responsible for setting up Widevine and PlayReady license server and
managing keys there.
Refer to
`player setup <https://shaka-player-demo.appspot.com/docs/api/tutorial-drm-config.html>`_

View File

@ -72,7 +72,7 @@ The examples below uses the H264 streams created in :doc:`encoding`.
--aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \
--aes_signing_iv d58ce954203b7c9a9a9d467f59839249
* One example with multi-DRM support (Playready PSSH in addition to Widevine PSSH)::
* One example with multi-DRM support (PlayReady in addition to Widevine)::
$ packager \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4 \
@ -88,9 +88,12 @@ The examples below uses the H264 streams created in :doc:`encoding`.
--signer widevine_test \
--aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \
--aes_signing_iv d58ce954203b7c9a9a9d467f59839249 \
--generate_playready_pssh
--additional_protection_systems PlayReady
Note that user is responsible for setting up the PlayReady server and managing keys there.
.. note::
User is responsible for setting up the PlayReady server and managing keys
there.
Refer to
`player setup <https://shaka-player-demo.appspot.com/docs/api/tutorial-drm-config.html>`_

View File

@ -5,7 +5,7 @@
// https://developers.google.com/open-source/licenses/bsd
//
// Defines common command line flags for encryption and decryption, which
// applies to all key sources, i.e. fixed key, widevine and playready.
// applies to all key sources, i.e. raw key, Widevine and PlayReady.
#ifndef PACKAGER_APP_CRYPTO_FLAGS_H_
#define PACKAGER_APP_CRYPTO_FLAGS_H_

View File

@ -257,6 +257,32 @@ bool ParseAdCues(const std::string& ad_cues, std::vector<Cuepoint>* cuepoints) {
return true;
}
bool ParseProtectionSystems(
const std::string& protection_systems_str,
std::vector<EncryptionParams::ProtectionSystem>* protection_systems) {
protection_systems->clear();
std::map<std::string, EncryptionParams::ProtectionSystem> mapping = {
{"common", EncryptionParams::ProtectionSystem::kCommonSystem},
{"commonsystem", EncryptionParams::ProtectionSystem::kCommonSystem},
{"playready", EncryptionParams::ProtectionSystem::kPlayReady},
{"widevine", EncryptionParams::ProtectionSystem::kWidevine},
};
for (const std::string& protection_system :
base::SplitString(base::ToLowerASCII(protection_systems_str), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
auto iter = mapping.find(protection_system);
if (iter == mapping.end()) {
LOG(ERROR) << "Seeing unrecognized protection system: "
<< protection_system;
return false;
}
protection_systems->push_back(iter->second);
}
return true;
}
base::Optional<PackagingParams> GetPackagingParams() {
PackagingParams packaging_params;
@ -276,9 +302,6 @@ base::Optional<PackagingParams> GetPackagingParams() {
int num_key_providers = 0;
EncryptionParams& encryption_params = packaging_params.encryption_params;
encryption_params.generate_common_pssh = FLAGS_generate_common_pssh;
encryption_params.generate_playready_pssh = FLAGS_generate_playready_pssh;
encryption_params.generate_widevine_pssh = FLAGS_generate_widevine_pssh;
if (FLAGS_enable_widevine_encryption) {
encryption_params.key_provider = KeyProvider::kWidevine;
++num_key_providers;
@ -298,6 +321,12 @@ base::Optional<PackagingParams> GetPackagingParams() {
return base::nullopt;
}
if (!ParseProtectionSystems(
FLAGS_additional_protection_systems,
&encryption_params.additional_protection_systems)) {
return base::nullopt;
}
if (encryption_params.key_provider != KeyProvider::kNone) {
encryption_params.clear_lead_in_seconds = FLAGS_clear_lead;
if (!GetProtectionScheme(&encryption_params.protection_scheme))

View File

@ -44,18 +44,32 @@ std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
return request_signer;
}
int GetProtectionSystemsFlag(
const std::vector<EncryptionParams::ProtectionSystem>& protection_systems) {
int protection_systems_flags = 0;
for (const auto protection_system : protection_systems) {
switch (protection_system) {
case EncryptionParams::ProtectionSystem::kCommonSystem:
protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
break;
case EncryptionParams::ProtectionSystem::kPlayReady:
protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
break;
case EncryptionParams::ProtectionSystem::kWidevine:
protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
break;
}
}
return protection_systems_flags;
}
} // namespace
std::unique_ptr<KeySource> CreateEncryptionKeySource(
FourCC protection_scheme,
const EncryptionParams& encryption_params) {
int protection_systems_flags(0);
if (encryption_params.generate_common_pssh)
protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
if (encryption_params.generate_playready_pssh)
protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
if (encryption_params.generate_widevine_pssh)
protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
int protection_systems_flags =
GetProtectionSystemsFlag(encryption_params.additional_protection_systems);
std::unique_ptr<KeySource> encryption_key_source;
switch (encryption_params.key_provider) {
@ -105,7 +119,7 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
!playready.program_identifier.empty()) {
if (playready.key_server_url.empty() ||
playready.program_identifier.empty()) {
LOG(ERROR) << "Either playready key_server_url or program_identifier "
LOG(ERROR) << "Either PlayReady key_server_url or program_identifier "
"is not set.";
return nullptr;
}
@ -115,7 +129,7 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
!playready.client_cert_private_key_file.empty()) {
if (playready.client_cert_file.empty() ||
playready.client_cert_private_key_file.empty()) {
LOG(ERROR) << "Either playready client_cert_file or "
LOG(ERROR) << "Either PlayReady client_cert_file or "
"client_cert_private_key_file is not set.";
return nullptr;
}

View File

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// Defines command line flags for playready encryption.
// Defines command line flags for PlayReady encryption.
#include "packager/app/playready_key_encryption_flags.h"
@ -12,7 +12,7 @@
DEFINE_bool(enable_playready_encryption,
false,
"Enable encryption with playready key.");
"Enable encryption with PlayReady key.");
DEFINE_string(playready_server_url, "", "PlayReady packaging server url.");
DEFINE_string(program_identifier, "",
"Program identifier for packaging request.");

View File

@ -8,19 +8,9 @@
#include "packager/app/protection_system_flags.h"
DEFINE_bool(generate_common_pssh,
false,
"When specified, generate an additional v1 PSSH box for the common "
"system ID. See: https://goo.gl/s8RIhr."
"The flag is default to be true if --enable_raw_key_encryption "
"is set and no other pssh flags are specified.");
DEFINE_bool(generate_playready_pssh,
false,
"When specified, include a PlayReady PSSH box."
"A playready PSSH is always generated regardless of the value of "
"--generate_playready_pssh for --enable_playready_encryption.");
DEFINE_bool(generate_widevine_pssh,
false,
"When specified, include a Widevine PSSH box. "
"A widevine PSSH is always generated regardless of the value of "
"--generate_widevine_pssh for --enable_widevine_encryption.");
DEFINE_string(additional_protection_systems,
"",
"Generate additional protection systems in addition to the "
"native protection system provided by the key source. Supported "
"protection systems include Widevine, PlayReady, and "
"CommonSystem (https://goo.gl/s8RIhr).");

View File

@ -11,8 +11,6 @@
#include <gflags/gflags.h>
DECLARE_bool(generate_common_pssh);
DECLARE_bool(generate_playready_pssh);
DECLARE_bool(generate_widevine_pssh);
DECLARE_string(additional_protection_systems);
#endif // PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_

View File

@ -35,6 +35,18 @@ DEFINE_int32(
num_subsegments_per_sidx,
0,
"This flag is deprecated. Use --generate_sidx_in_media_segments instead.");
DEFINE_bool(
generate_widevine_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
DEFINE_bool(
generate_playready_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
DEFINE_bool(
generate_common_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
// The current gflags library does not provide a way to check whether a flag is
// set in command line. If a flag has a different value to its default value,
@ -70,6 +82,16 @@ bool InformRetiredDefaultInt32Flag(const char* flagname, int32_t value) {
return true;
}
bool InformRetiredPsshGenerationFlag(const char* flagname, bool value) {
if (value) {
fprintf(stderr,
"WARNING: %s is deprecated and ignored. Please switch to "
"--additional_protection_systems.\n",
flagname);
}
return true;
}
DEFINE_validator(profile, &InformRetiredStringFlag);
DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag);
DEFINE_validator(webm_subsample_encryption, &InformRetiredDefaultTrueFlag);
@ -79,3 +101,6 @@ DEFINE_validator(playready_key, &InformRetiredStringFlag);
DEFINE_validator(mp4_use_decoding_timestamp_in_timeline,
&InformRetiredDefaultFalseFlag);
DEFINE_validator(num_subsegments_per_sidx, &InformRetiredDefaultInt32Flag);
DEFINE_validator(generate_widevine_pssh, &InformRetiredPsshGenerationFlag);
DEFINE_validator(generate_playready_pssh, &InformRetiredPsshGenerationFlag);
DEFINE_validator(generate_common_pssh, &InformRetiredPsshGenerationFlag);

View File

@ -14,3 +14,6 @@ DECLARE_string(playready_key_id);
DECLARE_string(playready_key);
DECLARE_bool(mp4_use_decoding_timestamp_in_timeline);
DECLARE_int32(num_subsegments_per_sidx);
DECLARE_bool(generate_widevine_pssh);
DECLARE_bool(generate_playready_pssh);
DECLARE_bool(generate_common_pssh);

View File

@ -185,7 +185,7 @@ Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
}
status = SetKeyInformationFromServerResponse(acquire_license_response,
encryption_key.get());
// Playready does not specify different streams.
// PlayReady does not specify different streams.
const char kEmptyDrmLabel[] = "";
EncryptionKeyMap encryption_key_map;
encryption_key_map[kEmptyDrmLabel] = std::move(encryption_key);
@ -199,7 +199,7 @@ Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
Status PlayReadyKeySource::FetchKeys(EmeInitDataType init_data_type,
const std::vector<uint8_t>& init_data) {
// Do nothing for playready encryption/decryption.
// Do nothing for PlayReady encryption/decryption.
return Status::OK;
}

View File

@ -16,7 +16,7 @@
namespace shaka {
namespace media {
/// A key source that uses playready for encryption.
/// A key source that uses PlayReady for encryption.
class PlayReadyKeySource : public KeySource {
public:
/// Creates a new PlayReadyKeySource from the given packaging information.

View File

@ -64,12 +64,8 @@ struct WidevineEncryptionParams {
};
/// PlayReady encryption parameters.
/// Two different modes of playready key acquisition is supported:
/// (1) Fetch from a key server. `key_server_url` and `program_identifier` are
/// required. The presence of other parameters may be necessary depends
/// on server configuration.
/// (2) Provide the raw key directly. Both `key_id` and `key` are required.
/// We are planning to merge this mode with `RawKeyParams`.
/// `key_server_url` and `program_identifier` are required. The presence of
/// other parameters may be necessary depends on server configuration.
struct PlayReadyEncryptionParams {
/// PlayReady license / key server URL.
std::string key_server_url;
@ -119,19 +115,14 @@ struct EncryptionParams {
PlayReadyEncryptionParams playready;
RawKeyParams raw_key;
/// When it is true, generate a v1 PSSH box for the common
/// system ID. See: https://goo.gl/s8RIhr.
/// The flag is default to be true if --enable_raw_key_encryption
/// is set and no other pssh flags are specified.
bool generate_common_pssh = false;
/// When it is true, include a PlayReady PSSH box.
/// A playready PSSH is always generated regardless of the value of
/// --generate_playready_pssh for --enable_playready_encryption.
bool generate_playready_pssh = false;
/// When it is true, include a widevine PSSH box.
/// A widevine PSSH is always generated regardless of the value of
/// --generate_widevine_pssh for --enable_widevine_encryption.
bool generate_widevine_pssh = false;
/// Supported protection systems.
enum class ProtectionSystem {
kWidevine,
kPlayReady,
kCommonSystem,
};
/// Additional protection systems to be generated.
std::vector<ProtectionSystem> additional_protection_systems;
/// Clear lead duration in seconds.
double clear_lead_in_seconds = 0;