Fix mpd duration not set in static live manifest
Closes #201 Change-Id: Ie9ab58ec58e1b135931a6576fb46145454b0f049
This commit is contained in:
parent
871c7b38d6
commit
94cadf9e28
|
@ -333,6 +333,14 @@ class PackagerAppTest(unittest.TestCase):
|
|||
self._DiffLiveGold(self.output[1], 'bear-640x360-v-live-golden')
|
||||
self._DiffLiveMpdGold(self.mpd_output, 'bear-640x360-av-live-golden.mpd')
|
||||
|
||||
def testPackageWithLiveStaticProfile(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video'], live=True),
|
||||
self._GetFlags(generate_static_mpd=True))
|
||||
self._DiffLiveGold(self.output[0], 'bear-640x360-a-live-golden')
|
||||
self._DiffLiveGold(self.output[1], 'bear-640x360-v-live-golden')
|
||||
self._DiffGold(self.mpd_output, 'bear-640x360-av-live-static-golden.mpd')
|
||||
|
||||
def testPackageWithLiveProfileAndEncryption(self):
|
||||
self.packager.Package(
|
||||
self._GetStreams(['audio', 'video'], live=True),
|
||||
|
@ -493,6 +501,7 @@ class PackagerAppTest(unittest.TestCase):
|
|||
dash_if_iop=True,
|
||||
output_media_info=False,
|
||||
output_hls=False,
|
||||
generate_static_mpd=False,
|
||||
use_fake_clock=True):
|
||||
flags = []
|
||||
if widevine_encryption:
|
||||
|
@ -528,6 +537,9 @@ class PackagerAppTest(unittest.TestCase):
|
|||
else:
|
||||
flags += ['--mpd_output', self.mpd_output]
|
||||
|
||||
if generate_static_mpd:
|
||||
flags += ['--generate_static_mpd']
|
||||
|
||||
flags.append('--segment_duration=1')
|
||||
# Use fake clock, so output can be compared.
|
||||
if use_fake_clock:
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?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" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||
<Period id="0">
|
||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||
<Representation id="0" bandwidth="872999" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||
<SegmentTimeline>
|
||||
<S t="2002" d="30030" r="1"/>
|
||||
<S t="62062" d="22022"/>
|
||||
</SegmentTimeline>
|
||||
</SegmentTemplate>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||
<Representation id="1" bandwidth="121855" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||
<SegmentTimeline>
|
||||
<S t="0" d="45056" r="1"/>
|
||||
<S t="90112" d="31744"/>
|
||||
</SegmentTimeline>
|
||||
</SegmentTemplate>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
</Period>
|
||||
</MPD>
|
|
@ -119,6 +119,8 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
|
|||
uint64_t file_size) {
|
||||
if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
|
||||
DCHECK(subsegments_.empty());
|
||||
// TODO(kqyang): Set mpd duration to |duration_seconds|, which is more
|
||||
// accurate than the duration coded in the original media header.
|
||||
if (mpd_notifier_->mpd_type() == MpdType::kStatic)
|
||||
mpd_notifier_->Flush();
|
||||
return;
|
||||
|
|
|
@ -295,6 +295,7 @@ TEST_P(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
|
|||
" pixel_width: 1\n"
|
||||
" pixel_height: 1\n"
|
||||
"}\n"
|
||||
"media_duration_seconds: 20.0\n"
|
||||
"init_segment_name: \"liveinit.mp4\"\n"
|
||||
"segment_template: \"live-$NUMBER$.mp4\"\n"
|
||||
"reference_time_scale: 1000\n"
|
||||
|
@ -368,6 +369,7 @@ TEST_P(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
|
|||
" pixel_width: 1\n"
|
||||
" pixel_height: 1\n"
|
||||
"}\n"
|
||||
"media_duration_seconds: 20.0\n"
|
||||
"init_segment_name: \"liveinit.mp4\"\n"
|
||||
"segment_template: \"live-$NUMBER$.mp4\"\n"
|
||||
"reference_time_scale: 1000\n"
|
||||
|
|
|
@ -144,6 +144,12 @@ void SetMediaInfoStreamInfo(const StreamInfo& stream_info,
|
|||
AddVideoInfo(static_cast<const VideoStreamInfo*>(&stream_info),
|
||||
media_info);
|
||||
}
|
||||
if (stream_info.duration() > 0) {
|
||||
// |stream_info.duration()| contains the media duration from the original
|
||||
// media header, which is usually good enough.
|
||||
media_info->set_media_duration_seconds(
|
||||
static_cast<double>(stream_info.duration()) / stream_info.time_scale());
|
||||
}
|
||||
}
|
||||
|
||||
void SetMediaInfoMuxerOptions(const MuxerOptions& muxer_options,
|
||||
|
|
|
@ -134,9 +134,11 @@ message MediaInfo {
|
|||
optional Range init_range = 6;
|
||||
optional Range index_range = 7;
|
||||
optional string media_file_name = 8;
|
||||
optional float media_duration_seconds = 9;
|
||||
// END VOD only.
|
||||
|
||||
// VOD and static LIVE.
|
||||
optional float media_duration_seconds = 9;
|
||||
|
||||
// LIVE only.
|
||||
optional string init_segment_name = 10;
|
||||
optional string segment_template = 11;
|
||||
|
|
|
@ -1199,6 +1199,15 @@ xml::scoped_xml_ptr<xmlNode> Representation::GetXml() {
|
|||
return xml::scoped_xml_ptr<xmlNode>();
|
||||
}
|
||||
|
||||
// Set media duration for static mpd.
|
||||
if (mpd_options_.mpd_type == MpdType::kStatic &&
|
||||
media_info_.has_media_duration_seconds()) {
|
||||
// Adding 'duration' attribute, so that this information can be used when
|
||||
// generating one MPD file. This should be removed from the final MPD.
|
||||
representation.SetFloatingPointAttribute(
|
||||
"duration", media_info_.media_duration_seconds());
|
||||
}
|
||||
|
||||
if (HasVODOnlyFields(media_info_) &&
|
||||
!representation.AddVODOnlyInfo(media_info_)) {
|
||||
LOG(ERROR) << "Failed to add VOD segment info.";
|
||||
|
|
|
@ -33,8 +33,7 @@ std::string TextCodecString(const MediaInfo& media_info) {
|
|||
|
||||
bool HasVODOnlyFields(const MediaInfo& media_info) {
|
||||
return media_info.has_init_range() || media_info.has_index_range() ||
|
||||
media_info.has_media_file_name() ||
|
||||
media_info.has_media_duration_seconds();
|
||||
media_info.has_media_file_name();
|
||||
}
|
||||
|
||||
bool HasLiveOnlyFields(const MediaInfo& media_info) {
|
||||
|
|
|
@ -294,12 +294,6 @@ bool RepresentationXmlNode::AddVODOnlyInfo(const MediaInfo& media_info) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (media_info.has_media_duration_seconds()) {
|
||||
// Adding 'duration' attribute, so that this information can be used when
|
||||
// generating one MPD file. This should be removed from the final MPD.
|
||||
SetFloatingPointAttribute("duration", media_info.media_duration_seconds());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue