<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Kubo Ryosuke</title>
    <description>The latest articles on Forem by Kubo Ryosuke (@sunfishshogi).</description>
    <link>https://forem.com/sunfishshogi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F442997%2Fec238db8-1e0b-438b-b4e6-d707e424ff16.png</url>
      <title>Forem: Kubo Ryosuke</title>
      <link>https://forem.com/sunfishshogi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sunfishshogi"/>
    <language>en</language>
    <item>
      <title>URL and Timestamp of MPEG-DASH Segments</title>
      <dc:creator>Kubo Ryosuke</dc:creator>
      <pubDate>Wed, 03 Nov 2021 09:49:38 +0000</pubDate>
      <link>https://forem.com/sunfishshogi/url-and-timestamp-of-mpeg-dash-segments-2pdn</link>
      <guid>https://forem.com/sunfishshogi/url-and-timestamp-of-mpeg-dash-segments-2pdn</guid>
      <description>&lt;p&gt;&lt;a href="https://qiita.com/sunfish-shogi/items/15c5108b7bfef9bd48fc"&gt;Japanese Page&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;MPD which is manifest file of MPEG-DASH indicates segment URLs and any attributes like HLS playlist.&lt;br&gt;
HLS playlist has simple list of URLs and attributes and is very easy to read. However, MPD has compex structure and is more difficult to read than HLS playlist.&lt;br&gt;
In this post, I describe things about segments of MPD. &lt;/p&gt;
&lt;h1&gt;
  
  
  MPD Examples
&lt;/h1&gt;

&lt;p&gt;You can see Reference Client and many DASH streams at DASH Industry Forum.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reference.dashif.org/"&gt;https://reference.dashif.org/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  BaseURL
&lt;/h1&gt;

&lt;p&gt;If MPD has BaseURL tag, segment URL is indicated as relative path from value of the tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;BaseURL&amp;gt;&lt;/span&gt;http://localhost/mystream/hd/&lt;span class="nt"&gt;&amp;lt;/BaseURL&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;BaseURL can have relative URL from MPD.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;BaseURL&amp;gt;&lt;/span&gt;./hd/&lt;span class="nt"&gt;&amp;lt;/BaseURL&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all segments are concatenated as one file, BaseURL can have full URL of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;BaseURL&amp;gt;&lt;/span&gt;http://localhost/mystream/video.mp4&lt;span class="nt"&gt;&amp;lt;/BaseURL&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, player will download those segments by range requests.&lt;br&gt;
Using SegmentBase or SegmentList/SegmentURL which will be described bellow, MPD can indicates byte ranges of those segments to player.&lt;/p&gt;
&lt;h1&gt;
  
  
  SegmentTemplate
&lt;/h1&gt;

&lt;p&gt;In live profile, SegmentTemplate tag is usually used.&lt;br&gt;
This tag can be used to both of live stream (dynamic type MPD) and VOD stream (static type MPD).&lt;br&gt;
ABEMA which is our video streaming service uses SegmentTemplate tag for all streams.&lt;/p&gt;
&lt;h2&gt;
  
  
  media attribute and initialization attribute
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;SegmentTemplate@media&lt;/code&gt; attribute and &lt;code&gt;SegmentTemplate@initialization&lt;/code&gt; attribute indicate media segments (MP4 containing moof and mdat) and initialization segment (MP4 containing ftyp and moov), respectively.&lt;br&gt;
However, you should resolve templates which is enclosed by &lt;code&gt;$&lt;/code&gt; and embedded to those values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; 
    &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/$Time$.mp4"&lt;/span&gt;
    &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are 5 types of template. In most cases, &lt;code&gt;$RepresentationID$&lt;/code&gt; and &lt;code&gt;$Time$&lt;/code&gt; or &lt;code&gt;$Number$&lt;/code&gt; will be used.&lt;br&gt;
&lt;code&gt;$RepresentationID$&lt;/code&gt; template indicates value of &lt;code&gt;Representation@id&lt;/code&gt;.&lt;br&gt;
In following sample, There are 2 Representation tags at same level with SegmentTemplate tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;AdaptationSet&lt;/span&gt; &lt;span class="na"&gt;contentType=&lt;/span&gt;&lt;span class="s"&gt;"video"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"video/mp4"&lt;/span&gt; &lt;span class="na"&gt;segmentAlignment=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;timescale=&lt;/span&gt;&lt;span class="s"&gt;"90000"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/$Time$.mp4"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-hd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"2000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"720"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1280"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-sd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"1000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"854"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/AdaptationSet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inserting &lt;code&gt;video-hd&lt;/code&gt; and &lt;code&gt;video-sd&lt;/code&gt; to &lt;code&gt;$RepresentationId$&lt;/code&gt; of &lt;code&gt;@initialization&lt;/code&gt; attribute, you can get paths: &lt;code&gt;video-hd/init.mp4&lt;/code&gt; and &lt;code&gt;video-sd/init.mp4&lt;/code&gt;. These are initialization segment of HD and SD, respectively.&lt;br&gt;
On the other way, what does &lt;code&gt;$Time$&lt;/code&gt; template indicates?&lt;/p&gt;
&lt;h2&gt;
  
  
  With SegmentTimeline
&lt;/h2&gt;

&lt;p&gt;SegmentTimeline tag enumerates relative time and duration of segments as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;MPD&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"urn:mpeg:dash:schema:mpd:2011"&lt;/span&gt; &lt;span class="na"&gt;availabilityStartTime=&lt;/span&gt;&lt;span class="s"&gt;"1970-01-01T00:00:00Z"&lt;/span&gt; &lt;span class="na"&gt;profiles=&lt;/span&gt;&lt;span class="s"&gt;"urn:mpeg:dash:profile:isoff-live:2011"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"dynamic"&lt;/span&gt; &lt;span class="na"&gt;minBufferTime=&lt;/span&gt;&lt;span class="s"&gt;"PT5.000000S"&lt;/span&gt; &lt;span class="na"&gt;publishTime=&lt;/span&gt;&lt;span class="s"&gt;"2021-10-28T13:07:58Z"&lt;/span&gt; &lt;span class="na"&gt;minimumUpdatePeriod=&lt;/span&gt;&lt;span class="s"&gt;"PT5.000000S"&lt;/span&gt; &lt;span class="na"&gt;timeShiftBufferDepth=&lt;/span&gt;&lt;span class="s"&gt;"PT60.000000S"&lt;/span&gt; &lt;span class="na"&gt;suggestedPresentationDelay=&lt;/span&gt;&lt;span class="s"&gt;"PT15.000000S"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;BaseURL&amp;gt;&lt;/span&gt;http://localhost/mystream/&lt;span class="nt"&gt;&amp;lt;/BaseURL&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Period&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;start=&lt;/span&gt;&lt;span class="s"&gt;"PT1609426800S"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AdaptationSet&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"video/mp4"&lt;/span&gt; &lt;span class="na"&gt;segmentAlignment=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;timescale=&lt;/span&gt;&lt;span class="s"&gt;"90000"&lt;/span&gt; &lt;span class="na"&gt;presentationTimeOffset=&lt;/span&gt;&lt;span class="s"&gt;"10786776"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/$Time$.mp4"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;SegmentTimeline&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"357357"&lt;/span&gt; &lt;span class="na"&gt;t=&lt;/span&gt;&lt;span class="s"&gt;"11771760"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"360360"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"357357"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/SegmentTimeline&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/SegmentTemplate&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-hd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"2000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"720"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1280"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-sd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"1000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"854"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/AdaptationSet&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AdaptationSet&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"audio/mp4"&lt;/span&gt; &lt;span class="na"&gt;segmentAlignment=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;timescale=&lt;/span&gt;&lt;span class="s"&gt;"48000"&lt;/span&gt; &lt;span class="na"&gt;presentationTimeOffset=&lt;/span&gt;&lt;span class="s"&gt;"5752947"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/$Time$.mp4"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;SegmentTimeline&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"191488"&lt;/span&gt; &lt;span class="na"&gt;t=&lt;/span&gt;&lt;span class="s"&gt;"6278272"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"192512"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/SegmentTimeline&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/SegmentTemplate&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"audio-high"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"190000"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;AudioChannelConfiguration&lt;/span&gt; &lt;span class="na"&gt;schemeIdUri=&lt;/span&gt;&lt;span class="s"&gt;"urn:mpeg:dash:23003:3:audio_channel_configuration:2011"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/Representation&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"audio-low"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"64000"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;AudioChannelConfiguration&lt;/span&gt; &lt;span class="na"&gt;schemeIdUri=&lt;/span&gt;&lt;span class="s"&gt;"urn:mpeg:dash:23003:3:audio_channel_configuration:2011"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/Representation&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/AdaptationSet&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Period&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/MPD&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SegmentTimeline tag has S tags which indicates each segments.&lt;br&gt;
However, if S tag has non-zero &lt;code&gt;@r&lt;/code&gt; attribute, &lt;code&gt;@r&lt;/code&gt; is repeat count of the S tag. (When &lt;code&gt;@r&lt;/code&gt; is negative value, it means open-ended.)  For example, &lt;code&gt;r="3"&lt;/code&gt; means +3 segments, in other words, there are continuous 4 segments which have same duration.&lt;br&gt;
&lt;code&gt;S@d&lt;/code&gt; attribute is duration of segment and &lt;code&gt;S@t&lt;/code&gt; attribute is earliest timestamp of segment.&lt;br&gt;
The second and the subsequent segments can omit &lt;code&gt;@t&lt;/code&gt; attribute, and its value is sum of previous segment's &lt;code&gt;@t&lt;/code&gt; and &lt;code&gt;@d&lt;/code&gt;.&lt;br&gt;
Insert those &lt;code&gt;@t&lt;/code&gt; values to &lt;code&gt;$Time$&lt;/code&gt; template, you can get media segment URLs.&lt;br&gt;
For example, earliest segments of above sample is &lt;code&gt;http://localhost/mystream/video-hd/11771760.mp4&lt;/code&gt; and &lt;code&gt;http://localhost/mystream/video-sd/11771760.mp4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;S@t&lt;/code&gt; and &lt;code&gt;S@d&lt;/code&gt; are always integer values. Dividing those by &lt;code&gt;SegmentTemplate@timescale&lt;/code&gt; attribute, you can get time and duration in seconds, respectively.&lt;br&gt;
So, in above sample, the duration of earliest video segment is &lt;code&gt;357357 / 90000 = 3.97&lt;/code&gt; seconds, and the timestamp is &lt;code&gt;11771760 / 90000 = 130.797&lt;/code&gt; seconds. These values are synchronized with values in MP4 boxes.&lt;br&gt;
Then, subtracting &lt;code&gt;SegmentTemplate@presentationTimeOffset&lt;/code&gt; from &lt;code&gt;S@t&lt;/code&gt;, you can get elapsed time from period start.&lt;br&gt;
For above sample, you can calculate elapsed time of latest video segment from period start by following expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(11771760 + 357357 + 360360 * 4 - 10786776) / 90000 = 30.93 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding &lt;code&gt;Period@start&lt;/code&gt; to &lt;code&gt;MPD@availabilityStartTime&lt;/code&gt;, you can get absolute time of period start.&lt;br&gt;
So, in above sample, period start is 2020/12/31T15:00:00Z and composition time of latest video segment is 2020/12/31T15:00:30.930Z.&lt;/p&gt;
&lt;h2&gt;
  
  
  Only SegmentTemplate
&lt;/h2&gt;

&lt;p&gt;As mentioned above, you can use SegmentTimeline to write timestamp (composition time) and duration of each segments.&lt;br&gt;
On the other hand, if all segments have same duration, SegmentTimeline is not mandatory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;AdaptationSet&lt;/span&gt; &lt;span class="na"&gt;contentType=&lt;/span&gt;&lt;span class="s"&gt;"video"&lt;/span&gt; &lt;span class="na"&gt;mimeType=&lt;/span&gt;&lt;span class="s"&gt;"video/mp4"&lt;/span&gt; &lt;span class="na"&gt;segmentAlignment=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;duration=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt; &lt;span class="na"&gt;startNumber=&lt;/span&gt;&lt;span class="s"&gt;"1000"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/init.mp4"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"$RepresentationID$/$Number$.mp4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-300k"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"300000"&lt;/span&gt; &lt;span class="na"&gt;codecs=&lt;/span&gt;&lt;span class="s"&gt;"avc1.64001e"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"360"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"640"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/AdaptationSet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In above sample, &lt;code&gt;SegmentTemplate@duration&lt;/code&gt; is segment duration and the all segments are 2 seconds.&lt;br&gt;
&lt;code&gt;@media&lt;/code&gt; attribute has &lt;code&gt;$Number$&lt;/code&gt; template, it is index number of segment which is started by &lt;code&gt;@startNumber&lt;/code&gt;.&lt;br&gt;
So, segment URLs of above MPD are followings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;video-300k/1000.mp4 --- earliest 2 seconds
video-300k/1001.mp4 --- 2nd 2 seconds
video-300k/1002.mp4 --- 3rd 2 seconds
    :
video-300k/1099.mp4 --- 1000th 2 seconds
    :
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This post examples use &lt;code&gt;$Time$&lt;/code&gt; template with SegmentTimeline or &lt;code&gt;$Number$&lt;/code&gt; without SegmentTimeline.&lt;br&gt;
However, not only these usages, you can use &lt;code&gt;$Number$&lt;/code&gt; template with SegmentTimeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  Relation with Representation
&lt;/h2&gt;

&lt;p&gt;In above samples, SegmentTemplate tag and Representation tags are placed in same layer. However, SegmentTemplate tag can be placed in each Representation tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-hd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"2000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"720"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1280"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;timescale=&lt;/span&gt;&lt;span class="s"&gt;"90000"&lt;/span&gt; &lt;span class="na"&gt;presentationTimeOffset=&lt;/span&gt;&lt;span class="s"&gt;"10786776"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"hd/$Time$.mp4"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"hd/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        ...
    &lt;span class="nt"&gt;&amp;lt;/SegmentTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Representation&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Representation&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"video-sd"&lt;/span&gt; &lt;span class="na"&gt;bandwidth=&lt;/span&gt;&lt;span class="s"&gt;"1000000"&lt;/span&gt; &lt;span class="na"&gt;frameRate=&lt;/span&gt;&lt;span class="s"&gt;"30000/1001"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"854"&lt;/span&gt; &lt;span class="na"&gt;scanType=&lt;/span&gt;&lt;span class="s"&gt;"progressive"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentTemplate&lt;/span&gt; &lt;span class="na"&gt;timescale=&lt;/span&gt;&lt;span class="s"&gt;"90000"&lt;/span&gt; &lt;span class="na"&gt;presentationTimeOffset=&lt;/span&gt;&lt;span class="s"&gt;"10786776"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"sd/$Time$.mp4"&lt;/span&gt; &lt;span class="na"&gt;initialization=&lt;/span&gt;&lt;span class="s"&gt;"sd/init.mp4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        ...
    &lt;span class="nt"&gt;&amp;lt;/SegmentTemplate&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Representation&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  SegmentList, Initialization and SegmentURL
&lt;/h1&gt;

&lt;p&gt;SegmentURL tags have URL or byte-range of each segments.&lt;br&gt;
For example, you can place Initialization tag and SegmentURL tags in SegmentList tag as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;SegmentList&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Initialization&lt;/span&gt; &lt;span class="na"&gt;sourceURL=&lt;/span&gt;&lt;span class="s"&gt;"init.mp4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentURL&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"0.mp4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentURL&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"1.mp4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;SegmentURL&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"2.mp4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/SegmentList&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is similar to HLS playlist and easy to understand.&lt;/p&gt;

&lt;h1&gt;
  
  
  SegmentBase
&lt;/h1&gt;

&lt;p&gt;If BaseURL has URL of single MP4 file and MPD has neither SegmentList nor SegmentTemplate, player have no way knowing byte-range of segments.&lt;br&gt;
&lt;code&gt;SegmentBase@indexRange&lt;/code&gt; attribute indicates byte-range of information about byte-range of each segments (ex. sidx Box).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;BaseURL&amp;gt;&lt;/span&gt;http://localhost/sample.mp4&lt;span class="nt"&gt;&amp;lt;/BaseURL&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;SegmentBase&lt;/span&gt; &lt;span class="na"&gt;indexRange=&lt;/span&gt;&lt;span class="s"&gt;"896-1730"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this example, player will send range-request of 896-1730 at first. The response data contains timestamp and offset of segments and player will send range-request for each segments.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There are many types of MPD usage. So it is difficult to understand.&lt;br&gt;
This post described major ways to represent segments in MPD.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;ISO/IEC 23009-1 Dynamic adaptive streaming over HTTP (DASH) - Part 1: Media presentation description and segment formats&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qiita.com/sunfish-shogi/items/4dc020954d46f0e998a6"&gt;フレームレートとタイムコード、タイムスタンプ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qiita.com/sunfish-shogi/items/008b3da9309b08465604"&gt;AbemaTV の MPEG-DASH 対応&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitmovin.com/dynamic-adaptive-streaming-http-mpeg-dash/"&gt;MPEG-DASH (Dynamic Adaptive Streaming over HTTP, ISO/IEC 23009-1) - BITMOVIN Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mpegdash</category>
      <category>streaming</category>
    </item>
    <item>
      <title>go-mp4: Golang Library and CLI Tool for MP4</title>
      <dc:creator>Kubo Ryosuke</dc:creator>
      <pubDate>Thu, 30 Jul 2020 03:20:24 +0000</pubDate>
      <link>https://forem.com/sunfishshogi/go-mp4-golang-library-and-cli-tool-for-mp4-52o1</link>
      <guid>https://forem.com/sunfishshogi/go-mp4-golang-library-and-cli-tool-for-mp4-52o1</guid>
      <description>&lt;p&gt;&lt;a href="https://qiita.com/sunfish-shogi/items/7205fde715f429f2a310" rel="noopener noreferrer"&gt;Japanese Page&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I'm going to introduce &lt;a href="https://github.com/abema/go-mp4" rel="noopener noreferrer"&gt;go-mp4&lt;/a&gt; which is Golang library for reading and writing MP4.&lt;/p&gt;

&lt;p&gt;go-mp4 was developed by extending MP4 module of ABEMA which is the video streaming service in Japan.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/abema/go-mp4" rel="noopener noreferrer"&gt;https://github.com/abema/go-mp4&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What's MP4
&lt;/h1&gt;

&lt;p&gt;There are many standards each for video codecs and audio codecs, for example,  AVC, AV1, AAC, MP3, and etc.&lt;br&gt;
However, it is not possible to record/playback the stream under synchronizing video and audio by only codecs.&lt;br&gt;
You should use container like MP4 or MPEG2-TS for the purpose.&lt;br&gt;
Containers can have video, audio, timecode, and other informations.&lt;/p&gt;

&lt;p&gt;ISO/IEC 14496-12 "ISO Base Media File" stipulates the data unit called "Box" (also called "Atom"), tree structure of boxes, and the box types for each role.&lt;br&gt;
And ISO/IEC 14496-14 "MP4 file format" is extension of that.&lt;/p&gt;

&lt;h1&gt;
  
  
  Structure of MP4 (ISO Base Media File Format)
&lt;/h1&gt;

&lt;p&gt;The figure below shows an example of hexdump of MP4.&lt;br&gt;
As mentioned above, it is composed of a collection of data units called box.&lt;br&gt;
The first 4 bytes represent box-size, and the next 4 bytes represent box-type.&lt;br&gt;
(If the box-size can not fit in 4 bytes, 0x00000001 is written in the first 4 bytes, and the box-size is written in 8 bytes of next to the box-type. And if the box-size is 0x00000000, the box continues until EOF.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb9nshqjr93t9ip69i1uz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb9nshqjr93t9ip69i1uz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at moov box, the size is 0x000004b3 (= 1203 bytes).&lt;br&gt;
You can see that this section contains mvhd box and trak box.&lt;br&gt;
Furthermore, the trak box contains tkhd box and mdia box.&lt;br&gt;
Therefore, this data has a tree structure as shown in the following figure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymxjd5d1lfoctzq98uzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fymxjd5d1lfoctzq98uzz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The standard describes the role of each box types, box type order, fields of each box types, and more.&lt;/p&gt;

&lt;h1&gt;
  
  
  About abema/go-mp4
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;When rewriting or adding some boxes, in some situation, it can be implemented easily depending with no library.&lt;br&gt;
However, in order to read or write boxes of deep layer, you have to seek repeatedly to reach to the target boxes. Furthermore, when the box size changes, you must seek back to the box-size of parent and correct it.&lt;br&gt;
I was looking for Golang library which supports many box types and has various uses, but I couldn't find.&lt;/p&gt;

&lt;p&gt;And, I often need to investigate the data of box.&lt;br&gt;
There are many tools available for that, but many of them seems to support only some of boxes or display only some fields of box.&lt;/p&gt;

&lt;p&gt;So, we developed &lt;a href="https://github.com/abema/go-mp4" rel="noopener noreferrer"&gt;abema/go-mp4&lt;/a&gt; to be more general-purpose and to meet these requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration with Your Go App
&lt;/h2&gt;

&lt;p&gt;You can visit to the boxes by depth-first order with the &lt;code&gt;ReadBoxStructure&lt;/code&gt; function as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadBoxStructure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"depth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// Box Type (e.g. "mdhd", "tfdt", "mdat")&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c"&gt;// Box Size&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSupported&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Payload&lt;/span&gt;
        &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadPayload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c"&gt;// Expands children&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Expand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can also extract only boxes which has specific path using the &lt;code&gt;ExtractBox&lt;/code&gt; function as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="c"&gt;// extract tkhd boxes which has path of moov-&amp;gt;trak-&amp;gt;tkhd&lt;/span&gt;
&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxPath&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxTypeMoov&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxTypeTrak&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoxTypeTkhd&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExtractBoxWithPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  CLI Tool
&lt;/h2&gt;

&lt;p&gt;go-mp4 has CLI tool.&lt;br&gt;
For example, you can view the box tree with the &lt;code&gt;mp4tool dump&lt;/code&gt; command.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

$ mp4tool dump sample.mp4
[ftyp] Size=32 MajorBrand="isom" MinorVersion=512 CompatibleBrands=[{CompatibleBrand="isom"}, {CompatibleBrand="iso2"}, {CompatibleBrand="avc1"}, {CompatibleBrand="mp41"}]
[free] (unsupported box type) Size=8 Data=[...] (use -a option to show all)
[mdat] Size=6402 Data=[...] (use -mdat option to expand)
[moov] Size=1836 
  [mvhd] Size=108 ... (use -a option to show all)
  [trak] Size=743 
    [tkhd] Size=92 ... (use -a option to show all)
    [edts] Size=36 
      [elst] Size=28 Version=0 Flags=0x000000 EntryCount=1 Entries=[{SegmentDurationV0=1000 MediaTimeV0=2048 MediaRateInteger=1}]
    [mdia] Size=607 
      [mdhd] Size=32 Version=0 Flags=0x000000 CreationTimeV0=0 ModificationTimeV0=0 TimescaleV0=10240 DurationV0=10240 Pad=false Language="eng" PreDefined=0
      [hdlr] Size=44 Version=0 Flags=0x000000 PreDefined=0 HandlerType="vide" Name="VideoHandle"
              :
              :


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By default, long lines are abbreviated. You can output everything except mdat box with the &lt;code&gt;-a&lt;/code&gt; option.&lt;br&gt;
Using &lt;code&gt;-mdat&lt;/code&gt; option, you can view the mdat box as hex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation with Run-Time Reflection
&lt;/h2&gt;

&lt;p&gt;You can add box types easily to go-mp4.&lt;br&gt;
For example, tfdt box has implemented as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;mp4&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BoxTypeTfdt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;BoxType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;StrToBoxType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tfdt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;AddBoxDef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tfdt&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Tfdt&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;FullBox&lt;/span&gt;                      &lt;span class="s"&gt;`mp4:"extend"`&lt;/span&gt;
  &lt;span class="n"&gt;BaseMediaDecodeTimeV0&lt;/span&gt; &lt;span class="kt"&gt;uint32&lt;/span&gt; &lt;span class="s"&gt;`mp4:"size=32,ver=0"`&lt;/span&gt;
  &lt;span class="n"&gt;BaseMediaDecodeTimeV1&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="s"&gt;`mp4:"size=64,ver=1"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// GetType returns the BoxType&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tfdt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;BoxType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;BoxTypeTfdt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It has just a struct and few implementations.&lt;br&gt;
It is interesting that the version number of tfdt box decides whether the size of BaseMediaDecodeTime is 32 bits or 64 bits.&lt;br&gt;
&lt;code&gt;mp4:"size=32,ver=0"&lt;/code&gt; tag and  &lt;code&gt;mp4:"size=64,ver=1"&lt;/code&gt; tag specifies that.&lt;br&gt;
In most cases you can add a new box type without special logic.&lt;/p&gt;

&lt;p&gt;It is a disadvantage that the evaluation is done at runtime using reflection.&lt;br&gt;
However, the processing cost will be relatively insignificant for many applications.&lt;br&gt;
(Creating a code generator, it will be completely resolved, and it will be easier to support other languages.)&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I have introduced our Golang library for MP4.&lt;/p&gt;

&lt;p&gt;In our company, we are developing more softwares related to video streaming.&lt;br&gt;
If possible, I want to make the such softwares to open source too.&lt;/p&gt;

</description>
      <category>go</category>
      <category>mp4</category>
    </item>
  </channel>
</rss>
