Refactor MasterPlaylist::WriteMasterPlaylist
Change-Id: Ida7453761748087cd13aab640c400381696578e1
This commit is contained in:
parent
b647c6731c
commit
04577b9638
|
@ -25,6 +25,14 @@ const char* kDefaultAudioGroupId = "default-audio-group";
|
||||||
const char* kDefaultSubtitleGroupId = "default-text-group";
|
const char* kDefaultSubtitleGroupId = "default-text-group";
|
||||||
const char* kUnexpectedGroupId = "unexpected-group";
|
const char* kUnexpectedGroupId = "unexpected-group";
|
||||||
|
|
||||||
|
void AppendVersionString(std::string* content) {
|
||||||
|
const std::string version = GetPackagerVersion();
|
||||||
|
if (version.empty())
|
||||||
|
return;
|
||||||
|
base::StringAppendF(content, "## Generated with %s version %s\n",
|
||||||
|
GetPackagerProjectUrl().c_str(), version.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
struct Variant {
|
struct Variant {
|
||||||
std::string audio_codec;
|
std::string audio_codec;
|
||||||
const std::string* audio_group_id = nullptr;
|
const std::string* audio_group_id = nullptr;
|
||||||
|
@ -271,6 +279,47 @@ void BuildMediaTags(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppendPlaylists(const std::string& default_language,
|
||||||
|
const std::string& base_url,
|
||||||
|
const std::list<MediaPlaylist*>& playlists,
|
||||||
|
std::string* content) {
|
||||||
|
std::map<std::string, std::list<const MediaPlaylist*>> audio_playlist_groups;
|
||||||
|
std::map<std::string, std::list<const MediaPlaylist*>>
|
||||||
|
subtitle_playlist_groups;
|
||||||
|
std::list<const MediaPlaylist*> video_playlists;
|
||||||
|
std::list<const MediaPlaylist*> iframe_playlists;
|
||||||
|
for (const MediaPlaylist* playlist : playlists) {
|
||||||
|
switch (playlist->stream_type()) {
|
||||||
|
case MediaPlaylist::MediaPlaylistStreamType::kAudio:
|
||||||
|
audio_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
|
||||||
|
break;
|
||||||
|
case MediaPlaylist::MediaPlaylistStreamType::kVideo:
|
||||||
|
video_playlists.push_back(playlist);
|
||||||
|
break;
|
||||||
|
case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
|
||||||
|
subtitle_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NOTIMPLEMENTED() << static_cast<int>(playlist->stream_type())
|
||||||
|
<< " not handled.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildMediaTags(audio_playlist_groups, default_language, base_url, content);
|
||||||
|
BuildMediaTags(subtitle_playlist_groups, default_language, base_url, content);
|
||||||
|
|
||||||
|
std::list<Variant> variants =
|
||||||
|
BuildVariants(audio_playlist_groups, subtitle_playlist_groups);
|
||||||
|
for (const auto& playlist : video_playlists) {
|
||||||
|
for (const auto& variant : variants) {
|
||||||
|
BuildVideoTag(*playlist, variant.audio_bitrate, variant.audio_codec,
|
||||||
|
variant.audio_group_id, variant.text_group_id, base_url,
|
||||||
|
content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MasterPlaylist::MasterPlaylist(const std::string& file_name,
|
MasterPlaylist::MasterPlaylist(const std::string& file_name,
|
||||||
|
@ -278,73 +327,13 @@ MasterPlaylist::MasterPlaylist(const std::string& file_name,
|
||||||
: file_name_(file_name), default_language_(default_language) {}
|
: file_name_(file_name), default_language_(default_language) {}
|
||||||
MasterPlaylist::~MasterPlaylist() {}
|
MasterPlaylist::~MasterPlaylist() {}
|
||||||
|
|
||||||
void MasterPlaylist::AddMediaPlaylist(MediaPlaylist* media_playlist) {
|
bool MasterPlaylist::WriteMasterPlaylist(
|
||||||
DCHECK(media_playlist);
|
const std::string& base_url,
|
||||||
switch (media_playlist->stream_type()) {
|
const std::string& output_dir,
|
||||||
case MediaPlaylist::MediaPlaylistStreamType::kAudio: {
|
const std::list<MediaPlaylist*>& playlists) {
|
||||||
std::string group_id = GetGroupId(*media_playlist);
|
std::string content = "#EXTM3U\n";
|
||||||
audio_playlist_groups_[group_id].push_back(media_playlist);
|
AppendVersionString(&content);
|
||||||
break;
|
AppendPlaylists(default_language_, base_url, playlists, &content);
|
||||||
}
|
|
||||||
case MediaPlaylist::MediaPlaylistStreamType::kVideo: {
|
|
||||||
video_playlists_.push_back(media_playlist);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MediaPlaylist::MediaPlaylistStreamType::kSubtitle: {
|
|
||||||
std::string group_id = GetGroupId(*media_playlist);
|
|
||||||
subtitle_playlist_groups_[group_id].push_back(media_playlist);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
NOTIMPLEMENTED() << static_cast<int>(media_playlist->stream_type())
|
|
||||||
<< " not handled.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Sometimes we need to iterate over all playlists, so keep a collection
|
|
||||||
// of all playlists to make iterating easier.
|
|
||||||
all_playlists_.push_back(media_playlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MasterPlaylist::WriteMasterPlaylist(const std::string& base_url,
|
|
||||||
const std::string& output_dir) {
|
|
||||||
// TODO(rkuroiwa): Handle audio only.
|
|
||||||
std::string audio_output;
|
|
||||||
std::string video_output;
|
|
||||||
std::string subtitle_output;
|
|
||||||
|
|
||||||
// Write out all the audio tags.
|
|
||||||
BuildMediaTags(audio_playlist_groups_, default_language_, base_url,
|
|
||||||
&audio_output);
|
|
||||||
|
|
||||||
// Write out all the text tags.
|
|
||||||
BuildMediaTags(subtitle_playlist_groups_, default_language_, base_url,
|
|
||||||
&subtitle_output);
|
|
||||||
|
|
||||||
std::list<Variant> variants =
|
|
||||||
BuildVariants(audio_playlist_groups_, subtitle_playlist_groups_);
|
|
||||||
|
|
||||||
// Write all the video tags out.
|
|
||||||
for (const auto& playlist : video_playlists_) {
|
|
||||||
for (const auto& variant : variants) {
|
|
||||||
BuildVideoTag(*playlist, variant.audio_bitrate, variant.audio_codec,
|
|
||||||
variant.audio_group_id, variant.text_group_id, base_url,
|
|
||||||
&video_output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string version = GetPackagerVersion();
|
|
||||||
std::string version_line;
|
|
||||||
if (!version.empty()) {
|
|
||||||
version_line =
|
|
||||||
base::StringPrintf("## Generated with %s version %s\n",
|
|
||||||
GetPackagerProjectUrl().c_str(), version.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string content = "";
|
|
||||||
base::StringAppendF(&content, "#EXTM3U\n%s%s%s%s", version_line.c_str(),
|
|
||||||
audio_output.c_str(), subtitle_output.c_str(),
|
|
||||||
video_output.c_str());
|
|
||||||
|
|
||||||
// Skip if the playlist is already written.
|
// Skip if the playlist is already written.
|
||||||
if (content == written_playlist_)
|
if (content == written_playlist_)
|
||||||
|
|
|
@ -8,11 +8,8 @@
|
||||||
#define PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
|
#define PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "packager/base/macros.h"
|
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace hls {
|
namespace hls {
|
||||||
|
|
||||||
|
@ -29,11 +26,6 @@ class MasterPlaylist {
|
||||||
const std::string& default_language);
|
const std::string& default_language);
|
||||||
virtual ~MasterPlaylist();
|
virtual ~MasterPlaylist();
|
||||||
|
|
||||||
/// @param media_playlist is a MediaPlaylist that should get added to this
|
|
||||||
/// master playlist. Ownership does not transfer.
|
|
||||||
/// @return true on success, false otherwise.
|
|
||||||
virtual void AddMediaPlaylist(MediaPlaylist* media_playlist);
|
|
||||||
|
|
||||||
/// Writes Master Playlist to output_dir + <name of playlist>.
|
/// Writes Master Playlist to output_dir + <name of playlist>.
|
||||||
/// This assumes that @a base_url is used as the prefix for Media Playlists.
|
/// This assumes that @a base_url is used as the prefix for Media Playlists.
|
||||||
/// @param base_url is the prefix for the Media Playlist files. This should be
|
/// @param base_url is the prefix for the Media Playlist files. This should be
|
||||||
|
@ -44,23 +36,16 @@ class MasterPlaylist {
|
||||||
/// @return true if the playlist is updated successfully or there is no
|
/// @return true if the playlist is updated successfully or there is no
|
||||||
/// difference since the last write, false otherwise.
|
/// difference since the last write, false otherwise.
|
||||||
virtual bool WriteMasterPlaylist(const std::string& base_url,
|
virtual bool WriteMasterPlaylist(const std::string& base_url,
|
||||||
const std::string& output_dir);
|
const std::string& output_dir,
|
||||||
|
const std::list<MediaPlaylist*>& playlists);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MasterPlaylist(const MasterPlaylist&) = delete;
|
||||||
|
MasterPlaylist& operator=(const MasterPlaylist&) = delete;
|
||||||
|
|
||||||
std::string written_playlist_;
|
std::string written_playlist_;
|
||||||
const std::string file_name_;
|
const std::string file_name_;
|
||||||
const std::string default_language_;
|
const std::string default_language_;
|
||||||
std::list<MediaPlaylist*> all_playlists_;
|
|
||||||
std::list<const MediaPlaylist*> video_playlists_;
|
|
||||||
|
|
||||||
// The ID is the group name, and the value is the list of all media playlists
|
|
||||||
// in that group. Keep audio and subtitle separate as they are processed
|
|
||||||
// separately.
|
|
||||||
std::map<std::string, std::list<const MediaPlaylist*>> audio_playlist_groups_;
|
|
||||||
std::map<std::string, std::list<const MediaPlaylist*>>
|
|
||||||
subtitle_playlist_groups_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MasterPlaylist);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace hls
|
} // namespace hls
|
||||||
|
|
|
@ -117,21 +117,15 @@ class MasterPlaylistTest : public ::testing::Test {
|
||||||
std::string master_playlist_path_;
|
std::string master_playlist_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(MasterPlaylistTest, AddMediaPlaylist) {
|
|
||||||
MockMediaPlaylist mock_playlist(kVodPlaylist, "playlist1.m3u8", "somename",
|
|
||||||
"somegroupid");
|
|
||||||
master_playlist_.AddMediaPlaylist(&mock_playlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(MasterPlaylistTest, WriteMasterPlaylistOneVideo) {
|
TEST_F(MasterPlaylistTest, WriteMasterPlaylistOneVideo) {
|
||||||
const uint64_t kBitRate = 435889;
|
const uint64_t kBitRate = 435889;
|
||||||
|
|
||||||
std::unique_ptr<MockMediaPlaylist> mock_playlist =
|
std::unique_ptr<MockMediaPlaylist> mock_playlist =
|
||||||
CreateVideoPlaylist("media1.m3u8", "avc1", kBitRate);
|
CreateVideoPlaylist("media1.m3u8", "avc1", kBitRate);
|
||||||
master_playlist_.AddMediaPlaylist(mock_playlist.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://myplaylistdomain.com/";
|
const char kBaseUrl[] = "http://myplaylistdomain.com/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_,
|
||||||
|
{mock_playlist.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -159,27 +153,26 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndAudio) {
|
||||||
// First video, sd.m3u8.
|
// First video, sd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> sd_video_playlist =
|
std::unique_ptr<MockMediaPlaylist> sd_video_playlist =
|
||||||
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", kVideo1BitRate);
|
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", kVideo1BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(sd_video_playlist.get());
|
|
||||||
|
|
||||||
// Second video, hd.m3u8.
|
// Second video, hd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> hd_video_playlist =
|
std::unique_ptr<MockMediaPlaylist> hd_video_playlist =
|
||||||
CreateVideoPlaylist("hd.m3u8", "hdvideocodec", kVideo2BitRate);
|
CreateVideoPlaylist("hd.m3u8", "hdvideocodec", kVideo2BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(hd_video_playlist.get());
|
|
||||||
|
|
||||||
// First audio, english.m3u8.
|
// First audio, english.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> english_playlist =
|
std::unique_ptr<MockMediaPlaylist> english_playlist =
|
||||||
CreateAudioPlaylist("eng.m3u8", "english", "audiogroup", "audiocodec",
|
CreateAudioPlaylist("eng.m3u8", "english", "audiogroup", "audiocodec",
|
||||||
"en", kAudio1Channels, kAudio1BitRate);
|
"en", kAudio1Channels, kAudio1BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(english_playlist.get());
|
|
||||||
|
|
||||||
// Second audio, spanish.m3u8.
|
// Second audio, spanish.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> spanish_playlist =
|
std::unique_ptr<MockMediaPlaylist> spanish_playlist =
|
||||||
CreateAudioPlaylist("spa.m3u8", "espanol", "audiogroup", "audiocodec",
|
CreateAudioPlaylist("spa.m3u8", "espanol", "audiogroup", "audiocodec",
|
||||||
"es", kAudio2Channels, kAudio2BitRate);
|
"es", kAudio2Channels, kAudio2BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(spanish_playlist.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://playlists.org/";
|
const char kBaseUrl[] = "http://playlists.org/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_,
|
||||||
|
{sd_video_playlist.get(), hd_video_playlist.get(), english_playlist.get(),
|
||||||
|
spanish_playlist.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -216,22 +209,21 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistMultipleAudioGroups) {
|
||||||
// First video, sd.m3u8.
|
// First video, sd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video_playlist =
|
std::unique_ptr<MockMediaPlaylist> video_playlist =
|
||||||
CreateVideoPlaylist("video.m3u8", "videocodec", kVideoBitRate);
|
CreateVideoPlaylist("video.m3u8", "videocodec", kVideoBitRate);
|
||||||
master_playlist_.AddMediaPlaylist(video_playlist.get());
|
|
||||||
|
|
||||||
// First audio, eng_lo.m3u8.
|
// First audio, eng_lo.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> eng_lo_playlist = CreateAudioPlaylist(
|
std::unique_ptr<MockMediaPlaylist> eng_lo_playlist = CreateAudioPlaylist(
|
||||||
"eng_lo.m3u8", "english_lo", "audio_lo", "audiocodec_lo", "en",
|
"eng_lo.m3u8", "english_lo", "audio_lo", "audiocodec_lo", "en",
|
||||||
kAudio1Channels, kAudio1BitRate);
|
kAudio1Channels, kAudio1BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(eng_lo_playlist.get());
|
|
||||||
|
|
||||||
// Second audio, eng_hi.m3u8.
|
// Second audio, eng_hi.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> eng_hi_playlist = CreateAudioPlaylist(
|
std::unique_ptr<MockMediaPlaylist> eng_hi_playlist = CreateAudioPlaylist(
|
||||||
"eng_hi.m3u8", "english_hi", "audio_hi", "audiocodec_hi", "en",
|
"eng_hi.m3u8", "english_hi", "audio_hi", "audiocodec_hi", "en",
|
||||||
kAudio2Channels, kAudio2BitRate);
|
kAudio2Channels, kAudio2BitRate);
|
||||||
master_playlist_.AddMediaPlaylist(eng_hi_playlist.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://anydomain.com/";
|
const char kBaseUrl[] = "http://anydomain.com/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_,
|
||||||
|
{video_playlist.get(), eng_lo_playlist.get(), eng_hi_playlist.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -260,19 +252,18 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistSameAudioGroupSameLanguage) {
|
||||||
// First video, video.m3u8.
|
// First video, video.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video_playlist =
|
std::unique_ptr<MockMediaPlaylist> video_playlist =
|
||||||
CreateVideoPlaylist("video.m3u8", "videocodec", 300000);
|
CreateVideoPlaylist("video.m3u8", "videocodec", 300000);
|
||||||
master_playlist_.AddMediaPlaylist(video_playlist.get());
|
|
||||||
|
|
||||||
// First audio, eng_lo.m3u8.
|
// First audio, eng_lo.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> eng_lo_playlist = CreateAudioPlaylist(
|
std::unique_ptr<MockMediaPlaylist> eng_lo_playlist = CreateAudioPlaylist(
|
||||||
"eng_lo.m3u8", "english", "audio", "audiocodec", "en", 1, 50000);
|
"eng_lo.m3u8", "english", "audio", "audiocodec", "en", 1, 50000);
|
||||||
master_playlist_.AddMediaPlaylist(eng_lo_playlist.get());
|
|
||||||
|
|
||||||
std::unique_ptr<MockMediaPlaylist> eng_hi_playlist = CreateAudioPlaylist(
|
std::unique_ptr<MockMediaPlaylist> eng_hi_playlist = CreateAudioPlaylist(
|
||||||
"eng_hi.m3u8", "english", "audio", "audiocodec", "en", 8, 100000);
|
"eng_hi.m3u8", "english", "audio", "audiocodec", "en", 8, 100000);
|
||||||
master_playlist_.AddMediaPlaylist(eng_hi_playlist.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://anydomain.com/";
|
const char kBaseUrl[] = "http://anydomain.com/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_,
|
||||||
|
{video_playlist.get(), eng_lo_playlist.get(), eng_hi_playlist.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -297,25 +288,23 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideosAndTexts) {
|
||||||
// Video, sd.m3u8.
|
// Video, sd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video1 =
|
std::unique_ptr<MockMediaPlaylist> video1 =
|
||||||
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
||||||
master_playlist_.AddMediaPlaylist(video1.get());
|
|
||||||
|
|
||||||
// Video, hd.m3u8.
|
// Video, hd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video2 =
|
std::unique_ptr<MockMediaPlaylist> video2 =
|
||||||
CreateVideoPlaylist("hd.m3u8", "sdvideocodec", 600000);
|
CreateVideoPlaylist("hd.m3u8", "sdvideocodec", 600000);
|
||||||
master_playlist_.AddMediaPlaylist(video2.get());
|
|
||||||
|
|
||||||
// Text, eng.m3u8.
|
// Text, eng.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> text_eng =
|
std::unique_ptr<MockMediaPlaylist> text_eng =
|
||||||
MakeText("eng.m3u8", "english", "textgroup", "en");
|
MakeText("eng.m3u8", "english", "textgroup", "en");
|
||||||
master_playlist_.AddMediaPlaylist(text_eng.get());
|
|
||||||
|
|
||||||
// Text, fr.m3u8.
|
// Text, fr.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> text_fr =
|
std::unique_ptr<MockMediaPlaylist> text_fr =
|
||||||
MakeText("fr.m3u8", "french", "textgroup", "fr");
|
MakeText("fr.m3u8", "french", "textgroup", "fr");
|
||||||
master_playlist_.AddMediaPlaylist(text_fr.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://playlists.org/";
|
const char kBaseUrl[] = "http://playlists.org/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_,
|
||||||
|
{video1.get(), video2.get(), text_eng.get(), text_fr.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -343,20 +332,19 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndTextGroups) {
|
||||||
// Video, sd.m3u8.
|
// Video, sd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video =
|
std::unique_ptr<MockMediaPlaylist> video =
|
||||||
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
||||||
master_playlist_.AddMediaPlaylist(video.get());
|
|
||||||
|
|
||||||
// Text, eng.m3u8.
|
// Text, eng.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> text_eng =
|
std::unique_ptr<MockMediaPlaylist> text_eng =
|
||||||
MakeText("eng.m3u8", "english", "en-text-group", "en");
|
MakeText("eng.m3u8", "english", "en-text-group", "en");
|
||||||
master_playlist_.AddMediaPlaylist(text_eng.get());
|
|
||||||
|
|
||||||
// Text, fr.m3u8.
|
// Text, fr.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> text_fr =
|
std::unique_ptr<MockMediaPlaylist> text_fr =
|
||||||
MakeText("fr.m3u8", "french", "fr-text-group", "fr");
|
MakeText("fr.m3u8", "french", "fr-text-group", "fr");
|
||||||
master_playlist_.AddMediaPlaylist(text_fr.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://playlists.org/";
|
const char kBaseUrl[] = "http://playlists.org/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_,
|
||||||
|
{video.get(), text_eng.get(), text_fr.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -385,20 +373,18 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndAudioAndText) {
|
||||||
// Video, sd.m3u8.
|
// Video, sd.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> video =
|
std::unique_ptr<MockMediaPlaylist> video =
|
||||||
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
CreateVideoPlaylist("sd.m3u8", "sdvideocodec", 300000);
|
||||||
master_playlist_.AddMediaPlaylist(video.get());
|
|
||||||
|
|
||||||
// Audio, english.m3u8.
|
// Audio, english.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> audio = CreateAudioPlaylist(
|
std::unique_ptr<MockMediaPlaylist> audio = CreateAudioPlaylist(
|
||||||
"eng.m3u8", "english", "audiogroup", "audiocodec", "en", 2, 50000);
|
"eng.m3u8", "english", "audiogroup", "audiocodec", "en", 2, 50000);
|
||||||
master_playlist_.AddMediaPlaylist(audio.get());
|
|
||||||
|
|
||||||
// Text, english.m3u8.
|
// Text, english.m3u8.
|
||||||
std::unique_ptr<MockMediaPlaylist> text =
|
std::unique_ptr<MockMediaPlaylist> text =
|
||||||
MakeText("eng.m3u8", "english", "textgroup", "en");
|
MakeText("eng.m3u8", "english", "textgroup", "en");
|
||||||
master_playlist_.AddMediaPlaylist(text.get());
|
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://playlists.org/";
|
const char kBaseUrl[] = "http://playlists.org/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(
|
||||||
|
kBaseUrl, test_output_dir_, {video.get(), audio.get(), text.get()}));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
@ -442,12 +428,14 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVidesAudiosTextsDifferentGroups) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add all the media playlists to the master playlist.
|
// Add all the media playlists to the master playlist.
|
||||||
|
std::list<MediaPlaylist*> media_playlist_list;
|
||||||
for (const auto& media_playlist : media_playlists) {
|
for (const auto& media_playlist : media_playlists) {
|
||||||
master_playlist_.AddMediaPlaylist(media_playlist.get());
|
media_playlist_list.push_back(media_playlist.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char kBaseUrl[] = "http://playlists.org/";
|
const char kBaseUrl[] = "http://playlists.org/";
|
||||||
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_));
|
EXPECT_TRUE(master_playlist_.WriteMasterPlaylist(kBaseUrl, test_output_dir_,
|
||||||
|
media_playlist_list));
|
||||||
|
|
||||||
std::string actual;
|
std::string actual;
|
||||||
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
ASSERT_TRUE(File::ReadFileToString(master_playlist_path_.c_str(), &actual));
|
||||||
|
|
|
@ -312,7 +312,7 @@ bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
|
||||||
|
|
||||||
*stream_id = sequence_number_.GetNext();
|
*stream_id = sequence_number_.GetNext();
|
||||||
base::AutoLock auto_lock(lock_);
|
base::AutoLock auto_lock(lock_);
|
||||||
master_playlist_->AddMediaPlaylist(media_playlist.get());
|
media_playlists_.push_back(media_playlist.get());
|
||||||
stream_map_[*stream_id].reset(
|
stream_map_[*stream_id].reset(
|
||||||
new StreamEntry{std::move(media_playlist), encryption_method});
|
new StreamEntry{std::move(media_playlist), encryption_method});
|
||||||
return true;
|
return true;
|
||||||
|
@ -348,14 +348,14 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
||||||
// Update the playlists when there is new segments in live mode.
|
// Update the playlists when there is new segments in live mode.
|
||||||
if (playlist_type() == HlsPlaylistType::kLive ||
|
if (playlist_type() == HlsPlaylistType::kLive ||
|
||||||
playlist_type() == HlsPlaylistType::kEvent) {
|
playlist_type() == HlsPlaylistType::kEvent) {
|
||||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_)) {
|
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||||
|
media_playlists_)) {
|
||||||
LOG(ERROR) << "Failed to write master playlist.";
|
LOG(ERROR) << "Failed to write master playlist.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Update all playlists if target duration is updated.
|
// Update all playlists if target duration is updated.
|
||||||
if (target_duration_updated) {
|
if (target_duration_updated) {
|
||||||
for (auto& streams : stream_map_) {
|
for (MediaPlaylist* playlist : media_playlists_) {
|
||||||
MediaPlaylist* playlist = streams.second->media_playlist.get();
|
|
||||||
playlist->SetTargetDuration(target_duration_);
|
playlist->SetTargetDuration(target_duration_);
|
||||||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
if (!WriteMediaPlaylist(output_dir_, playlist))
|
||||||
return false;
|
return false;
|
||||||
|
@ -461,12 +461,12 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
||||||
|
|
||||||
bool SimpleHlsNotifier::Flush() {
|
bool SimpleHlsNotifier::Flush() {
|
||||||
base::AutoLock auto_lock(lock_);
|
base::AutoLock auto_lock(lock_);
|
||||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_)) {
|
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||||
|
media_playlists_)) {
|
||||||
LOG(ERROR) << "Failed to write master playlist.";
|
LOG(ERROR) << "Failed to write master playlist.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (auto& streams : stream_map_) {
|
for (MediaPlaylist* playlist : media_playlists_) {
|
||||||
MediaPlaylist* playlist = streams.second->media_playlist.get();
|
|
||||||
playlist->SetTargetDuration(target_duration_);
|
playlist->SetTargetDuration(target_duration_);
|
||||||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
if (!WriteMediaPlaylist(output_dir_, playlist))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#ifndef PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
|
#ifndef PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
|
||||||
#define PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
|
#define PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -89,6 +90,7 @@ class SimpleHlsNotifier : public HlsNotifier {
|
||||||
|
|
||||||
// Maps to unique_ptr because StreamEntry also holds unique_ptr
|
// Maps to unique_ptr because StreamEntry also holds unique_ptr
|
||||||
std::map<uint32_t, std::unique_ptr<StreamEntry>> stream_map_;
|
std::map<uint32_t, std::unique_ptr<StreamEntry>> stream_map_;
|
||||||
|
std::list<MediaPlaylist*> media_playlists_;
|
||||||
|
|
||||||
base::AtomicSequenceNumber sequence_number_;
|
base::AtomicSequenceNumber sequence_number_;
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,14 @@
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace hls {
|
namespace hls {
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::ElementsAre;
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
using ::testing::InSequence;
|
using ::testing::InSequence;
|
||||||
using ::testing::Mock;
|
using ::testing::Mock;
|
||||||
using ::testing::Property;
|
using ::testing::Property;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::StrEq;
|
using ::testing::StrEq;
|
||||||
using ::testing::_;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char kMasterPlaylistName[] = "master.m3u8";
|
const char kMasterPlaylistName[] = "master.m3u8";
|
||||||
|
@ -43,9 +44,10 @@ class MockMasterPlaylist : public MasterPlaylist {
|
||||||
MockMasterPlaylist()
|
MockMasterPlaylist()
|
||||||
: MasterPlaylist(kMasterPlaylistName, kDefaultLanguage) {}
|
: MasterPlaylist(kMasterPlaylistName, kDefaultLanguage) {}
|
||||||
|
|
||||||
MOCK_METHOD1(AddMediaPlaylist, void(MediaPlaylist* media_playlist));
|
MOCK_METHOD3(WriteMasterPlaylist,
|
||||||
MOCK_METHOD2(WriteMasterPlaylist,
|
bool(const std::string& prefix,
|
||||||
bool(const std::string& prefix, const std::string& output_dir));
|
const std::string& output_dir,
|
||||||
|
const std::list<MediaPlaylist*>& playlists));
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockMediaPlaylistFactory : public MediaPlaylistFactory {
|
class MockMediaPlaylistFactory : public MediaPlaylistFactory {
|
||||||
|
@ -128,9 +130,6 @@ class SimpleHlsNotifierTest : public ::testing::Test {
|
||||||
std::unique_ptr<MockMediaPlaylistFactory> factory(
|
std::unique_ptr<MockMediaPlaylistFactory> factory(
|
||||||
new MockMediaPlaylistFactory());
|
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(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
@ -167,7 +166,6 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrl) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_media_playlist,
|
EXPECT_CALL(*mock_media_playlist,
|
||||||
SetMediaInfo(Property(&MediaInfo::init_segment_name, StrEq(""))))
|
SetMediaInfo(Property(&MediaInfo::init_segment_name, StrEq(""))))
|
||||||
|
@ -207,7 +205,6 @@ TEST_F(SimpleHlsNotifierTest, RebaseInitSegmentUrl) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
// Verify that the common prefix is stripped in init segment.
|
// Verify that the common prefix is stripped in init segment.
|
||||||
EXPECT_CALL(
|
EXPECT_CALL(
|
||||||
|
@ -243,7 +240,6 @@ TEST_F(SimpleHlsNotifierTest, RebaseSegmentUrlRelativeToPlaylist) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "video/playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "video/playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
// Verify that the init segment URL is relative to playlist path.
|
// Verify that the init segment URL is relative to playlist path.
|
||||||
EXPECT_CALL(*mock_media_playlist,
|
EXPECT_CALL(*mock_media_playlist,
|
||||||
|
@ -292,7 +288,6 @@ TEST_F(SimpleHlsNotifierTest, RebaseAbsoluteSegmentPrefixAndOutputDirMatch) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
|
|
||||||
|
@ -334,7 +329,6 @@ TEST_F(SimpleHlsNotifierTest,
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*mock_media_playlist,
|
EXPECT_CALL(*mock_media_playlist,
|
||||||
|
@ -363,7 +357,7 @@ TEST_F(SimpleHlsNotifierTest, Flush) {
|
||||||
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
std::unique_ptr<MockMasterPlaylist> mock_master_playlist(
|
||||||
new MockMasterPlaylist());
|
new MockMasterPlaylist());
|
||||||
EXPECT_CALL(*mock_master_playlist,
|
EXPECT_CALL(*mock_master_playlist,
|
||||||
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir)))
|
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir), _))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
InjectMasterPlaylist(std::move(mock_master_playlist), ¬ifier);
|
||||||
EXPECT_TRUE(notifier.Init());
|
EXPECT_TRUE(notifier.Init());
|
||||||
|
@ -379,7 +373,6 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewStream) {
|
||||||
// Pointer released by SimpleHlsNotifier.
|
// Pointer released by SimpleHlsNotifier.
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
EXPECT_CALL(*mock_master_playlist, AddMediaPlaylist(mock_media_playlist));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
EXPECT_CALL(*factory, CreateMock(kVodPlaylist, Eq(kTestTimeShiftBufferDepth),
|
||||||
|
@ -409,9 +402,6 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(kVodPlaylist, "playlist.m3u8", "", "");
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
*mock_master_playlist,
|
|
||||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
|
||||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
EXPECT_CALL(*factory, CreateMock(_, _, _, _, _))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
@ -446,7 +436,8 @@ TEST_F(SimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
Mock::VerifyAndClearExpectations(mock_media_playlist);
|
Mock::VerifyAndClearExpectations(mock_media_playlist);
|
||||||
|
|
||||||
EXPECT_CALL(*mock_master_playlist_ptr,
|
EXPECT_CALL(*mock_master_playlist_ptr,
|
||||||
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir)))
|
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir),
|
||||||
|
ElementsAre(mock_media_playlist)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(*mock_media_playlist, SetTargetDuration(kTargetDuration))
|
EXPECT_CALL(*mock_media_playlist, SetTargetDuration(kTargetDuration))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
|
@ -908,9 +899,6 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
MockMediaPlaylist* mock_media_playlist =
|
MockMediaPlaylist* mock_media_playlist =
|
||||||
new MockMediaPlaylist(expected_playlist_type_, "playlist.m3u8", "", "");
|
new MockMediaPlaylist(expected_playlist_type_, "playlist.m3u8", "", "");
|
||||||
|
|
||||||
EXPECT_CALL(
|
|
||||||
*mock_master_playlist,
|
|
||||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist)));
|
|
||||||
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*factory, CreateMock(expected_playlist_type_, _, _, _, _))
|
EXPECT_CALL(*factory, CreateMock(expected_playlist_type_, _, _, _, _))
|
||||||
.WillOnce(Return(mock_media_playlist));
|
.WillOnce(Return(mock_media_playlist));
|
||||||
|
@ -929,7 +917,7 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegment) {
|
||||||
.WillOnce(Return(kLongestSegmentDuration));
|
.WillOnce(Return(kLongestSegmentDuration));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_master_playlist,
|
EXPECT_CALL(*mock_master_playlist,
|
||||||
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir)))
|
WriteMasterPlaylist(StrEq(kTestPrefix), StrEq(kAnyOutputDir), _))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(*mock_media_playlist, SetTargetDuration(kTargetDuration))
|
EXPECT_CALL(*mock_media_playlist, SetTargetDuration(kTargetDuration))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
|
@ -975,15 +963,9 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
||||||
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist1.m3u8"), _, _))
|
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist1.m3u8"), _, _))
|
||||||
.WillOnce(Return(mock_media_playlist1));
|
.WillOnce(Return(mock_media_playlist1));
|
||||||
EXPECT_CALL(*mock_media_playlist1, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist1, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(
|
|
||||||
*mock_master_playlist,
|
|
||||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist1)));
|
|
||||||
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist2.m3u8"), _, _))
|
EXPECT_CALL(*factory, CreateMock(_, _, StrEq("playlist2.m3u8"), _, _))
|
||||||
.WillOnce(Return(mock_media_playlist2));
|
.WillOnce(Return(mock_media_playlist2));
|
||||||
EXPECT_CALL(*mock_media_playlist2, SetMediaInfo(_)).WillOnce(Return(true));
|
EXPECT_CALL(*mock_media_playlist2, SetMediaInfo(_)).WillOnce(Return(true));
|
||||||
EXPECT_CALL(
|
|
||||||
*mock_master_playlist,
|
|
||||||
AddMediaPlaylist(static_cast<MediaPlaylist*>(mock_media_playlist2)));
|
|
||||||
|
|
||||||
hls_params_.playlist_type = GetParam();
|
hls_params_.playlist_type = GetParam();
|
||||||
SimpleHlsNotifier notifier(hls_params_);
|
SimpleHlsNotifier notifier(hls_params_);
|
||||||
|
@ -1006,7 +988,10 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
||||||
EXPECT_CALL(*mock_media_playlist1, GetLongestSegmentDuration())
|
EXPECT_CALL(*mock_media_playlist1, GetLongestSegmentDuration())
|
||||||
.WillOnce(Return(kLongestSegmentDuration));
|
.WillOnce(Return(kLongestSegmentDuration));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_master_playlist_ptr, WriteMasterPlaylist(_, _))
|
EXPECT_CALL(
|
||||||
|
*mock_master_playlist_ptr,
|
||||||
|
WriteMasterPlaylist(
|
||||||
|
_, _, ElementsAre(mock_media_playlist1, mock_media_playlist2)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
// SetTargetDuration and update all playlists as target duration is updated.
|
// SetTargetDuration and update all playlists as target duration is updated.
|
||||||
EXPECT_CALL(*mock_media_playlist1, SetTargetDuration(kTargetDuration))
|
EXPECT_CALL(*mock_media_playlist1, SetTargetDuration(kTargetDuration))
|
||||||
|
@ -1031,7 +1016,7 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
||||||
EXPECT_CALL(*mock_media_playlist2, AddSegment(_, _, _, _, _)).Times(1);
|
EXPECT_CALL(*mock_media_playlist2, AddSegment(_, _, _, _, _)).Times(1);
|
||||||
EXPECT_CALL(*mock_media_playlist2, GetLongestSegmentDuration())
|
EXPECT_CALL(*mock_media_playlist2, GetLongestSegmentDuration())
|
||||||
.WillOnce(Return(kLongestSegmentDuration));
|
.WillOnce(Return(kLongestSegmentDuration));
|
||||||
EXPECT_CALL(*mock_master_playlist_ptr, WriteMasterPlaylist(_, _))
|
EXPECT_CALL(*mock_master_playlist_ptr, WriteMasterPlaylist(_, _, _))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
// Not updating other playlists as target duration does not change.
|
// Not updating other playlists as target duration does not change.
|
||||||
EXPECT_CALL(*mock_media_playlist2,
|
EXPECT_CALL(*mock_media_playlist2,
|
||||||
|
|
Loading…
Reference in New Issue