Bug fixes and clean-ups for I-Frame playlists
- Add empty lines between different types of renditions to improve readability. - Group variants with the same audio/text group together, as it is where the Adaptation occurs. - Write master playlist after writing media playlists. This makes more sense and it is also necessary to have the bandwidth of the last iframe playist segment correctly computed. - For fMP4, I-Frame segment must include the 'moof' header. - Fix a problem that hls_iframe_playlist_name is not passed to MuxerListenerFactory. Issue: #287 Change-Id: Icf37c5de1dc29f85ae3f419cbc3264d04ca491a4
This commit is contained in:
parent
1750357024
commit
8257eea804
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1242703,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video.m3u8
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1168277,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video.m3u8
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1217518,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video.m3u8
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1111340,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video.m3u8
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio/audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1105163,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video/video.m3u8
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-MEDIA:TYPE=AUDIO,URI="audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2"
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1174135,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group"
|
||||
video.m3u8
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#EXTM3U
|
||||
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>
|
||||
|
||||
#EXT-X-STREAM-INF:BANDWIDTH=1183948,CODECS="avc1.64001f",RESOLUTION=1024x436
|
||||
video.m3u8
|
||||
|
|
|
@ -325,21 +325,35 @@ void AppendPlaylists(const std::string& default_language,
|
|||
}
|
||||
}
|
||||
|
||||
if (!audio_playlist_groups.empty()) {
|
||||
content->append("\n");
|
||||
BuildMediaTags(audio_playlist_groups, default_language, base_url, content);
|
||||
BuildMediaTags(subtitle_playlist_groups, default_language, base_url, content);
|
||||
}
|
||||
|
||||
if (!subtitle_playlist_groups.empty()) {
|
||||
content->append("\n");
|
||||
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) {
|
||||
if (video_playlists.empty())
|
||||
break;
|
||||
content->append("\n");
|
||||
for (const auto& playlist : video_playlists) {
|
||||
BuildStreamInfTag(*playlist, variant, base_url, content);
|
||||
}
|
||||
}
|
||||
|
||||
if (!iframe_playlists.empty()) {
|
||||
content->append("\n");
|
||||
for (const auto& playlist : iframe_playlists) {
|
||||
// I-Frame playlists do not have variant. Just use the default.
|
||||
BuildStreamInfTag(*playlist, Variant(), base_url, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -143,6 +143,7 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistOneVideo) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=435889,CODECS=\"avc1\",RESOLUTION=800x600\n"
|
||||
"http://myplaylistdomain.com/media1.m3u8\n";
|
||||
|
||||
|
@ -166,6 +167,7 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistOneIframePlaylist) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=435889,CODECS=\"avc1\",RESOLUTION="
|
||||
"800x600,URI=\"http://myplaylistdomain.com/media1.m3u8\"\n";
|
||||
|
||||
|
@ -213,12 +215,14 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndAudio) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://playlists.org/eng.m3u8\","
|
||||
"GROUP-ID=\"audiogroup\",LANGUAGE=\"en\",NAME=\"english\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"2\"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://playlists.org/spa.m3u8\","
|
||||
"GROUP-ID=\"audiogroup\",LANGUAGE=\"es\",NAME=\"espanol\","
|
||||
"AUTOSELECT=YES,CHANNELS=\"5\"\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=360000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audiogroup\"\n"
|
||||
"http://playlists.org/sd.m3u8\n"
|
||||
|
@ -264,15 +268,18 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistMultipleAudioGroups) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://anydomain.com/eng_hi.m3u8\","
|
||||
"GROUP-ID=\"audio_hi\",LANGUAGE=\"en\",NAME=\"english_hi\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"8\"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://anydomain.com/eng_lo.m3u8\","
|
||||
"GROUP-ID=\"audio_lo\",LANGUAGE=\"en\",NAME=\"english_lo\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"1\"\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=400000,CODECS=\"videocodec,audiocodec_hi\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio_hi\"\n"
|
||||
"http://anydomain.com/video.m3u8\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"videocodec,audiocodec_lo\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio_lo\"\n"
|
||||
"http://anydomain.com/video.m3u8\n";
|
||||
|
@ -304,11 +311,13 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistSameAudioGroupSameLanguage) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://anydomain.com/eng_lo.m3u8\","
|
||||
"GROUP-ID=\"audio\",LANGUAGE=\"en\",NAME=\"english\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"1\"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://anydomain.com/eng_hi.m3u8\","
|
||||
"GROUP-ID=\"audio\",LANGUAGE=\"en\",NAME=\"english\",CHANNELS=\"8\"\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=400000,CODECS=\"videocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio\"\n"
|
||||
"http://anydomain.com/video.m3u8\n";
|
||||
|
@ -345,11 +354,13 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideosAndTexts) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/eng.m3u8\","
|
||||
"GROUP-ID=\"textgroup\",LANGUAGE=\"en\",NAME=\"english\",DEFAULT=YES,"
|
||||
"AUTOSELECT=YES\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/fr.m3u8\","
|
||||
"GROUP-ID=\"textgroup\",LANGUAGE=\"fr\",NAME=\"french\",AUTOSELECT=YES\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=300000,CODECS=\"sdvideocodec\","
|
||||
"RESOLUTION=800x600,SUBTITLES=\"textgroup\"\n"
|
||||
"http://playlists.org/sd.m3u8\n"
|
||||
|
@ -385,15 +396,18 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndTextGroups) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/eng.m3u8\","
|
||||
"GROUP-ID=\"en-text-group\",LANGUAGE=\"en\",NAME=\"english\",DEFAULT=YES,"
|
||||
"AUTOSELECT=YES\n"
|
||||
"GROUP-ID=\"en-text-group\",LANGUAGE=\"en\",NAME=\"english\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/fr.m3u8\","
|
||||
"GROUP-ID=\"fr-text-group\",LANGUAGE=\"fr\",NAME=\"french\",AUTOSELECT="
|
||||
"YES\n"
|
||||
"GROUP-ID=\"fr-text-group\",LANGUAGE=\"fr\",NAME=\"french\","
|
||||
"AUTOSELECT=YES\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=300000,CODECS=\"sdvideocodec\","
|
||||
"RESOLUTION=800x600,SUBTITLES=\"en-text-group\"\n"
|
||||
"http://playlists.org/sd.m3u8\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=300000,CODECS=\"sdvideocodec\","
|
||||
"RESOLUTION=800x600,SUBTITLES=\"fr-text-group\"\n"
|
||||
"http://playlists.org/sd.m3u8\n";
|
||||
|
@ -425,12 +439,15 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistVideoAndAudioAndText) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://playlists.org/eng.m3u8\","
|
||||
"GROUP-ID=\"audiogroup\",LANGUAGE=\"en\",NAME=\"english\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"2\"\n"
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/eng.m3u8\","
|
||||
"GROUP-ID=\"textgroup\",LANGUAGE=\"en\",NAME=\"english\",DEFAULT=YES,"
|
||||
"AUTOSELECT=YES\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audiogroup\",SUBTITLES=\"textgroup\"\n"
|
||||
"http://playlists.org/sd.m3u8\n";
|
||||
|
@ -481,58 +498,51 @@ TEST_F(MasterPlaylistTest, WriteMasterPlaylistMixedPlaylistsDifferentGroups) {
|
|||
"#EXTM3U\n"
|
||||
"## Generated with https://github.com/google/shaka-packager version "
|
||||
"test\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://playlists.org/audio-1.m3u8\","
|
||||
"GROUP-ID=\"audio-group-1\",LANGUAGE=\"en\",NAME=\"audio 1\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"2\"\n"
|
||||
|
||||
"#EXT-X-MEDIA:TYPE=AUDIO,URI=\"http://playlists.org/audio-2.m3u8\","
|
||||
"GROUP-ID=\"audio-group-2\",LANGUAGE=\"en\",NAME=\"audio 2\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"2\"\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/text-1.m3u8\","
|
||||
"GROUP-ID=\"text-group-1\",LANGUAGE=\"en\",NAME=\"text "
|
||||
"1\",DEFAULT=YES,AUTOSELECT=YES\n"
|
||||
|
||||
"GROUP-ID=\"text-group-1\",LANGUAGE=\"en\",NAME=\"text 1\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES\n"
|
||||
"#EXT-X-MEDIA:TYPE=SUBTITLES,URI=\"http://playlists.org/text-2.m3u8\","
|
||||
"GROUP-ID=\"text-group-2\",LANGUAGE=\"en\",NAME=\"text "
|
||||
"2\",DEFAULT=YES,AUTOSELECT=YES\n"
|
||||
|
||||
"GROUP-ID=\"text-group-2\",LANGUAGE=\"en\",NAME=\"text 2\","
|
||||
"DEFAULT=YES,AUTOSELECT=YES\n"
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-1\",SUBTITLES=\"text-group-1\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-1\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-1\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-1\",SUBTITLES=\"text-group-1\"\n"
|
||||
"http://playlists.org/video-2.m3u8\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-1\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-1\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-2.m3u8\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-1\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-1\"\n"
|
||||
"http://playlists.org/video-2.m3u8\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-1.m3u8\n"
|
||||
"#EXT-X-STREAM-INF:BANDWIDTH=350000,CODECS=\"sdvideocodec,audiocodec\","
|
||||
"RESOLUTION=800x600,AUDIO=\"audio-group-2\",SUBTITLES=\"text-group-2\"\n"
|
||||
"http://playlists.org/video-2.m3u8\n"
|
||||
|
||||
"\n"
|
||||
"#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=100000,CODECS=\"sdvideocodec\","
|
||||
"RESOLUTION=800x600,URI=\"http://playlists.org/iframe-1.m3u8\"\n"
|
||||
|
||||
"#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=100000,CODECS=\"sdvideocodec\","
|
||||
"RESOLUTION=800x600,URI=\"http://playlists.org/iframe-2.m3u8\"\n";
|
||||
|
||||
|
|
|
@ -348,11 +348,6 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
|||
// Update the playlists when there is new segments in live mode.
|
||||
if (playlist_type() == HlsPlaylistType::kLive ||
|
||||
playlist_type() == HlsPlaylistType::kEvent) {
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
}
|
||||
// Update all playlists if target duration is updated.
|
||||
if (target_duration_updated) {
|
||||
for (MediaPlaylist* playlist : media_playlists_) {
|
||||
|
@ -361,7 +356,13 @@ bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
return WriteMediaPlaylist(output_dir_, media_playlist.get());
|
||||
if (!WriteMediaPlaylist(output_dir_, media_playlist.get()))
|
||||
return false;
|
||||
}
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -461,16 +462,16 @@ bool SimpleHlsNotifier::NotifyEncryptionUpdate(
|
|||
|
||||
bool SimpleHlsNotifier::Flush() {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
}
|
||||
for (MediaPlaylist* playlist : media_playlists_) {
|
||||
playlist->SetTargetDuration(target_duration_);
|
||||
if (!WriteMediaPlaylist(output_dir_, playlist))
|
||||
return false;
|
||||
}
|
||||
if (!master_playlist_->WriteMasterPlaylist(prefix_, output_dir_,
|
||||
media_playlists_)) {
|
||||
LOG(ERROR) << "Failed to write master playlist.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -988,11 +988,6 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
|||
EXPECT_CALL(*mock_media_playlist1, GetLongestSegmentDuration())
|
||||
.WillOnce(Return(kLongestSegmentDuration));
|
||||
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist_ptr,
|
||||
WriteMasterPlaylist(
|
||||
_, _, ElementsAre(mock_media_playlist1, mock_media_playlist2)))
|
||||
.WillOnce(Return(true));
|
||||
// SetTargetDuration and update all playlists as target duration is updated.
|
||||
EXPECT_CALL(*mock_media_playlist1, SetTargetDuration(kTargetDuration))
|
||||
.Times(1);
|
||||
|
@ -1010,14 +1005,17 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
|||
.Append(base::FilePath::FromUTF8Unsafe("playlist2.m3u8"))
|
||||
.AsUTF8Unsafe())))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(
|
||||
*mock_master_playlist_ptr,
|
||||
WriteMasterPlaylist(
|
||||
_, _, ElementsAre(mock_media_playlist1, mock_media_playlist2)))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_TRUE(notifier.NotifyNewSegment(stream_id1, "segment_name", kStartTime,
|
||||
kDuration, 0, kSize));
|
||||
|
||||
EXPECT_CALL(*mock_media_playlist2, AddSegment(_, _, _, _, _)).Times(1);
|
||||
EXPECT_CALL(*mock_media_playlist2, GetLongestSegmentDuration())
|
||||
.WillOnce(Return(kLongestSegmentDuration));
|
||||
EXPECT_CALL(*mock_master_playlist_ptr, WriteMasterPlaylist(_, _, _))
|
||||
.WillOnce(Return(true));
|
||||
// Not updating other playlists as target duration does not change.
|
||||
EXPECT_CALL(*mock_media_playlist2,
|
||||
WriteToFile(StrEq(
|
||||
|
@ -1025,6 +1023,8 @@ TEST_P(LiveOrEventSimpleHlsNotifierTest, NotifyNewSegmentsWithMultipleStreams) {
|
|||
.Append(base::FilePath::FromUTF8Unsafe("playlist2.m3u8"))
|
||||
.AsUTF8Unsafe())))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(*mock_master_playlist_ptr, WriteMasterPlaylist(_, _, _))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_TRUE(notifier.NotifyNewSegment(stream_id2, "segment_name", kStartTime,
|
||||
kDuration, 0, kSize));
|
||||
}
|
||||
|
|
|
@ -189,13 +189,25 @@ Status Segmenter::FinalizeSegment(size_t stream_id,
|
|||
sidx_->references[sidx_->references.size() - 1].referenced_size =
|
||||
data_offset + mdat.data_size;
|
||||
|
||||
const uint64_t moof_start_offset = fragment_buffer_->Size();
|
||||
|
||||
// Write the fragment to buffer.
|
||||
moof_->Write(fragment_buffer_.get());
|
||||
mdat.WriteHeader(fragment_buffer_.get());
|
||||
|
||||
bool first_key_frame = true;
|
||||
for (const std::unique_ptr<Fragmenter>& fragmenter : fragmenters_) {
|
||||
for (const KeyFrameInfo& key_frame_info : fragmenter->key_frame_infos()) {
|
||||
key_frame_infos_.push_back(key_frame_info);
|
||||
key_frame_infos_.back().start_byte_offset += fragment_buffer_->Size();
|
||||
// https://goo.gl/xcFus6 6. Trick play requirements
|
||||
// 6.10. If using fMP4, I-frame segments must include the 'moof' header
|
||||
// associated with the I-frame. It also implies that only the first key
|
||||
// frame can be included.
|
||||
if (!fragmenter->key_frame_infos().empty() && first_key_frame) {
|
||||
const KeyFrameInfo& key_frame_info =
|
||||
fragmenter->key_frame_infos().front();
|
||||
first_key_frame = false;
|
||||
key_frame_infos_.push_back(
|
||||
{key_frame_info.timestamp, moof_start_offset,
|
||||
fragment_buffer_->Size() - moof_start_offset + key_frame_info.size});
|
||||
}
|
||||
fragment_buffer_->AppendBuffer(*fragmenter->data());
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ MuxerListenerFactory::StreamData ToMuxerListenerData(
|
|||
data.hls_group_id = stream.hls_group_id;
|
||||
data.hls_name = stream.hls_name;
|
||||
data.hls_playlist_name = stream.hls_playlist_name;
|
||||
data.hls_iframe_playlist_name = stream.hls_iframe_playlist_name;
|
||||
return data;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue