diff --git a/packager/mpd/base/mpd_utils.cc b/packager/mpd/base/mpd_utils.cc index 8d288e30f8b..3e8bdee2561 100644 --- a/packager/mpd/base/mpd_utils.cc +++ b/packager/mpd/base/mpd_utils.cc @@ -188,13 +188,30 @@ std::string GetAdaptationSetKey(const MediaInfo& media_info, return key; } +std::string FloatToXmlString(double number) { + // Keep up to microsecond accuracy but trim trailing 0s + std::string formatted = absl::StrFormat("%.6g", number); + size_t decimalPos = formatted.find('.'); + if (decimalPos != std::string::npos) { + size_t lastNonZeroPos = formatted.find_last_not_of('0'); + if (lastNonZeroPos >= decimalPos) { + formatted.erase(lastNonZeroPos + 1); + } + if (formatted.back() == '.') { + formatted.pop_back(); + } + } + + return formatted; +} + std::string SecondsToXmlDuration(double seconds) { // Chrome internally uses time accurate to microseconds, which is implemented // per MSE spec (https://www.w3.org/TR/media-source/). // We need a string formatter that has at least microseconds accuracy for a - // normal video (with duration up to 3 hours). Chrome's DoubleToString + // normal video (with duration up to 3 hours). FloatToXmlString // implementation meets the requirement. - return absl::StrFormat("PT%gS", seconds); + return absl::StrFormat("PT%sS", FloatToXmlString(seconds)); } bool GetDurationAttribute(xmlNodePtr node, float* duration) { diff --git a/packager/mpd/base/mpd_utils.h b/packager/mpd/base/mpd_utils.h index 3e12d6d92aa..b48fbc06e7c 100644 --- a/packager/mpd/base/mpd_utils.h +++ b/packager/mpd/base/mpd_utils.h @@ -50,6 +50,8 @@ std::string GetBaseCodec(const MediaInfo& media_info); // Returns a key made from the characteristics that separate AdaptationSets. std::string GetAdaptationSetKey(const MediaInfo& media_info, bool ignore_codec); +std::string FloatToXmlString(double number); + std::string SecondsToXmlDuration(double seconds); // Tries to get "duration" attribute from |node|. On success |duration| is set. diff --git a/packager/mpd/base/xml/xml_node.cc b/packager/mpd/base/xml/xml_node.cc index 079e0007ab7..9fedfe49895 100644 --- a/packager/mpd/base/xml/xml_node.cc +++ b/packager/mpd/base/xml/xml_node.cc @@ -203,7 +203,7 @@ bool XmlNode::SetFloatingPointAttribute(const std::string& attribute_name, double number) { DCHECK(impl_->node); return xmlSetProp(impl_->node.get(), BAD_CAST attribute_name.c_str(), - BAD_CAST(absl::StrFormat("%g", number).c_str())) != nullptr; + BAD_CAST(FloatToXmlString(number).c_str())) != nullptr; } bool XmlNode::SetId(uint32_t id) {