Shaka Packager SDK
packager_util.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/packager_util.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
12 #include "packager/file/file.h"
13 #include "packager/media/base/media_handler.h"
14 #include "packager/media/base/muxer_options.h"
15 #include "packager/media/base/playready_key_source.h"
16 #include "packager/media/base/raw_key_source.h"
17 #include "packager/media/base/request_signer.h"
18 #include "packager/media/base/widevine_key_source.h"
19 #include "packager/mpd/base/mpd_options.h"
20 #include "packager/status.h"
21 
22 namespace shaka {
23 namespace media {
24 namespace {
25 
26 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
27  std::unique_ptr<RequestSigner> request_signer;
28  switch (signer.signing_key_type) {
29  case WidevineSigner::SigningKeyType::kAes:
30  request_signer.reset(AesRequestSigner::CreateSigner(
31  signer.signer_name, signer.aes.key, signer.aes.iv));
32  break;
33  case WidevineSigner::SigningKeyType::kRsa:
34  request_signer.reset(
35  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
36  break;
37  case WidevineSigner::SigningKeyType::kNone:
38  break;
39  }
40  if (!request_signer)
41  LOG(ERROR) << "Failed to create the signer object.";
42  return request_signer;
43 }
44 
45 } // namespace
46 
47 std::unique_ptr<KeySource> CreateEncryptionKeySource(
48  FourCC protection_scheme,
49  const EncryptionParams& encryption_params) {
50  std::unique_ptr<KeySource> encryption_key_source;
51  switch (encryption_params.key_provider) {
52  case KeyProvider::kWidevine: {
53  const WidevineEncryptionParams& widevine = encryption_params.widevine;
54  if (widevine.key_server_url.empty()) {
55  LOG(ERROR) << "'key_server_url' should not be empty.";
56  return nullptr;
57  }
58  if (widevine.content_id.empty()) {
59  LOG(ERROR) << "'content_id' should not be empty.";
60  return nullptr;
61  }
62  std::unique_ptr<WidevineKeySource> widevine_key_source(
63  new WidevineKeySource(widevine.key_server_url,
64  encryption_params.protection_systems,
65  protection_scheme));
66  if (!widevine.signer.signer_name.empty()) {
67  std::unique_ptr<RequestSigner> request_signer(
68  CreateSigner(widevine.signer));
69  if (!request_signer)
70  return nullptr;
71  widevine_key_source->set_signer(std::move(request_signer));
72  }
73  widevine_key_source->set_group_id(widevine.group_id);
74  widevine_key_source->set_enable_entitlement_license(
75  widevine.enable_entitlement_license);
76 
77  Status status =
78  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
79  if (!status.ok()) {
80  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
81  << status.ToString();
82  return nullptr;
83  }
84  encryption_key_source = std::move(widevine_key_source);
85  break;
86  }
87  case KeyProvider::kRawKey: {
88  encryption_key_source = RawKeySource::Create(encryption_params.raw_key);
89  break;
90  }
91  case KeyProvider::kPlayReady: {
92  const PlayReadyEncryptionParams& playready = encryption_params.playready;
93  if (!playready.key_server_url.empty() ||
94  !playready.program_identifier.empty()) {
95  if (playready.key_server_url.empty() ||
96  playready.program_identifier.empty()) {
97  LOG(ERROR) << "Either PlayReady key_server_url or program_identifier "
98  "is not set.";
99  return nullptr;
100  }
101  std::unique_ptr<PlayReadyKeySource> playready_key_source;
102  // private_key_password is allowed to be empty for unencrypted key.
103  playready_key_source.reset(new PlayReadyKeySource(
104  playready.key_server_url, encryption_params.protection_systems));
105  Status status = playready_key_source->FetchKeysWithProgramIdentifier(
106  playready.program_identifier);
107  if (!status.ok()) {
108  LOG(ERROR) << "PlayReady encryption key source failed to fetch keys: "
109  << status.ToString();
110  return nullptr;
111  }
112  encryption_key_source = std::move(playready_key_source);
113  } else {
114  LOG(ERROR) << "Error creating PlayReady key source.";
115  return nullptr;
116  }
117  break;
118  }
119  default:
120  break;
121  }
122  return encryption_key_source;
123 }
124 
125 std::unique_ptr<KeySource> CreateDecryptionKeySource(
126  const DecryptionParams& decryption_params) {
127  std::unique_ptr<KeySource> decryption_key_source;
128  switch (decryption_params.key_provider) {
129  case KeyProvider::kWidevine: {
130  const WidevineDecryptionParams& widevine = decryption_params.widevine;
131  if (widevine.key_server_url.empty()) {
132  LOG(ERROR) << "'key_server_url' should not be empty.";
133  return std::unique_ptr<KeySource>();
134  }
135  std::unique_ptr<WidevineKeySource> widevine_key_source(
136  new WidevineKeySource(
137  widevine.key_server_url,
138  ProtectionSystem::kWidevine /* value does not matter here */,
139  FOURCC_NULL /* value does not matter here */));
140  if (!widevine.signer.signer_name.empty()) {
141  std::unique_ptr<RequestSigner> request_signer(
142  CreateSigner(widevine.signer));
143  if (!request_signer)
144  return std::unique_ptr<KeySource>();
145  widevine_key_source->set_signer(std::move(request_signer));
146  }
147 
148  decryption_key_source = std::move(widevine_key_source);
149  break;
150  }
151  case KeyProvider::kRawKey: {
152  decryption_key_source = RawKeySource::Create(decryption_params.raw_key);
153  break;
154  }
155  default:
156  break;
157  }
158  return decryption_key_source;
159 }
160 
161 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
162  MpdOptions mpd_options;
163  mpd_options.dash_profile =
164  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
165  mpd_options.mpd_type =
166  (on_demand_profile || mpd_params.generate_static_live_mpd)
167  ? MpdType::kStatic
168  : MpdType::kDynamic;
169  mpd_options.mpd_params = mpd_params;
170  return mpd_options;
171 }
172 
173 } // namespace media
174 } // namespace shaka
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key)
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
All the methods that are virtual are virtual for mocking.