Properly handle failures when using PlayReady key source
Change-Id: I0a50ae67fcde1fa4a99b91ad7c2642bbfc90b73a
This commit is contained in:
parent
1974d37646
commit
fd41ef0032
|
@ -149,8 +149,13 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
|
||||||
if (!playready.ca_file.empty()) {
|
if (!playready.ca_file.empty()) {
|
||||||
playready_key_source->SetCaFile(playready.ca_file);
|
playready_key_source->SetCaFile(playready.ca_file);
|
||||||
}
|
}
|
||||||
playready_key_source->FetchKeysWithProgramIdentifier(
|
Status status = playready_key_source->FetchKeysWithProgramIdentifier(
|
||||||
playready.program_identifier);
|
playready.program_identifier);
|
||||||
|
if (!status.ok()) {
|
||||||
|
LOG(ERROR) << "PlayReady encryption key source failed to fetch keys: "
|
||||||
|
<< status.ToString();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
encryption_key_source = std::move(playready_key_source);
|
encryption_key_source = std::move(playready_key_source);
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Error creating PlayReady key source.";
|
LOG(ERROR) << "Error creating PlayReady key source.";
|
||||||
|
|
|
@ -11,14 +11,11 @@
|
||||||
#include "packager/media/base/playready_pssh_generator.h"
|
#include "packager/media/base/playready_pssh_generator.h"
|
||||||
#include "packager/media/base/raw_key_pssh_generator.h"
|
#include "packager/media/base/raw_key_pssh_generator.h"
|
||||||
#include "packager/media/base/widevine_pssh_generator.h"
|
#include "packager/media/base/widevine_pssh_generator.h"
|
||||||
|
#include "packager/status_macros.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
EncryptionKey::EncryptionKey() {}
|
|
||||||
|
|
||||||
EncryptionKey::~EncryptionKey() {}
|
|
||||||
|
|
||||||
KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) {
|
KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) {
|
||||||
if (protection_systems_flags & COMMON_PROTECTION_SYSTEM_FLAG) {
|
if (protection_systems_flags & COMMON_PROTECTION_SYSTEM_FLAG) {
|
||||||
pssh_generators_.emplace_back(new RawKeyPsshGenerator());
|
pssh_generators_.emplace_back(new RawKeyPsshGenerator());
|
||||||
|
@ -37,7 +34,7 @@ KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeySource::~KeySource() {}
|
KeySource::~KeySource() = default;
|
||||||
|
|
||||||
Status KeySource::UpdateProtectionSystemInfo(
|
Status KeySource::UpdateProtectionSystemInfo(
|
||||||
EncryptionKeyMap* encryption_key_map) {
|
EncryptionKeyMap* encryption_key_map) {
|
||||||
|
@ -49,21 +46,15 @@ Status KeySource::UpdateProtectionSystemInfo(
|
||||||
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
||||||
key_ids.push_back(pair.second->key_id);
|
key_ids.push_back(pair.second->key_id);
|
||||||
}
|
}
|
||||||
Status status = pssh_generator->GeneratePsshFromKeyIds(key_ids, &info);
|
RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIds(key_ids, &info));
|
||||||
if (!status.ok()) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
||||||
pair.second->key_system_info.push_back(info);
|
pair.second->key_system_info.push_back(info);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
|
||||||
ProtectionSystemSpecificInfo info;
|
ProtectionSystemSpecificInfo info;
|
||||||
Status status = pssh_generator->GeneratePsshFromKeyIdAndKey(
|
RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIdAndKey(
|
||||||
pair.second->key_id, pair.second->key, &info);
|
pair.second->key_id, pair.second->key, &info));
|
||||||
if (!status.ok()) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
pair.second->key_system_info.push_back(info);
|
pair.second->key_system_info.push_back(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,6 @@ enum class EmeInitDataType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EncryptionKey {
|
struct EncryptionKey {
|
||||||
EncryptionKey();
|
|
||||||
~EncryptionKey();
|
|
||||||
|
|
||||||
std::vector<ProtectionSystemSpecificInfo> key_system_info;
|
std::vector<ProtectionSystemSpecificInfo> key_system_info;
|
||||||
std::vector<uint8_t> key_id;
|
std::vector<uint8_t> key_id;
|
||||||
std::vector<uint8_t> key;
|
std::vector<uint8_t> key;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "packager/media/base/playready_key_source.h"
|
#include "packager/media/base/playready_key_source.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "packager/base/base64.h"
|
#include "packager/base/base64.h"
|
||||||
#include "packager/base/logging.h"
|
#include "packager/base/logging.h"
|
||||||
#include "packager/base/strings/string_number_conversions.h"
|
#include "packager/base/strings/string_number_conversions.h"
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include "packager/media/base/http_key_fetcher.h"
|
#include "packager/media/base/http_key_fetcher.h"
|
||||||
#include "packager/media/base/key_source.h"
|
#include "packager/media/base/key_source.h"
|
||||||
#include "packager/media/base/playready_pssh_generator.h"
|
#include "packager/media/base/playready_pssh_generator.h"
|
||||||
|
#include "packager/status_macros.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
@ -118,33 +120,23 @@ Status SetKeyInformationFromServerResponse(const std::string& response,
|
||||||
// the packager response and encrypt multiple tracks using differnt
|
// the packager response and encrypt multiple tracks using differnt
|
||||||
// key_id/keys.
|
// key_id/keys.
|
||||||
std::string key_id_hex;
|
std::string key_id_hex;
|
||||||
Status status = RetrieveTextInXMLElement("KeyId", response, &key_id_hex);
|
RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyId", response, &key_id_hex));
|
||||||
if (!status.ok()) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
key_id_hex.erase(
|
key_id_hex.erase(
|
||||||
std::remove(key_id_hex.begin(), key_id_hex.end(), '-'), key_id_hex.end());
|
std::remove(key_id_hex.begin(), key_id_hex.end(), '-'), key_id_hex.end());
|
||||||
std::string key_data_b64;
|
|
||||||
status = RetrieveTextInXMLElement("KeyData", response, &key_data_b64);
|
|
||||||
if (!status.ok()) {
|
|
||||||
LOG(ERROR) << "Key retreiving KeyData";
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
std::string pssh_data_b64;
|
|
||||||
status = RetrieveTextInXMLElement("Data", response, &pssh_data_b64);
|
|
||||||
if (!status.ok()) {
|
|
||||||
LOG(ERROR) << "Key retreiving Data";
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) {
|
if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) {
|
||||||
LOG(ERROR) << "Cannot parse key_id_hex, " << key_id_hex;
|
LOG(ERROR) << "Cannot parse key_id_hex, " << key_id_hex;
|
||||||
return Status(error::SERVER_ERROR, "Cannot parse key_id_hex.");
|
return Status(error::SERVER_ERROR, "Cannot parse key_id_hex.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string key_data_b64;
|
||||||
|
RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyData", response, &key_data_b64));
|
||||||
if (!Base64StringToBytes(key_data_b64, &encryption_key->key)) {
|
if (!Base64StringToBytes(key_data_b64, &encryption_key->key)) {
|
||||||
LOG(ERROR) << "Cannot parse key, " << key_data_b64;
|
LOG(ERROR) << "Cannot parse key, " << key_data_b64;
|
||||||
return Status(error::SERVER_ERROR, "Cannot parse key.");
|
return Status(error::SERVER_ERROR, "Cannot parse key.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string pssh_data_b64;
|
||||||
|
RETURN_IF_ERROR(RetrieveTextInXMLElement("Data", response, &pssh_data_b64));
|
||||||
std::vector<uint8_t> pssh_data;
|
std::vector<uint8_t> pssh_data;
|
||||||
if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
|
if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
|
||||||
LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
|
LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
|
||||||
|
@ -172,26 +164,24 @@ Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
|
||||||
if (!ca_file_.empty()) {
|
if (!ca_file_.empty()) {
|
||||||
key_fetcher.SetCaFile(ca_file_);
|
key_fetcher.SetCaFile(ca_file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string acquire_license_request = kAcquireLicenseRequest;
|
std::string acquire_license_request = kAcquireLicenseRequest;
|
||||||
base::ReplaceFirstSubstringAfterOffset(
|
base::ReplaceFirstSubstringAfterOffset(
|
||||||
&acquire_license_request, 0, "$0", program_identifier);
|
&acquire_license_request, 0, "$0", program_identifier);
|
||||||
std::string acquire_license_response;
|
std::string acquire_license_response;
|
||||||
Status status = key_fetcher.FetchKeys(server_url_, acquire_license_request,
|
Status status = key_fetcher.FetchKeys(server_url_, acquire_license_request,
|
||||||
&acquire_license_response);
|
&acquire_license_response);
|
||||||
if (!status.ok()) {
|
VLOG(1) << "Server response: " << acquire_license_response;
|
||||||
LOG(ERROR) << "Server response: " << acquire_license_response;
|
RETURN_IF_ERROR(status);
|
||||||
return status;
|
|
||||||
}
|
RETURN_IF_ERROR(SetKeyInformationFromServerResponse(acquire_license_response,
|
||||||
status = SetKeyInformationFromServerResponse(acquire_license_response,
|
encryption_key.get()));
|
||||||
encryption_key.get());
|
|
||||||
// PlayReady does not specify different streams.
|
// PlayReady does not specify different streams.
|
||||||
const char kEmptyDrmLabel[] = "";
|
const char kEmptyDrmLabel[] = "";
|
||||||
EncryptionKeyMap encryption_key_map;
|
EncryptionKeyMap encryption_key_map;
|
||||||
encryption_key_map[kEmptyDrmLabel] = std::move(encryption_key);
|
encryption_key_map[kEmptyDrmLabel] = std::move(encryption_key);
|
||||||
status = UpdateProtectionSystemInfo(&encryption_key_map);
|
RETURN_IF_ERROR(UpdateProtectionSystemInfo(&encryption_key_map));
|
||||||
if (!status.ok()) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
encryption_key_ = std::move(encryption_key_map[kEmptyDrmLabel]);
|
encryption_key_ = std::move(encryption_key_map[kEmptyDrmLabel]);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue