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 <gflags/gflags.h>
10 #include <iostream>
11 
12 #include "packager/app/fixed_key_encryption_flags.h"
13 #include "packager/app/playready_key_encryption_flags.h"
14 #include "packager/app/mpd_flags.h"
15 #include "packager/app/muxer_flags.h"
16 #include "packager/app/widevine_encryption_flags.h"
17 #include "packager/base/logging.h"
18 #include "packager/base/strings/string_number_conversions.h"
19 #include "packager/media/base/fixed_key_source.h"
20 #include "packager/media/base/muxer_options.h"
21 #include "packager/media/base/playready_key_source.h"
22 #include "packager/media/base/request_signer.h"
23 #include "packager/media/base/widevine_key_source.h"
24 #include "packager/media/file/file.h"
25 #include "packager/mpd/base/mpd_options.h"
26 
27 DEFINE_bool(mp4_use_decoding_timestamp_in_timeline,
28  false,
29  "If set, decoding timestamp instead of presentation timestamp will "
30  "be used when generating media timeline, e.g. timestamps in sidx "
31  "and mpd. This is to workaround a Chromium bug that decoding "
32  "timestamp is used in buffered range, https://crbug.com/398130.");
33 DEFINE_bool(dump_stream_info, false, "Dump demuxed stream info.");
34 
35 namespace shaka {
36 namespace media {
37 
38 std::unique_ptr<RequestSigner> CreateSigner() {
39  std::unique_ptr<RequestSigner> signer;
40 
41  if (!FLAGS_aes_signing_key.empty()) {
42  signer.reset(AesRequestSigner::CreateSigner(
43  FLAGS_signer, FLAGS_aes_signing_key, FLAGS_aes_signing_iv));
44  if (!signer) {
45  LOG(ERROR) << "Cannot create an AES signer object from '"
46  << FLAGS_aes_signing_key << "':'" << FLAGS_aes_signing_iv
47  << "'.";
48  return std::unique_ptr<RequestSigner>();
49  }
50  } else if (!FLAGS_rsa_signing_key_path.empty()) {
51  std::string rsa_private_key;
52  if (!File::ReadFileToString(FLAGS_rsa_signing_key_path.c_str(),
53  &rsa_private_key)) {
54  LOG(ERROR) << "Failed to read from '" << FLAGS_rsa_signing_key_path
55  << "'.";
56  return std::unique_ptr<RequestSigner>();
57  }
58  signer.reset(RsaRequestSigner::CreateSigner(FLAGS_signer, rsa_private_key));
59  if (!signer) {
60  LOG(ERROR) << "Cannot create a RSA signer object from '"
61  << FLAGS_rsa_signing_key_path << "'.";
62  return std::unique_ptr<RequestSigner>();
63  }
64  }
65  return signer;
66 }
67 
68 std::unique_ptr<KeySource> CreateEncryptionKeySource() {
69  std::unique_ptr<KeySource> encryption_key_source;
70  if (FLAGS_enable_widevine_encryption) {
71  std::unique_ptr<WidevineKeySource> widevine_key_source(
72  new WidevineKeySource(FLAGS_key_server_url, FLAGS_include_common_pssh));
73  if (!FLAGS_signer.empty()) {
74  std::unique_ptr<RequestSigner> request_signer(CreateSigner());
75  if (!request_signer)
76  return std::unique_ptr<KeySource>();
77  widevine_key_source->set_signer(std::move(request_signer));
78  }
79 
80  std::vector<uint8_t> content_id;
81  if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) {
82  LOG(ERROR) << "Invalid content_id hex string specified.";
83  return std::unique_ptr<KeySource>();
84  }
85  Status status = widevine_key_source->FetchKeys(content_id, FLAGS_policy);
86  if (!status.ok()) {
87  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
88  << status.ToString();
89  return std::unique_ptr<KeySource>();
90  }
91  encryption_key_source = std::move(widevine_key_source);
92  } else if (FLAGS_enable_fixed_key_encryption) {
93  encryption_key_source = FixedKeySource::CreateFromHexStrings(
94  FLAGS_key_id, FLAGS_key, FLAGS_pssh, FLAGS_iv);
95  } else if (FLAGS_enable_playready_encryption) {
96  if (!FLAGS_playready_key_id.empty() && !FLAGS_playready_key.empty()) {
97  encryption_key_source = PlayReadyKeySource::CreateFromKeyAndKeyId(
98  FLAGS_playready_key_id, FLAGS_playready_key);
99  } else if (!FLAGS_playready_server_url.empty() &&
100  !FLAGS_program_identifier.empty()) {
101  std::unique_ptr<PlayReadyKeySource> playready_key_source;
102  if (!FLAGS_client_cert_file.empty() &&
103  !FLAGS_client_cert_private_key_file.empty() &&
104  !FLAGS_client_cert_private_key_password.empty()) {
105  playready_key_source.reset(new PlayReadyKeySource(
106  FLAGS_playready_server_url,
107  FLAGS_client_cert_file,
108  FLAGS_client_cert_private_key_file,
109  FLAGS_client_cert_private_key_password));
110  } else {
111  playready_key_source.reset(new PlayReadyKeySource(
112  FLAGS_playready_server_url));
113  }
114  if (!FLAGS_ca_file.empty()) {
115  playready_key_source->SetCaFile(FLAGS_ca_file);
116  }
117  playready_key_source->FetchKeysWithProgramIdentifier(FLAGS_program_identifier);
118  encryption_key_source = std::move(playready_key_source);
119  } else {
120  LOG(ERROR) << "Error creating PlayReady key source.";
121  return std::unique_ptr<KeySource>();
122  }
123  }
124  return encryption_key_source;
125 }
126 
127 std::unique_ptr<KeySource> CreateDecryptionKeySource() {
128  std::unique_ptr<KeySource> decryption_key_source;
129  if (FLAGS_enable_widevine_decryption) {
130  std::unique_ptr<WidevineKeySource> widevine_key_source(
131  new WidevineKeySource(FLAGS_key_server_url, FLAGS_include_common_pssh));
132  if (!FLAGS_signer.empty()) {
133  std::unique_ptr<RequestSigner> request_signer(CreateSigner());
134  if (!request_signer)
135  return std::unique_ptr<KeySource>();
136  widevine_key_source->set_signer(std::move(request_signer));
137  }
138 
139  decryption_key_source = std::move(widevine_key_source);
140  } else if (FLAGS_enable_fixed_key_decryption) {
141  const char kNoPssh[] = "";
142  const char kNoIv[] = "";
143  decryption_key_source = FixedKeySource::CreateFromHexStrings(
144  FLAGS_key_id, FLAGS_key, kNoPssh, kNoIv);
145  }
146  return decryption_key_source;
147 }
148 
149 bool GetMuxerOptions(MuxerOptions* muxer_options) {
150  DCHECK(muxer_options);
151 
152  muxer_options->segment_duration = FLAGS_segment_duration;
153  muxer_options->fragment_duration = FLAGS_fragment_duration;
154  muxer_options->segment_sap_aligned = FLAGS_segment_sap_aligned;
155  muxer_options->fragment_sap_aligned = FLAGS_fragment_sap_aligned;
156  muxer_options->num_subsegments_per_sidx = FLAGS_num_subsegments_per_sidx;
157  muxer_options->webm_subsample_encryption = FLAGS_webm_subsample_encryption;
158  if (FLAGS_mp4_use_decoding_timestamp_in_timeline) {
159  LOG(WARNING) << "Flag --mp4_use_decoding_timestamp_in_timeline is set. "
160  "Note that it is a temporary hack to workaround Chromium "
161  "bug https://crbug.com/398130. The flag may be removed "
162  "when the Chromium bug is fixed.";
163  }
164  muxer_options->mp4_use_decoding_timestamp_in_timeline =
165  FLAGS_mp4_use_decoding_timestamp_in_timeline;
166 
167  muxer_options->temp_dir = FLAGS_temp_dir;
168  return true;
169 }
170 
171 bool GetMpdOptions(bool on_demand_profile, MpdOptions* mpd_options) {
172  DCHECK(mpd_options);
173 
174  mpd_options->dash_profile =
175  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
176  mpd_options->mpd_type =
177  (on_demand_profile || FLAGS_generate_static_mpd)
178  ? MpdType::kStatic
179  : MpdType::kDynamic;
180  mpd_options->availability_time_offset = FLAGS_availability_time_offset;
181  mpd_options->minimum_update_period = FLAGS_minimum_update_period;
182  mpd_options->min_buffer_time = FLAGS_min_buffer_time;
183  mpd_options->time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
184  mpd_options->suggested_presentation_delay =
185  FLAGS_suggested_presentation_delay;
186  mpd_options->default_language = FLAGS_default_language;
187  return true;
188 }
189 
190 } // namespace media
191 } // 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::string &aes_key_hex, const std::string &iv_hex)
static std::unique_ptr< FixedKeySource > CreateFromHexStrings(const std::string &key_id_hex, const std::string &key_hex, const std::string &pssh_boxes_hex, const std::string &iv_hex)
void SetCaFile(const std::string &ca_file)
Sets the Certificate Authority file for validating self-signed certificates.
static bool ReadFileToString(const char *file_name, std::string *contents)
Definition: file.cc:185
static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::string &key_id_hex, const std::string &key_hex)