Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding dash_only and hls_only parameters #721

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ More Screens Ltd. <*@morescreens.net>
Philo Inc. <*@philo.com>
Piotr Srebrny <srebrny.piotr@gmail.com>
Richard Eklycke <richard@eklycke.se>
Sanil Raut <sr1990003@gmail.com>
Sergio Ammirata <sergio@ammirata.net>
The Chromium Authors <*@chromium.org>
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ Leo Law <leoltlaw.gh@gmail.com>
Piotr Srebrny <srebrny.piotr@gmail.com>
Richard Eklycke <richard@eklycke.se>
Rintaro Kuroiwa <rkuroiwa@google.com>
Sanil Raut <sr1990003@gmail.com>
Sergio Ammirata <sergio@ammirata.net>
Thomas Inskip <tinskip@google.com>
5 changes: 5 additions & 0 deletions docs/source/options/dash_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,8 @@ DASH options

Ignored if $Time$ is used in segment template, since $Time$ requires
accurate Segment Timeline.

--dash_only=0|1

Optional. Defaults to 0 if not specified. If it is set to 1, indicates the
stream is DASH only.
5 changes: 5 additions & 0 deletions docs/source/options/hls_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,8 @@ HLS options

The EXT-X-MEDIA-SEQUENCE documentation can be read here:
https://tools.ietf.org/html/rfc8216#section-4.3.3.2.

--hls_only=0|1

Optional. Defaults to 0 if not specified. If it is set to 1, indicates the
stream is HLS only.
18 changes: 18 additions & 0 deletions docs/source/tutorials/dash_hls_example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,21 @@

The above packaging command creates five single file MP4 streams, and HLS
playlists as well as DASH manifests.

* Output DASH + HLS with dash_only and hls_only options

$ packager \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update this example to use a practical use case?

For example, HLS requires WebVTT in text format while DASH supports only segmented WebVTT in mp4 format. So that is an excellent use case for the two flags.

    $ packager \
      'in=h264_baseline_360p_600.mp4,stream=audio,init_segment=audio/init.mp4,segment_template=audio/$Number$.m4s' \
      'in=input_text.vtt,stream=text,init_segment=text/init.mp4,segment_template=text/$Number$.m4s',dash_only=true' \
      'in=input_text.vtt,stream=text,segment_template=text/$Number$.vtt',hls_only=true' \  
      'in=h264_baseline_360p_600.mp4,stream=video,init_segment=h264_360p/init.mp4,segment_template=h264_360p/$Number$.m4s' \
      'in=h264_main_480p_1000.mp4,stream=video,init_segment=h264_480p/init.mp4,segment_template=h264_480p/$Number$.m4s' \
      'in=h264_main_720p_3000.mp4,stream=video,init_segment=h264_720p/init.mp4,segment_template=h264_720p/$Number$.m4s' \
      'in=h264_high_1080p_6000.mp4,stream=video,init_segment=h264_1080p/init.mp4,segment_template=h264_1080p/$Number$.m4s' \
      --generate_static_live_mpd --mpd_output h264.mpd \
      --hls_master_playlist_output h264_master.m3u8

'in=h264_baseline_360p_600.mp4,stream=audio,init_segment=audio/init.mp4,segment_template=audio/$Number$.m4s' \
'in=input_text.vtt,stream=text,init_segment=text/init.mp4,segment_template=text/$Number$.m4s',dash_only=true' \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I accidentally included an extra ' after "m4s", can you remove it? Same below.

'in=input_text.vtt,stream=text,segment_template=text/$Number$.vtt',hls_only=true' \
'in=h264_baseline_360p_600.mp4,stream=video,init_segment=h264_360p/init.mp4,segment_template=h264_360p/$Number$.m4s' \
'in=h264_main_480p_1000.mp4,stream=video,init_segment=h264_480p/init.mp4,segment_template=h264_480p/$Number$.m4s' \
'in=h264_main_720p_3000.mp4,stream=video,init_segment=h264_720p/init.mp4,segment_template=h264_720p/$Number$.m4s' \
'in=h264_high_1080p_6000.mp4,stream=video,init_segment=h264_1080p/init.mp4,segment_template=h264_1080p/$Number$.m4s' \
--generate_static_live_mpd --mpd_output h264.mpd \
--hls_master_playlist_output h264_master.m3u8

