Add --hls_key_uri to allow setting fairplay/identity key uri
Change-Id: I52e0f56cd10390faf515170f407ea488a6b3c9fc
This commit is contained in:
parent
61e36d7d21
commit
5cf2b17ade
|
@ -11,6 +11,11 @@ HLS options
|
|||
The base URL for the Media Playlists and media files listed in the
|
||||
playlists. This is the prefix for the files.
|
||||
|
||||
--hls_key_uri <uri>
|
||||
|
||||
The key uri for 'identity' and 'com.apple.streamingkeydelivery' key formats.
|
||||
Ignored if the playlist is not encrypted or not using the above key formats.
|
||||
|
||||
--hls_playlist_type <type>
|
||||
|
||||
VOD, EVENT, or LIVE. This defines the EXT-X-PLAYLIST-TYPE in the HLS
|
||||
|
|
|
@ -14,6 +14,11 @@ DEFINE_string(hls_base_url,
|
|||
"",
|
||||
"The base URL for the Media Playlists and media files listed in "
|
||||
"the playlists. This is the prefix for the files.");
|
||||
DEFINE_string(hls_key_uri,
|
||||
"",
|
||||
"The key uri for 'identity' and 'com.apple.streamingkeydelivery' "
|
||||
"key formats. Ignored if the playlist is not encrypted or not "
|
||||
"using the above key formats.");
|
||||
DEFINE_string(hls_playlist_type,
|
||||
"VOD",
|
||||
"VOD, EVENT, or LIVE. This defines the EXT-X-PLAYLIST-TYPE in "
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
DECLARE_string(hls_master_playlist_output);
|
||||
DECLARE_string(hls_base_url);
|
||||
DECLARE_string(hls_key_uri);
|
||||
DECLARE_string(hls_playlist_type);
|
||||
|
||||
#endif // PACKAGER_APP_HLS_FLAGS_H_
|
||||
|
|
|
@ -356,6 +356,7 @@ base::Optional<PackagingParams> GetPackagingParams() {
|
|||
}
|
||||
hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
|
||||
hls_params.base_url = FLAGS_hls_base_url;
|
||||
hls_params.key_uri = FLAGS_hls_key_uri;
|
||||
hls_params.time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
|
||||
|
||||
TestParams& test_params = packaging_params.test_params;
|
||||
|
|
|
@ -122,6 +122,7 @@ class PackagerAppTest(unittest.TestCase):
|
|||
def _GetFlags(self,
|
||||
strip_parameter_set_nalus=True,
|
||||
encryption=False,
|
||||
fairplay=False,
|
||||
clear_lead=1,
|
||||
protection_scheme=None,
|
||||
vp9_subsample_encryption=True,
|
||||
|
@ -160,6 +161,15 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
if not random_iv:
|
||||
flags.append('--iv=' + self.encryption_iv)
|
||||
|
||||
if fairplay:
|
||||
fairplay_pssh = ('000000207073736800000000'
|
||||
'29701FE43CC74A348C5BAE90C7439A4700000000')
|
||||
fairplay_key_uri = ('skd://www.license.com/'
|
||||
'getkey?KeyId=31323334-3536-3738-3930-313233343536')
|
||||
flags += [
|
||||
'--pssh=' + fairplay_pssh, '--hls_key_uri=' + fairplay_key_uri
|
||||
]
|
||||
if protection_scheme:
|
||||
flags += ['--protection_scheme', protection_scheme]
|
||||
if not vp9_subsample_encryption:
|
||||
|
@ -771,6 +781,31 @@ class PackagerFunctionalTest(PackagerAppTest):
|
|||
os.path.join(self.tmp_dir, 'video.m3u8'),
|
||||
'bear-640x360-v-enc-golden.m3u8')
|
||||
|
||||
def testPackageAvcTsWithEncryptionAndFairplay(self):
|
||||
# Currently we only support live packaging for ts.
|
||||
self.assertPackageSuccess(
|
||||
self._GetStreams(
|
||||
['audio', 'video'],
|
||||
output_format='ts',
|
||||
live=True,
|
||||
hls=True,
|
||||
test_files=['bear-640x360.ts']),
|
||||
self._GetFlags(encryption=True, output_hls=True, fairplay=True))
|
||||
self._DiffLiveGold(self.output[0],
|
||||
'bear-640x360-a-enc-golden',
|
||||
output_format='ts')
|
||||
self._DiffLiveGold(self.output[1],
|
||||
'bear-640x360-v-enc-golden',
|
||||
output_format='ts')
|
||||
self._DiffGold(self.hls_master_playlist_output,
|
||||
'bear-640x360-av-master-golden.m3u8')
|
||||
self._DiffGold(
|
||||
os.path.join(self.tmp_dir, 'audio.m3u8'),
|
||||
'bear-640x360-a-fairplay-enc-golden.m3u8')
|
||||
self._DiffGold(
|
||||
os.path.join(self.tmp_dir, 'video.m3u8'),
|
||||
'bear-640x360-v-fairplay-enc-golden.m3u8')
|
||||
|
||||
def testPackageAvcTsWithEncryptionExerciseEmulationPrevention(self):
|
||||
self.encryption_key = 'ad7e9786def9159db6724be06dfcde7a'
|
||||
# Currently we only support live packaging for ts.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
#EXT-X-TARGETDURATION:2
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:0.975,
|
||||
output_audio-1.ts
|
||||
#EXTINF:0.998,
|
||||
output_audio-2.ts
|
||||
#EXT-X-DISCONTINUITY
|
||||
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery"
|
||||
#EXTINF:0.789,
|
||||
output_audio-3.ts
|
||||
#EXT-X-ENDLIST
|
|
@ -0,0 +1,14 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
#EXT-X-TARGETDURATION:2
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:1.001,
|
||||
output_video-1.ts
|
||||
#EXT-X-DISCONTINUITY
|
||||
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://www.license.com/getkey?KeyId=31323334-3536-3738-3930-313233343536",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery"
|
||||
#EXTINF:1.001,
|
||||
output_video-2.ts
|
||||
#EXTINF:0.734,
|
||||
output_video-3.ts
|
||||
#EXT-X-ENDLIST
|
|
@ -250,11 +250,13 @@ std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
|
|||
SimpleHlsNotifier::SimpleHlsNotifier(HlsPlaylistType playlist_type,
|
||||
double time_shift_buffer_depth,
|
||||
const std::string& prefix,
|
||||
const std::string& key_uri,
|
||||
const std::string& output_dir,
|
||||
const std::string& master_playlist_name)
|
||||
: HlsNotifier(playlist_type),
|
||||
time_shift_buffer_depth_(time_shift_buffer_depth),
|
||||
prefix_(prefix),
|
||||
key_uri_(key_uri),
|
||||
output_dir_(output_dir),
|
||||
media_playlist_factory_(new MediaPlaylistFactory()),
|
||||
master_playlist_(new MasterPlaylist(master_playlist_name)) {}
|
||||
|
@ -389,31 +391,39 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
|||
key_id, iv, protection_system_specific_data,
|
||||
media_playlist.get());
|
||||
}
|
||||
|
||||
// Key Id does not need to be specified with "identity" and "sdk".
|
||||
const std::vector<uint8_t> empty_key_id;
|
||||
|
||||
if (IsCommonSystemId(system_id)) {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key url.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
std::string key_uri_data_base64 =
|
||||
Base64EncodeData(kUriBase64Prefix, key_uri_data);
|
||||
NotifyEncryptionToMediaPlaylist(encryption_method,
|
||||
key_uri_data_base64, std::vector<uint8_t>(),
|
||||
std::string key_uri;
|
||||
if (!key_uri_.empty()) {
|
||||
key_uri = key_uri_;
|
||||
} else {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key uri.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
key_uri = Base64EncodeData(kUriBase64Prefix, key_uri_data);
|
||||
}
|
||||
NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
|
||||
iv, "identity", "", media_playlist.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsFairplaySystemId(system_id)) {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key url.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
std::string key_uri_data_base64 =
|
||||
Base64EncodeData(kUriFairplayPrefix, key_uri_data);
|
||||
} else if (IsFairplaySystemId(system_id)) {
|
||||
std::string key_uri;
|
||||
if (!key_uri_.empty()) {
|
||||
key_uri = key_uri_;
|
||||
} else {
|
||||
// Use key_id as the key_uri. The player needs to have custom logic to
|
||||
// convert it to the actual key uri.
|
||||
std::string key_uri_data = VectorToString(key_id);
|
||||
key_uri = Base64EncodeData(kUriFairplayPrefix, key_uri_data);
|
||||
}
|
||||
|
||||
// Fairplay defines IV to be carried with the key, not the playlist.
|
||||
NotifyEncryptionToMediaPlaylist(encryption_method,
|
||||
key_uri_data_base64, std::vector<uint8_t>(),
|
||||
std::vector<uint8_t>(),
|
||||
"com.apple.streamingkeydelivery", "1",
|
||||
media_playlist.get());
|
||||
const std::vector<uint8_t> empty_iv;
|
||||
NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
|
||||
empty_iv, "com.apple.streamingkeydelivery",
|
||||
"1", media_playlist.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,16 @@ class SimpleHlsNotifier : public HlsNotifier {
|
|||
/// shifting buffer, only for live HLS.
|
||||
/// @param prefix is the used as the prefix for MediaPlaylist URIs. May be
|
||||
/// empty for relative URI from the playlist.
|
||||
/// @param key_uri defines the key uri for "identity" and
|
||||
/// "com.apple.streamingkeydelivery" key formats. Ignored if the
|
||||
/// playlist is not encrypted or not using the above key formats.
|
||||
/// @param output_dir is the output directory of the playlists. May be empty
|
||||
/// to write to current directory.
|
||||
/// @param master_playlist_name is the name of the master playlist.
|
||||
SimpleHlsNotifier(HlsPlaylistType playlist_type,
|
||||
double time_shift_buffer_depth,
|
||||
const std::string& prefix,
|
||||
const std::string& key_uri,
|
||||
const std::string& output_dir,
|
||||
const std::string& master_playlist_name);
|
||||
~SimpleHlsNotifier() override;
|
||||
|
@ -88,6 +92,7 @@ class SimpleHlsNotifier : public HlsNotifier {
|
|||
|
||||
const double time_shift_buffer_depth_ = 0;
|
||||
const std::string prefix_;
|
||||
const std::string key_uri_;
|
||||
const std::string output_dir_;
|
||||
uint32_t target_duration_ = 0;
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ using ::testing::_;
|
|||
|
||||
namespace {
|
||||
const char kMasterPlaylistName[] = "master.m3u8";
|
||||
const char kEmptyKeyUri[] = "";
|
||||
const char kFairplayKeyUri[] = "skd://www.license.com/getkey?key_id=testing";
|
||||
const char kIdentityKeyUri[] = "https://www.license.com/getkey?key_id=testing";
|
||||
const HlsPlaylistType kVodPlaylist = HlsPlaylistType::kVod;
|
||||
const HlsPlaylistType kLivePlaylist = HlsPlaylistType::kLive;
|
||||
|
||||
|
@ -139,7 +142,8 @@ class SimpleHlsNotifierTest : public ::testing::Test {
|
|||
|
||||
TEST_F(SimpleHlsNotifierTest, Init) {
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
EXPECT_TRUE(notifier.Init());
|
||||
}
|
||||
|
||||
|
@ -171,7 +175,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
|
|||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
@ -211,7 +216,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
|
|||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
@ -250,7 +256,8 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
|
|||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kEmptyPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kEmptyPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
@ -271,7 +278,7 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
|
|||
TEST_F(SimpleHlsNotifierTest, RebaseAbsoluteSegmentPrefixAndOutputDirMatch) {
|
||||
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
||||
SimpleHlsNotifier test_notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAbsoluteOutputDir,
|
||||
kTestPrefix, kEmptyKeyUri, kAbsoluteOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||
|
@ -313,7 +320,7 @@ TEST_F(SimpleHlsNotifierTest,
|
|||
RebaseAbsoluteSegmentCompletelyDifferentDirectory) {
|
||||
const char kAbsoluteOutputDir[] = "/tmp/something/";
|
||||
SimpleHlsNotifier test_notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAbsoluteOutputDir,
|
||||
kTestPrefix, kEmptyKeyUri, kAbsoluteOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||
|
@ -350,7 +357,8 @@ TEST_F(SimpleHlsNotifierTest,
|
|||
|
||||
TEST_F(SimpleHlsNotifierTest, Flush) {
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||
new MockMasterPlaylist());
|
||||
EXPECT_CALL(*mock_master_playlist,
|
||||
|
@ -379,7 +387,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewStream) {
|
|||
.WillOnce(Return(mock_media_playlist));
|
||||
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
@ -422,7 +431,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
.WillOnce(Return(kLongestSegmentDuration));
|
||||
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
MockMasterPlaylist* mock_master_playlist_ptr = mock_master_playlist.get();
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
@ -454,7 +464,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyNewSegmentWithoutStreamsRegistered) {
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
EXPECT_TRUE(notifier.Init());
|
||||
EXPECT_FALSE(notifier.NotifyNewSegment(1u, "anything", 0u, 0u, 0u, 0u));
|
||||
}
|
||||
|
@ -464,7 +475,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevine) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -526,7 +538,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -579,12 +592,13 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWidevineNoKeyidsInPssh) {
|
|||
widevine_system_id_, iv, pssh_box));
|
||||
}
|
||||
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentifyKey) {
|
||||
TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateIdentityKey) {
|
||||
// Pointer released by SimpleHlsNotifier.
|
||||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -613,7 +627,8 @@ TEST_F(SimpleHlsNotifierTest, WidevineMultipleKeyIdsNoContentIdInPssh) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -690,7 +705,8 @@ TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kIdentityKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -698,16 +714,11 @@ TEST_F(SimpleHlsNotifierTest, EncryptionScheme) {
|
|||
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::kSampleAesCenc,
|
||||
StrEq("data:text/plain;base64," + expected_key_uri_base64), StrEq(""),
|
||||
StrEq("0x45454545454545454545454545454545"), StrEq("identity"), _));
|
||||
EXPECT_CALL(*mock_media_playlist,
|
||||
AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAesCenc,
|
||||
StrEq(kIdentityKeyUri), StrEq(""),
|
||||
StrEq("0x45454545454545454545454545454545"),
|
||||
StrEq("identity"), _));
|
||||
EXPECT_TRUE(notifier.NotifyEncryptionUpdate(
|
||||
stream_id, key_id, common_system_id_, iv, dummy_pssh_data));
|
||||
}
|
||||
|
@ -719,23 +730,18 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateFairplay) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kLivePlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kLivePlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kFairplayKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
const std::vector<uint8_t> key_id(16, 0x12);
|
||||
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("skd://" + expected_key_uri_base64),
|
||||
StrEq(""),
|
||||
StrEq(""),
|
||||
StrEq("com.apple.streamingkeydelivery"), StrEq("1")));
|
||||
AddEncryptionInfo(MediaPlaylist::EncryptionMethod::kSampleAes,
|
||||
StrEq(kFairplayKeyUri), StrEq(""), StrEq(""),
|
||||
StrEq("com.apple.streamingkeydelivery"), StrEq("1")));
|
||||
EXPECT_TRUE(notifier.NotifyEncryptionUpdate(
|
||||
stream_id, key_id, fairplay_system_id_, std::vector<uint8_t>(),
|
||||
dummy_pssh_data));
|
||||
|
@ -747,7 +753,8 @@ TEST_F(SimpleHlsNotifierTest, WidevineCencEncryptionScheme) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kCencProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -795,7 +802,8 @@ TEST_F(SimpleHlsNotifierTest, WidevineNotifyEncryptionUpdateEmptyIv) {
|
|||
MockMediaPlaylist* mock_media_playlist =
|
||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
const uint32_t stream_id =
|
||||
SetupStream(kSampleAesProtectionScheme, mock_media_playlist, ¬ifier);
|
||||
|
||||
|
@ -862,7 +870,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyEncryptionUpdateWithoutStreamsRegistered) {
|
|||
std::vector<uint8_t> pssh_data;
|
||||
std::vector<uint8_t> key_id;
|
||||
SimpleHlsNotifier notifier(kVodPlaylist, kTestTimeShiftBufferDepth,
|
||||
kTestPrefix, kAnyOutputDir, kMasterPlaylistName);
|
||||
kTestPrefix, kEmptyKeyUri, kAnyOutputDir,
|
||||
kMasterPlaylistName);
|
||||
EXPECT_TRUE(notifier.Init());
|
||||
EXPECT_FALSE(
|
||||
notifier.NotifyEncryptionUpdate(1238u, key_id, system_id, iv, pssh_data));
|
||||
|
@ -921,9 +930,8 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
|||
.AsUTF8Unsafe())))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
SimpleHlsNotifier notifier(GetParam(),
|
||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
||||
kAnyOutputDir, kMasterPlaylistName);
|
||||
SimpleHlsNotifier notifier(GetParam(), kTestTimeShiftBufferDepth, kTestPrefix,
|
||||
kEmptyKeyUri, kAnyOutputDir, kMasterPlaylistName);
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
EXPECT_TRUE(notifier.Init());
|
||||
|
@ -967,9 +975,8 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
|||
*mock_master_playlist,
|
||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist2)));
|
||||
|
||||
SimpleHlsNotifier notifier(GetParam(),
|
||||
kTestTimeShiftBufferDepth, kTestPrefix,
|
||||
kAnyOutputDir, kMasterPlaylistName);
|
||||
SimpleHlsNotifier notifier(GetParam(), kTestTimeShiftBufferDepth, kTestPrefix,
|
||||
kEmptyKeyUri, kAnyOutputDir, kMasterPlaylistName);
|
||||
MockMasterPlaylist* mock_master_playlist_ptr = mock_master_playlist.get();
|
||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||
InjectMediaPlaylistFactory(std::move(factory), ¬ifier);
|
||||
|
|
|
@ -31,6 +31,10 @@ struct HlsParams {
|
|||
/// Defines the live window, or the guaranteed duration of the time shifting
|
||||
/// buffer for 'live' playlists.
|
||||
double time_shift_buffer_depth = 0;
|
||||
/// Defines the key uri for "identity" and "com.apple.streamingkeydelivery"
|
||||
/// key formats. Ignored if the playlist is not encrypted or not using the
|
||||
/// above key formats.
|
||||
std::string key_uri;
|
||||
};
|
||||
|
||||
} // namespace shaka
|
||||
|
|
|
@ -810,7 +810,7 @@ Status Packager::Initialize(
|
|||
|
||||
internal->hls_notifier.reset(new hls::SimpleHlsNotifier(
|
||||
hls_params.playlist_type, hls_params.time_shift_buffer_depth,
|
||||
hls_params.base_url,
|
||||
hls_params.base_url, hls_params.key_uri,
|
||||
master_playlist_path.DirName().AsEndingWithSeparator().AsUTF8Unsafe(),
|
||||
master_playlist_name.AsUTF8Unsafe()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue