From 570a2d1a1589f52cd7774f12a7dfb65583b27c47 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Thu, 1 Feb 2018 12:27:30 -0800 Subject: [PATCH] Support 'iframe_playlist_name' stream descriptor Issue: #287 Change-Id: I484761dfacadce05175d16c4c12454f0ed932579 --- .../source/options/hls_stream_descriptors.rst | 7 +++++++ packager/app/packager_main.cc | 6 +++++- packager/app/stream_descriptor.cc | 6 ++++++ .../media/event/muxer_listener_factory.cc | 21 +++++++++++++------ packager/media/event/muxer_listener_factory.h | 1 + packager/packager.h | 3 +++ 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/source/options/hls_stream_descriptors.rst b/docs/source/options/hls_stream_descriptors.rst index 35234cedb4..72e9dd8045 100644 --- a/docs/source/options/hls_stream_descriptors.rst +++ b/docs/source/options/hls_stream_descriptors.rst @@ -17,3 +17,10 @@ HLS specific stream descriptor fields relative to hls_master_playlist_output (see below). If unspecified, defaults to something of the form 'stream_0.m3u8', 'stream_1.m3u8', 'stream_2.m3u8', etc. + +:iframe_playlist_name: + + The optional HLS I-Frames only playlist file to create. Usually ends with + '.m3u8', and is relative to hls_master_playlist_output (see below). Should + only be set for video streams. If unspecified, no I-Frames only playlist is + created. diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index e4ddcf8aed..26ec7040e1 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -100,7 +100,11 @@ const char kUsage[] = " - playlist_name: The HLS playlist file to create. Usually ends with\n" " '.m3u8', and is relative to --hls_master_playlist_output. If\n" " unspecified, defaults to something of the form 'stream_0.m3u8',\n" - " 'stream_1.m3u8', 'stream_2.m3u8', etc.\n"; + " 'stream_1.m3u8', 'stream_2.m3u8', etc.\n" + " - iframe_playlist_name: The optional HLS I-Frames only playlist file\n" + " to create. Usually ends with '.m3u8', and is relative to\n" + " hls_master_playlist_output. Should only be set for video streams. If\n" + " unspecified, no I-Frames only playlist is created.\n"; // Labels for parameters in RawKey key info. const char kDrmLabelLabel[] = "label"; diff --git a/packager/app/stream_descriptor.cc b/packager/app/stream_descriptor.cc index 2991f2d54f..ae67a13ce8 100644 --- a/packager/app/stream_descriptor.cc +++ b/packager/app/stream_descriptor.cc @@ -26,6 +26,7 @@ enum FieldType { kHlsNameField, kHlsGroupIdField, kHlsPlaylistNameField, + kHlsIframePlaylistNameField, kTrickPlayFactorField, kSkipEncryptionField, kDrmStreamLabelField, @@ -56,6 +57,7 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = { {"hls_name", kHlsNameField}, {"hls_group_id", kHlsGroupIdField}, {"playlist_name", kHlsPlaylistNameField}, + {"iframe_playlist_name", kHlsIframePlaylistNameField}, {"trick_play_factor", kTrickPlayFactorField}, {"tpf", kTrickPlayFactorField}, {"skip_encryption", kSkipEncryptionField}, @@ -128,6 +130,10 @@ base::Optional ParseStreamDescriptor( descriptor.hls_playlist_name = iter->second; break; } + case kHlsIframePlaylistNameField: { + descriptor.hls_iframe_playlist_name = iter->second; + break; + } case kTrickPlayFactorField: { unsigned factor; if (!base::StringToUint(iter->second, &factor)) { diff --git a/packager/media/event/muxer_listener_factory.cc b/packager/media/event/muxer_listener_factory.cc index b83974c364..99604c4f8e 100644 --- a/packager/media/event/muxer_listener_factory.cc +++ b/packager/media/event/muxer_listener_factory.cc @@ -37,7 +37,7 @@ std::unique_ptr CreateMpdListenerInternal( return listener; } -std::unique_ptr CreateHlsListenerInternal( +std::list> CreateHlsListenersInternal( const MuxerListenerFactory::StreamData& stream, int stream_index, hls::HlsNotifier* notifier) { @@ -47,6 +47,7 @@ std::unique_ptr CreateHlsListenerInternal( std::string group_id = stream.hls_group_id; std::string name = stream.hls_name; std::string hls_playlist_name = stream.hls_playlist_name; + std::string hls_iframe_playlist_name = stream.hls_iframe_playlist_name; if (name.empty()) { name = base::StringPrintf("stream_%d", stream_index); @@ -57,9 +58,14 @@ std::unique_ptr CreateHlsListenerInternal( } const bool kIFramesOnly = true; - std::unique_ptr listener(new HlsNotifyMuxerListener( + std::list> listeners; + listeners.emplace_back(new HlsNotifyMuxerListener( hls_playlist_name, !kIFramesOnly, name, group_id, notifier)); - return listener; + if (!hls_iframe_playlist_name.empty()) { + listeners.emplace_back(new HlsNotifyMuxerListener( + hls_iframe_playlist_name, kIFramesOnly, name, group_id, notifier)); + } + return listeners; } } // namespace @@ -85,8 +91,10 @@ std::unique_ptr MuxerListenerFactory::CreateListener( combined_listener->AddListener(CreateMpdListenerInternal(mpd_notifier_)); } if (hls_notifier_) { - combined_listener->AddListener( - CreateHlsListenerInternal(stream, stream_index, hls_notifier_)); + for (auto& listener : + CreateHlsListenersInternal(stream, stream_index, hls_notifier_)) { + combined_listener->AddListener(std::move(listener)); + } } return std::move(combined_listener); @@ -99,7 +107,8 @@ std::unique_ptr MuxerListenerFactory::CreateHlsListener( } const int stream_index = stream_index_++; - return CreateHlsListenerInternal(stream, stream_index, hls_notifier_); + return std::move( + CreateHlsListenersInternal(stream, stream_index, hls_notifier_).front()); } } // namespace media diff --git a/packager/media/event/muxer_listener_factory.h b/packager/media/event/muxer_listener_factory.h index c7bddd787c..b1bfc006d4 100644 --- a/packager/media/event/muxer_listener_factory.h +++ b/packager/media/event/muxer_listener_factory.h @@ -43,6 +43,7 @@ class MuxerListenerFactory { std::string hls_group_id; std::string hls_name; std::string hls_playlist_name; + std::string hls_iframe_playlist_name; }; /// Create a new muxer listener. diff --git a/packager/packager.h b/packager/packager.h index bd4799bca6..dbe68419d5 100644 --- a/packager/packager.h +++ b/packager/packager.h @@ -112,6 +112,9 @@ struct StreamDescriptor { /// Required for HLS output. It defines the name of the playlist for the /// stream. Usually ends with `.m3u8`. std::string hls_playlist_name; + /// Optional for HLS output. It defines the name of the I-Frames only playlist + /// for the stream. For Video only. Usually ends with `.m3u8`. + std::string hls_iframe_playlist_name; }; class SHAKA_EXPORT Packager {