The above packaging command creates HLS playlists and DASH manifest while using
dash_only for creating segmented WebVTT in mp4 format and hls_only option for
creating WebVTT in text format.

30 changes: 30 additions & 0 deletions packager/app/stream_descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ enum FieldType {
kHlsCharacteristicsField,
kDashAccessiblitiesField,
kDashRolesField,
kDashOnlyField,
kHlsOnlyField,
};

struct FieldNameToTypeMapping {
Expand Down Expand Up @@ -77,6 +79,8 @@ const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
{"dash_role", kDashRolesField},
{"roles", kDashRolesField},
{"role", kDashRolesField},
{"dash_only", kDashOnlyField},
{"hls_only", kHlsOnlyField},
};

FieldType GetFieldType(const std::string& field_name) {
Expand Down Expand Up @@ -206,6 +210,32 @@ base::Optional<StreamDescriptor> ParseStreamDescriptor(
base::SplitString(iter->second, ";", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
break;
case kDashOnlyField:
unsigned dash_only_value;
if (!base::StringToUint(iter->second, &dash_only_value)) {
LOG(ERROR) << "Non-numeric option for dash_only field "
"specified (" << iter->second << ").";
return base::nullopt;
}
if (dash_only_value > 1) {
LOG(ERROR) << "dash_only should be either 0 or 1.";
return base::nullopt;
}
descriptor.dash_only = dash_only_value > 0;
break;
case kHlsOnlyField:
unsigned hls_only_value;
if (!base::StringToUint(iter->second, &hls_only_value)) {
LOG(ERROR) << "Non-numeric option for hls_only field "
"specified (" << iter->second << ").";
return base::nullopt;
}
if (hls_only_value > 1) {
LOG(ERROR) << "hls_only should be either 0 or 1.";
return base::nullopt;
}
descriptor.hls_only = hls_only_value > 0;
break;
default:
LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first
<< "\").";
Expand Down
18 changes: 18 additions & 0 deletions packager/app/test/packager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,10 @@ def _GetStream(self,
using_time_specifier=False,
hls=False,
hls_characteristics=None,
hls_only=None,
dash_accessibilities=None,
dash_roles=None,
dash_only=None,
trick_play_factor=None,
drm_label=None,
skip_encryption=None,
Expand All @@ -303,8 +305,10 @@ def _GetStream(self,
$Number$. This flag is only relevant if segmented is True.
hls: Should the output be for an HLS manifest.
hls_characteristics: CHARACTERISTICS attribute for the HLS stream.
hls_only: If set to true, will indicate that the stream is for HLS only.
dash_accessibilities: Accessibility element for the DASH stream.
dash_roles: Role element for the DASH stream.
dash_only: If set to true, will indicate that the stream is for DASH only.
trick_play_factor: Signals the stream is to be used for a trick play
stream and which key frames to use. A trick play factor of 0 is the
same as not specifying a trick play factor.
Expand Down Expand Up @@ -360,11 +364,17 @@ def _GetStream(self,
if hls_characteristics:
stream.Append('hls_characteristics', hls_characteristics)

if hls_only:
stream.Append('hls_only', 1)

if dash_accessibilities:
stream.Append('dash_accessibilities', dash_accessibilities)
if dash_roles:
stream.Append('dash_roles', dash_roles)

if dash_only:
stream.Append('dash_only', 1)

requires_init_segment = segmented and base_ext not in [
'aac', 'ac3', 'ec3', 'ts', 'vtt'
]
Expand Down Expand Up @@ -700,6 +710,14 @@ def testAudioVideoWithTwoTrickPlayDecreasingRate(self):
# order of trick play factors gets the same mpd.
self._CheckTestResults('audio-video-with-two-trick-play')

def testDashOnlyAndHlsOnly(self):
streams = [
self._GetStream('video', hls_only=True),
self._GetStream('audio', dash_only=True),
]
self.assertPackageSuccess(streams, self._GetFlags(output_dash=True,output_hls=True))
self._CheckTestResults('hls-only-dash-only')

def testAudioVideoWithLanguageOverride(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], language='por', hls=True),
Expand Down
Binary file not shown.
Binary file not shown.
5 changes: 5 additions & 0 deletions packager/app/test/testdata/hls-only-dash-only/output.m3u8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#EXTM3U
## Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>

#EXT-X-STREAM-INF:BANDWIDTH=973483,AVERAGE-BANDWIDTH=879459,CODECS="avc1.64001e",RESOLUTION=640x360,FRAME-RATE=29.970
stream_1.m3u8
15 changes: 15 additions & 0 deletions packager/app/test/testdata/hls-only-dash-only/output.mpd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.739954710006714S">
<Period id="0">
<AdaptationSet id="0" contentType="audio" subsegmentAlignment="true">
<Representation id="0" bandwidth="133334" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="793-860" timescale="44100">
<Initialization range="0-792"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>
16 changes: 16 additions & 0 deletions packager/app/test/testdata/hls-only-dash-only/stream_1.m3u8
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#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
#EXT-X-MAP:URI="bear-640x360-video.mp4",BYTERANGE="859@0"
#EXTINF:1.001,
#EXT-X-BYTERANGE:99313@927
bear-640x360-video.mp4
#EXTINF:1.001,
#EXT-X-BYTERANGE:121807
bear-640x360-video.mp4
#EXTINF:0.734,
#EXT-X-BYTERANGE:79662
bear-640x360-video.mp4
#EXT-X-ENDLIST
6 changes: 4 additions & 2 deletions packager/media/event/muxer_listener_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ std::unique_ptr<MuxerListener> MuxerListenerFactory::CreateListener(
combined_listener->AddListener(
CreateMediaInfoDumpListenerInternal(stream.media_info_output));
}
if (mpd_notifier_) {

if (mpd_notifier_ && !stream.hls_only) {
combined_listener->AddListener(
CreateMpdListenerInternal(stream, mpd_notifier_));
}
if (hls_notifier_) {

if (hls_notifier_ && !stream.dash_only) {
for (auto& listener :
CreateHlsListenersInternal(stream, stream_index, hls_notifier_)) {
combined_listener->AddListener(std::move(listener));
Expand Down
2 changes: 2 additions & 0 deletions packager/media/event/muxer_listener_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ class MuxerListenerFactory {
std::string hls_playlist_name;
std::string hls_iframe_playlist_name;
std::vector<std::string> hls_characteristics;
bool hls_only = false;

// DASH specific values needed to write DASH mpd. Will only be used if an
// MpdNotifier is given to the factory.
std::vector<std::string> dash_accessiblities;
std::vector<std::string> dash_roles;
bool dash_only = false;
};

/// Create a new muxer listener.
Expand Down
2 changes: 2 additions & 0 deletions packager/packager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ MuxerListenerFactory::StreamData ToMuxerListenerData(
data.hls_playlist_name = stream.hls_playlist_name;
data.hls_iframe_playlist_name = stream.hls_iframe_playlist_name;
data.hls_characteristics = stream.hls_characteristics;
data.hls_only = stream.hls_only;

data.dash_accessiblities = stream.dash_accessiblities;
data.dash_roles = stream.dash_roles;
data.dash_only = stream.dash_only;
return data;
};

Expand Down
5 changes: 5 additions & 0 deletions packager/packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ struct StreamDescriptor {
std::vector<std::string> dash_accessiblities;
/// Optional for DASH output. It defines Role elements of the stream.
std::vector<std::string> dash_roles;

/// Set to true to indicate that the stream is for dash only.
bool dash_only = false;
/// Set to true to indicate that the stream is for hls only.
bool hls_only = false;
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test in packager_test.py?

One option is to modify it from https://github.com/google/shaka-packager/blob/master/packager/app/test/packager_test.py#L652 and use dash_only for audio and use hls_only for video. After writing the test, you can run the below command to generate the golden files for you.

$ ninja -C out/Debug
$ out/Debug/packager_test.py --test_update_golden_files=1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add the test. Thanks for the commands.

class SHAKA_EXPORT Packager {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes have updated the mentioned files. Please review and let me know.

Expand Down