DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
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/fixed_key_source.h"
14 #include "packager/media/base/media_handler.h"
15 #include "packager/media/base/muxer_options.h"
16 #include "packager/media/base/playready_key_source.h"
17 #include "packager/media/base/request_signer.h"
18 #include "packager/media/base/widevine_key_source.h"
19 #include "packager/media/chunking/chunking_handler.h"
20 #include "packager/media/crypto/encryption_handler.h"
21 #include "packager/mpd/base/mpd_options.h"
22 #include "packager/packager.h"
23 #include "packager/status.h"
24 
25 namespace shaka {
26 namespace media {
27 namespace {
28 
29 } // namespace
30 
31 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
32  std::unique_ptr<RequestSigner> request_signer;
33  switch (signer.signing_key_type) {
34  case WidevineSigner::SigningKeyType::kAes:
35  request_signer.reset(AesRequestSigner::CreateSigner(
36  signer.signer_name, signer.aes.key, signer.aes.iv));
37  break;
38  case WidevineSigner::SigningKeyType::kRsa:
39  request_signer.reset(
40  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
41  break;
42  case WidevineSigner::SigningKeyType::kNone:
43  break;
44  }
45  if (!request_signer)
46  LOG(ERROR) << "Failed to create the signer object.";
47  return request_signer;
48 }
49 
50 std::unique_ptr<KeySource> CreateEncryptionKeySource(
51  FourCC protection_scheme,
52  const EncryptionParams& encryption_params) {
53  std::unique_ptr<KeySource> encryption_key_source;
54  switch (encryption_params.key_provider) {
55  case KeyProvider::kWidevine: {
56  const WidevineEncryptionParams& widevine = encryption_params.widevine;
57  if (widevine.key_server_url.empty()) {
58  LOG(ERROR) << "'key_server_url' should not be empty.";
59  return std::unique_ptr<KeySource>();
60  }
61  if (widevine.content_id.empty()) {
62  LOG(ERROR) << "'content_id' should not be empty.";
63  return std::unique_ptr<KeySource>();
64  }
65  std::unique_ptr<WidevineKeySource> widevine_key_source(
66  new WidevineKeySource(widevine.key_server_url,
67  widevine.include_common_pssh));
68  widevine_key_source->set_protection_scheme(protection_scheme);
69  if (!widevine.signer.signer_name.empty()) {
70  std::unique_ptr<RequestSigner> request_signer(
71  CreateSigner(widevine.signer));
72  if (!request_signer)
73  return std::unique_ptr<KeySource>();
74  widevine_key_source->set_signer(std::move(request_signer));
75  }
76  widevine_key_source->set_group_id(widevine.group_id);
77 
78  Status status =
79  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
80  if (!status.ok()) {
81  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
82  << status.ToString();
83  return std::unique_ptr<KeySource>();
84  }
85  encryption_key_source = std::move(widevine_key_source);
86  break;
87  }
88  case KeyProvider::kRawKey: {
89  const RawKeyEncryptionParams& raw_key = encryption_params.raw_key;
90  const std::string kDefaultTrackType;
91  // TODO(kqyang): Refactor FixedKeySource.
92  encryption_key_source = FixedKeySource::Create(
93  raw_key.key_map.find("")->second.key_id,
94  raw_key.key_map.find("")->second.key, raw_key.pssh, raw_key.iv);
95  break;
96  }
97  case KeyProvider::kPlayready: {
98  const PlayreadyEncryptionParams& playready = encryption_params.playready;
99  if (!playready.key_id.empty() && !playready.key.empty()) {
100  encryption_key_source = PlayReadyKeySource::CreateFromKeyAndKeyId(
101  playready.key_id, playready.key);
102  } else if (!playready.key_server_url.empty() &&
103  !playready.program_identifier.empty()) {
104  std::unique_ptr<PlayReadyKeySource> playready_key_source;
105  if (!playready.client_cert_file.empty() &&
106  !playready.client_cert_private_key_file.empty() &&
107  !playready.client_cert_private_key_password.empty()) {
108  playready_key_source.reset(new PlayReadyKeySource(
109  playready.key_server_url, playready.client_cert_file,
110  playready.client_cert_private_key_file,
111  playready.client_cert_private_key_password));
112  } else {
113  playready_key_source.reset(
114  new PlayReadyKeySource(playready.key_server_url));
115  }
116  if (!playready.ca_file.empty()) {
117  playready_key_source->SetCaFile(playready.ca_file);
118  }
119  playready_key_source->FetchKeysWithProgramIdentifier(
120  playready.program_identifier);
121  encryption_key_source = std::move(playready_key_source);
122  } else {
123  LOG(ERROR) << "Error creating PlayReady key source.";
124  return std::unique_ptr<KeySource>();
125  }
126  break;
127  }
128  case KeyProvider::kNone:
129  break;
130  }
131  return encryption_key_source;
132 }
133 
134 std::unique_ptr<KeySource> CreateDecryptionKeySource(
135  const DecryptionParams& decryption_params) {
136  std::unique_ptr<KeySource> decryption_key_source;
137  switch (decryption_params.key_provider) {
138  case KeyProvider::kWidevine: {
139  const WidevineDecryptionParams& widevine = decryption_params.widevine;
140  if (widevine.key_server_url.empty()) {
141  LOG(ERROR) << "'key_server_url' should not be empty.";
142  return std::unique_ptr<KeySource>();
143  }
144  std::unique_ptr<WidevineKeySource> widevine_key_source(
145  new WidevineKeySource(widevine.key_server_url,
146  true /* commmon pssh, does not matter here */));
147  if (!widevine.signer.signer_name.empty()) {
148  std::unique_ptr<RequestSigner> request_signer(
149  CreateSigner(widevine.signer));
150  if (!request_signer)
151  return std::unique_ptr<KeySource>();
152  widevine_key_source->set_signer(std::move(request_signer));
153  }
154 
155  decryption_key_source = std::move(widevine_key_source);
156  break;
157  }
158  case KeyProvider::kRawKey: {
159  const RawKeyDecryptionParams& raw_key = decryption_params.raw_key;
160  const std::vector<uint8_t> kNoPssh;
161  const std::vector<uint8_t> kNoIv;
162  decryption_key_source = FixedKeySource::Create(
163  raw_key.key_map.find("")->second.key_id,
164  raw_key.key_map.find("")->second.key, kNoPssh, kNoIv);
165  break;
166  }
167  case KeyProvider::kNone:
168  case KeyProvider::kPlayready:
169  break;
170  }
171  return decryption_key_source;
172 }
173 
174 ChunkingOptions GetChunkingOptions(const ChunkingParams& chunking_params) {
175  ChunkingOptions chunking_options;
176  chunking_options.segment_duration_in_seconds =
177  chunking_params.segment_duration_in_seconds;
178  chunking_options.subsegment_duration_in_seconds =
179  chunking_params.subsegment_duration_in_seconds;
180  chunking_options.segment_sap_aligned = chunking_params.segment_sap_aligned;
181  chunking_options.subsegment_sap_aligned =
182  chunking_params.subsegment_sap_aligned;
183  return chunking_options;
184 }
185 
186 MuxerOptions GetMuxerOptions(const std::string& temp_dir,
187  const Mp4OutputParams& mp4_params) {
188  MuxerOptions muxer_options;
189  muxer_options.num_subsegments_per_sidx = mp4_params.num_subsegments_per_sidx;
190  muxer_options.mp4_include_pssh_in_stream = mp4_params.include_pssh_in_stream;
191  muxer_options.mp4_use_decoding_timestamp_in_timeline =
192  mp4_params.use_decoding_timestamp_in_timeline;
193  muxer_options.temp_dir = temp_dir;
194  return muxer_options;
195 }
196 
197 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
198  MpdOptions mpd_options;
199  mpd_options.dash_profile =
200  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
201  mpd_options.mpd_type =
202  (on_demand_profile || mpd_params.generate_static_live_mpd)
203  ? MpdType::kStatic
204  : MpdType::kDynamic;
205  mpd_options.minimum_update_period = mpd_params.minimum_update_period;
206  mpd_options.min_buffer_time = mpd_params.min_buffer_time;
207  mpd_options.time_shift_buffer_depth = mpd_params.time_shift_buffer_depth;
208  mpd_options.suggested_presentation_delay =
209  mpd_params.suggested_presentation_delay;
210  mpd_options.default_language = mpd_params.default_language;
211  return mpd_options;
212 }
213 
214 Status ConnectHandlers(std::vector<std::shared_ptr<MediaHandler>>& handlers) {
215  size_t num_handlers = handlers.size();
216  Status status;
217  for (size_t i = 1; i < num_handlers; ++i) {
218  status.Update(handlers[i - 1]->AddHandler(handlers[i]));
219  }
220  return status;
221 }
222 
223 } // namespace media
224 } // namespace shaka
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
void SetCaFile(const std::string &ca_file)
Sets the Certificate Authority file for validating self-signed certificates.
double segment_duration_in_seconds
Segment duration in seconds.
static std::unique_ptr< FixedKeySource > Create(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, const std::vector< uint8_t > &pssh_boxes, const std::vector< uint8_t > &iv)
static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)