Add fixed key support for HLS sample-aes encryption
Change-Id: I5a18e014f697561e0741b043e91f70fe2f11d2ce
This commit is contained in:
parent
dad07c95d7
commit
f27960e00d
|
@ -8,22 +8,28 @@
|
|||
|
||||
#include "packager/base/base64.h"
|
||||
#include "packager/base/files/file_path.h"
|
||||
#include "packager/base/json/json_writer.h"
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
#include "packager/base/strings/stringprintf.h"
|
||||
#include "packager/hls/base/media_playlist.h"
|
||||
#include "packager/media/base/fixed_key_source.h"
|
||||
#include "packager/media/base/widevine_key_source.h"
|
||||
#include "packager/media/base/widevine_pssh_data.pb.h"
|
||||
|
||||
namespace shaka {
|
||||
namespace hls {
|
||||
|
||||
namespace {
|
||||
const uint8_t kSystemIdWidevine[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
bool IsWidevineSystemId(const std::vector<uint8_t>& system_id) {
|
||||
return system_id.size() == arraysize(kSystemIdWidevine) &&
|
||||
std::equal(system_id.begin(), system_id.end(), kSystemIdWidevine);
|
||||
return system_id.size() == arraysize(media::kWidevineSystemId) &&
|
||||
std::equal(system_id.begin(), system_id.end(),
|
||||
media::kWidevineSystemId);
|
||||
}
|
||||
|
||||
bool IsCommonSystemId(const std::vector<uint8_t>& system_id) {
|
||||
return system_id.size() == arraysize(media::kCommonSystemId) &&
|
||||
std::equal(system_id.begin(), system_id.end(), media::kCommonSystemId);
|
||||
}
|
||||
|
||||
// TODO(rkuroiwa): Dedup these with the functions in MpdBuilder.
|
||||
|
@ -62,6 +68,48 @@ void MakePathsRelativeToOutputDirectory(const std::string& output_dir,
|
|||
media_info->segment_template(), directory_with_separator));
|
||||
}
|
||||
}
|
||||
|
||||
bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_data,
|
||||
const std::vector<uint8_t>& key_id,
|
||||
std::string* pssh_json) {
|
||||
media::WidevinePsshData pssh_proto;
|
||||
if (!pssh_proto.ParseFromArray(pssh_data.data(), pssh_data.size())) {
|
||||
LOG(ERROR) << "Failed to parse protection_system_specific_data.";
|
||||
return false;
|
||||
}
|
||||
if (!pssh_proto.has_provider() ||
|
||||
(!pssh_proto.has_content_id() && pssh_proto.key_id_size() == 0)) {
|
||||
LOG(ERROR) << "Missing fields to generate URI.";
|
||||
return false;
|
||||
}
|
||||
|
||||
base::DictionaryValue pssh_dict;
|
||||
pssh_dict.SetString("provider", pssh_proto.provider());
|
||||
if (pssh_proto.has_content_id()) {
|
||||
std::string content_id_base64;
|
||||
base::Base64Encode(base::StringPiece(pssh_proto.content_id().data(),
|
||||
pssh_proto.content_id().size()),
|
||||
&content_id_base64);
|
||||
pssh_dict.SetString("content_id", content_id_base64);
|
||||
}
|
||||
base::ListValue* key_ids = new base::ListValue();
|
||||
key_ids->AppendString(base::HexEncode(key_id.data(), key_id.size()));
|
||||
for (const std::string& id : pssh_proto.key_id()) {
|
||||
if (key_id.size() == id.size() &&
|
||||
memcmp(key_id.data(), id.data(), id.size()) == 0) {
|
||||
continue;
|
||||
}
|
||||
key_ids->AppendString(base::HexEncode(id.data(), id.size()));
|
||||
}
|
||||
pssh_dict.Set("key_ids", key_ids);
|
||||
|
||||
if (!base::JSONWriter::Write(pssh_dict, pssh_json)) {
|
||||
LOG(ERROR) << "Failed to write to JSON.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MediaPlaylistFactory::~MediaPlaylistFactory() {}
|
||||
|
@ -149,7 +197,6 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO(rkuroiwa): Add static key support. for common system id.
|
||||
bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
||||
uint32_t stream_id,
|
||||
const std::vector<uint8_t>& key_id,
|
||||
|
@ -162,55 +209,37 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
|||
LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
|
||||
return false;
|
||||
}
|
||||
if (!IsWidevineSystemId(system_id)) {
|
||||
|
||||
std::string key_format;
|
||||
std::string key_uri_data;
|
||||
if (IsWidevineSystemId(system_id)) {
|
||||
key_format = "com.widevine";
|
||||
if (!WidevinePsshToJson(protection_system_specific_data, key_id,
|
||||
&key_uri_data)) {
|
||||
return false;
|
||||
}
|
||||
} else if (IsCommonSystemId(system_id)) {
|
||||
key_format = "identity";
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key url.
|
||||
key_uri_data.assign(key_id.begin(), key_id.end());
|
||||
} else {
|
||||
LOG(ERROR) << "Unknown system ID: "
|
||||
<< base::HexEncode(system_id.data(), system_id.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
media::WidevinePsshData pssh_data;
|
||||
if (!pssh_data.ParseFromArray(protection_system_specific_data.data(),
|
||||
protection_system_specific_data.size())) {
|
||||
LOG(ERROR) << "Failed ot parse protection_system_specific_data.";
|
||||
return false;
|
||||
}
|
||||
if (!pssh_data.has_provider() || !pssh_data.has_content_id() ||
|
||||
pssh_data.key_id_size() == 0) {
|
||||
LOG(ERROR) << "Missing fields to generate URI.";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string content_id_base64;
|
||||
base::Base64Encode(base::StringPiece(pssh_data.content_id().data(),
|
||||
pssh_data.content_id().size()),
|
||||
&content_id_base64);
|
||||
std::string json_format = base::StringPrintf(
|
||||
"{"
|
||||
"\"provider\":\"%s\","
|
||||
"\"content_id\":\"%s\","
|
||||
"\"key_ids\":[",
|
||||
pssh_data.provider().c_str(), content_id_base64.c_str());
|
||||
json_format += "\"" + base::HexEncode(key_id.data(), key_id.size()) + "\",";
|
||||
for (const std::string& id: pssh_data.key_id()) {
|
||||
if (key_id.size() == id.size() &&
|
||||
memcmp(key_id.data(), id.data(), id.size()) == 0) {
|
||||
continue;
|
||||
}
|
||||
json_format += "\"" + base::HexEncode(id.data(), id.size()) + "\",";
|
||||
}
|
||||
json_format += "]}";
|
||||
std::string json_format_base64;
|
||||
base::Base64Encode(json_format, &json_format_base64);
|
||||
|
||||
auto& media_playlist = result->second;
|
||||
std::string iv_string;
|
||||
if (!iv.empty()) {
|
||||
iv_string = "0x" + base::HexEncode(iv.data(), iv.size());
|
||||
}
|
||||
std::string key_uri_data_base64;
|
||||
base::Base64Encode(key_uri_data, &key_uri_data_base64);
|
||||
media_playlist->AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
"data:text/plain;base64," + json_format_base64, iv_string,
|
||||
"com.widevine", "");
|
||||
"data:text/plain;base64," + key_uri_data_base64, iv_string, key_format,
|
||||
"" /* key_format_versions */);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "packager/base/base64.h"
|
||||
#include "packager/hls/base/mock_media_playlist.h"
|
||||
#include "packager/hls/base/simple_hls_notifier.h"
|
||||
#include "packager/media/base/fixed_key_source.h"
|
||||
#include "packager/media/base/widevine_key_source.h"
|
||||
#include "packager/media/base/widevine_pssh_data.pb.h"
|
||||
|
||||
namespace shaka {
|
||||
|
@ -72,7 +74,13 @@ class SimpleHlsNotifierTest : public ::testing::Test {
|
|||
: notifier_(HlsNotifier::HlsProfile::kOnDemandProfile,
|
||||
kTestPrefix,
|
||||
kAnyOutputDir,
|
||||
kMasterPlaylistName) {}
|
||||
kMasterPlaylistName),
|
||||
widevine_system_id_(
|
||||
media::kWidevineSystemId,
|
||||
media::kWidevineSystemId + arraysize(media::kWidevineSystemId)),
|
||||
common_system_id_(
|
||||
media::kCommonSystemId,
|
||||
media::kCommonSystemId + arraysize(media::kCommonSystemId)) {}
|
||||
|
||||
void InjectMediaPlaylistFactory(scoped_ptr<MediaPlaylistFactory> factory) {
|
||||
notifier_.media_playlist_factory_ = factory.Pass();
|
||||
|
@ -96,7 +104,32 @@ class SimpleHlsNotifierTest : public ::testing::Test {
|
|||
return notifier_.media_playlist_map_;
|
||||
}
|
||||
|
||||
uint32_t SetupStream(MockMediaPlaylist* mock_media_playlist) {
|
||||
scoped_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||
new MockMasterPlaylist());
|
||||
scoped_ptr<MockMediaPlaylistFactory> factory(
|
||||
new MockMediaPlaylistFactory());
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist,
|
||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(mock_master_playlist.Pass());
|
||||
InjectMediaPlaylistFactory(factory.Pass());
|
||||
EXPECT_TRUE(notifier_.Init());
|
||||
MediaInfo media_info;
|
||||
uint32_t stream_id;
|
||||
EXPECT_TRUE(notifier_.NotifyNewStream(media_info, "playlist.m3u8", "name",
|
||||
"groupid", &stream_id));
|
||||
return stream_id;
|
||||
}
|
||||
|
||||
SimpleHlsNotifier notifier_;
|
||||
const std::vector<uint8_t> widevine_system_id_;
|
||||
const std::vector<uint8_t> common_system_id_;
|
||||
};
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, Init) {
|
||||
|
@ -288,35 +321,13 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
|
|||
EXPECT_FALSE(notifier_.NotifyNewSegment(1u, "anything", 0u, 0u, 0u));
|
||||
}
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdate) {
|
||||
scoped_ptr<MockMasterPlaylist> mock_master_playlist(new MockMasterPlaylist());
|
||||
scoped_ptr<MockMediaPlaylistFactory> factory(new MockMediaPlaylistFactory());
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "", "", "");
|
||||
const uint32_t stream_id = SetupStream(mock_media_playlist);
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist,
|
||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(mock_master_playlist.Pass());
|
||||
InjectMediaPlaylistFactory(factory.Pass());
|
||||
EXPECT_TRUE(notifier_.Init());
|
||||
MediaInfo media_info;
|
||||
uint32_t stream_id;
|
||||
EXPECT_TRUE(notifier_.NotifyNewStream(media_info, "playlist.m3u8", "name",
|
||||
"groupid", &stream_id));
|
||||
|
||||
const uint8_t kSystemIdWidevine[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
std::vector<uint8_t> system_id(
|
||||
kSystemIdWidevine, kSystemIdWidevine + arraysize(kSystemIdWidevine));
|
||||
std::vector<uint8_t> iv(16, 0x45);
|
||||
const std::vector<uint8_t> iv(16, 0x45);
|
||||
|
||||
media::WidevinePsshData widevine_pssh_data;
|
||||
widevine_pssh_data.set_provider("someprovider");
|
||||
|
@ -333,9 +344,9 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdate) {
|
|||
|
||||
const char kExpectedJson[] =
|
||||
"{"
|
||||
"\"provider\":\"someprovider\","
|
||||
"\"content_id\":\"Y29udGVudGlk\","
|
||||
"\"key_ids\":[\"11223344\",]}";
|
||||
"\"key_ids\":[\"11223344\"],"
|
||||
"\"provider\":\"someprovider\"}";
|
||||
std::string expected_json_base64;
|
||||
base::Base64Encode(kExpectedJson, &expected_json_base64);
|
||||
|
||||
|
@ -348,44 +359,86 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdate) {
|
|||
EXPECT_TRUE(notifier_.NotifyEncryptionUpdate(
|
||||
stream_id,
|
||||
std::vector<uint8_t>(kAnyKeyId, kAnyKeyId + arraysize(kAnyKeyId)),
|
||||
system_id, iv, pssh_data));
|
||||
widevine_system_id_, iv, pssh_data));
|
||||
}
|
||||
|
||||
// Verify that when there are multiple key IDs in PSSH, the key ID that is
|
||||
// passed to NotifyEncryptionUpdate() is the first key ID in the json format.
|
||||
TEST_F(SimpleHlsNotifierTest, MultipleKeyIdsInPssh) {
|
||||
scoped_ptr<MockMasterPlaylist> mock_master_playlist(new MockMasterPlaylist());
|
||||
scoped_ptr<MockMediaPlaylistFactory> factory(new MockMediaPlaylistFactory());
|
||||
|
||||
// Verify that key_ids in pssh is optional.
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "", "", "");
|
||||
const uint32_t stream_id = SetupStream(mock_media_playlist);
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist,
|
||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(mock_master_playlist.Pass());
|
||||
InjectMediaPlaylistFactory(factory.Pass());
|
||||
EXPECT_TRUE(notifier_.Init());
|
||||
MediaInfo media_info;
|
||||
uint32_t stream_id;
|
||||
EXPECT_TRUE(notifier_.NotifyNewStream(media_info, "playlist.m3u8", "name",
|
||||
"groupid", &stream_id));
|
||||
|
||||
const uint8_t kSystemIdWidevine[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
std::vector<uint8_t> system_id(
|
||||
kSystemIdWidevine, kSystemIdWidevine + arraysize(kSystemIdWidevine));
|
||||
std::vector<uint8_t> iv(16, 0x45);
|
||||
const std::vector<uint8_t> iv(16, 0x45);
|
||||
|
||||
media::WidevinePsshData widevine_pssh_data;
|
||||
widevine_pssh_data.set_provider("someprovider");
|
||||
widevine_pssh_data.set_content_id("contentid");
|
||||
std::string widevine_pssh_data_str = widevine_pssh_data.SerializeAsString();
|
||||
EXPECT_TRUE(!widevine_pssh_data_str.empty());
|
||||
std::vector<uint8_t> pssh_data(widevine_pssh_data_str.begin(),
|
||||
widevine_pssh_data_str.end());
|
||||
|
||||
const char kExpectedJson[] =
|
||||
"{"
|
||||
"\"content_id\":\"Y29udGVudGlk\","
|
||||
"\"key_ids\":[\"11223344\"],"
|
||||
"\"provider\":\"someprovider\"}";
|
||||
std::string expected_json_base64;
|
||||
base::Base64Encode(kExpectedJson, &expected_json_base64);
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_media_playlist,
|
||||
AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
StrEq("data:text/plain;base64," + expected_json_base64),
|
||||
StrEq("0x45454545454545454545454545454545"),
|
||||
StrEq("com.widevine"), _));
|
||||
const uint8_t kAnyKeyId[] = {
|
||||
0x11, 0x22, 0x33, 0x44,
|
||||
};
|
||||
EXPECT_TRUE(notifier_.NotifyEncryptionUpdate(
|
||||
stream_id,
|
||||
std::vector<uint8_t>(kAnyKeyId, kAnyKeyId + arraysize(kAnyKeyId)),
|
||||
widevine_system_id_, iv, pssh_data));
|
||||
}
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFixedKey) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "", "", "");
|
||||
const uint32_t stream_id = SetupStream(mock_media_playlist);
|
||||
|
||||
const std::vector<uint8_t> key_id(16, 0x23);
|
||||
const std::vector<uint8_t> iv(16, 0x45);
|
||||
const std::vector<uint8_t> dummy_pssh_data(10, 'p');
|
||||
|
||||
std::string expected_key_uri_base64;
|
||||
base::Base64Encode(std::string(key_id.begin(), key_id.end()),
|
||||
&expected_key_uri_base64);
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_media_playlist,
|
||||
AddEncryptionInfo(
|
||||
MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
StrEq("data:text/plain;base64," + expected_key_uri_base64),
|
||||
StrEq("0x45454545454545454545454545454545"), StrEq("identity"), _));
|
||||
EXPECT_TRUE(notifier_.NotifyEncryptionUpdate(
|
||||
stream_id, key_id, common_system_id_, iv, dummy_pssh_data));
|
||||
}
|
||||
|
||||
// Verify that when there are multiple key IDs in PSSH, the key ID that is
|
||||
// passed to NotifyEncryptionUpdate() is the first key ID in the json format.
|
||||
// Also verify that content_id is optional.
|
||||
TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "", "", "");
|
||||
uint32_t stream_id = SetupStream(mock_media_playlist);
|
||||
|
||||
std::vector<uint8_t> iv(16, 0x45);
|
||||
|
||||
media::WidevinePsshData widevine_pssh_data;
|
||||
widevine_pssh_data.set_provider("someprovider");
|
||||
const uint8_t kFirstKeyId[] = {
|
||||
0x11, 0x11, 0x11, 0x11,
|
||||
};
|
||||
|
@ -403,9 +456,8 @@ TEST_F(SimpleHlsNotifierTest, MultipleKeyIdsInPssh) {
|
|||
|
||||
const char kExpectedJson[] =
|
||||
"{"
|
||||
"\"provider\":\"someprovider\","
|
||||
"\"content_id\":\"Y29udGVudGlk\","
|
||||
"\"key_ids\":[\"22222222\",\"11111111\",]}";
|
||||
"\"key_ids\":[\"22222222\",\"11111111\"],"
|
||||
"\"provider\":\"someprovider\"}";
|
||||
std::string expected_json_base64;
|
||||
base::Base64Encode(kExpectedJson, &expected_json_base64);
|
||||
|
||||
|
@ -421,37 +473,14 @@ TEST_F(SimpleHlsNotifierTest, MultipleKeyIdsInPssh) {
|
|||
// key_ids array in the JSON.
|
||||
std::vector<uint8_t>(kSecondKeyId,
|
||||
kSecondKeyId + arraysize(kSecondKeyId)),
|
||||
system_id, iv, pssh_data));
|
||||
widevine_system_id_, iv, pssh_data));
|
||||
}
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateEmptyIv) {
|
||||
scoped_ptr<MockMasterPlaylist> mock_master_playlist(new MockMasterPlaylist());
|
||||
scoped_ptr<MockMediaPlaylistFactory> factory(new MockMediaPlaylistFactory());
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "", "", "");
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist,
|
||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _))
|
||||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
InjectMasterPlaylist(mock_master_playlist.Pass());
|
||||
InjectMediaPlaylistFactory(factory.Pass());
|
||||
EXPECT_TRUE(notifier_.Init());
|
||||
MediaInfo media_info;
|
||||
uint32_t stream_id;
|
||||
EXPECT_TRUE(notifier_.NotifyNewStream(media_info, "playlist.m3u8", "name",
|
||||
"groupid", &stream_id));
|
||||
|
||||
const uint8_t kSystemIdWidevine[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
std::vector<uint8_t> system_id(
|
||||
kSystemIdWidevine, kSystemIdWidevine + arraysize(kSystemIdWidevine));
|
||||
const uint32_t stream_id = SetupStream(mock_media_playlist);
|
||||
|
||||
media::WidevinePsshData widevine_pssh_data;
|
||||
widevine_pssh_data.set_provider("someprovider");
|
||||
|
@ -468,9 +497,9 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateEmptyIv) {
|
|||
|
||||
const char kExpectedJson[] =
|
||||
"{"
|
||||
"\"provider\":\"someprovider\","
|
||||
"\"content_id\":\"Y29udGVudGlk\","
|
||||
"\"key_ids\":[\"11223344\",]}";
|
||||
"\"key_ids\":[\"11223344\"],"
|
||||
"\"provider\":\"someprovider\"}";
|
||||
std::string expected_json_base64;
|
||||
base::Base64Encode(kExpectedJson, &expected_json_base64);
|
||||
|
||||
|
@ -484,7 +513,7 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateEmptyIv) {
|
|||
EXPECT_TRUE(notifier_.NotifyEncryptionUpdate(
|
||||
stream_id,
|
||||
std::vector<uint8_t>(kAnyKeyId, kAnyKeyId + arraysize(kAnyKeyId)),
|
||||
system_id, empty_iv, pssh_data));
|
||||
widevine_system_id_, empty_iv, pssh_data));
|
||||
}
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'../base/base.gyp:base',
|
||||
'../media/base/media_base.gyp:widevine_pssh_data_proto',
|
||||
'../media/base/media_base.gyp:media_base',
|
||||
'../media/file/file.gyp:file',
|
||||
'../mpd/mpd.gyp:media_info_proto',
|
||||
],
|
||||
|
|
|
@ -43,10 +43,6 @@ const int kDefaultCryptoPeriodCount = 10;
|
|||
const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes.
|
||||
const int kKeyFetchTimeoutInSeconds = 60; // 1 minute.
|
||||
|
||||
const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
|
||||
bool Base64StringToBytes(const std::string& base64_string,
|
||||
std::vector<uint8_t>* bytes) {
|
||||
DCHECK(bytes);
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
|
||||
namespace shaka {
|
||||
namespace media {
|
||||
|
||||
const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
|
||||
class KeyFetcher;
|
||||
class RequestSigner;
|
||||
template <class T> class ProducerConsumerQueue;
|
||||
|
|
Loading…
Reference in New Issue