Search code examples
javatimesimpledateformat

Parse media presentation time from dash manifest java?


In a streaming video dash manifest we receive the period start time as PT461486H44M42.24S. This is basically a timestamp for the media segment to be loaded. Sample will be

  <Period id="C 2022-08-26 08-45-41" start="PT461486H44M42.24S">

I want to know what is this time format? And how can I convert it to long milliseconds. I checked the [SimpleDateFormat] SDF but it doesn't matches.


Solution

  • Your String seems to represent a duration in ISO-8601 format.

    You can use java.time.Duration.parse in order to create a Duration which may give you information about specific unit. Since a duration is an amount of time in contrast to epoch millis, you should not convert Duration.toMillis() to any date or datetime. They are basically totally different.

    Here's an example usage of a Duration derived from your String:

    public static void main(String[] args) {
        // your example String
        String durStr = "PT461486H44M42.24S";
        // parse it to a Duration
        Duration duration = Duration.parse(durStr);
        // create a result message from the units of a Duration
        String durMsg = String.format("%d milliseconds are %d days, %d hours, %d minutes, %d seconds and %d milliseconds",
                                    duration.toMillis(),
                                    duration.toDays(),
                                    duration.toHoursPart(), 
                                    duration.toMinutesPart(), 
                                    duration.toSecondsPart(), 
                                    duration.toMillisPart());
        // print the result message
        System.out.println(durMsg);
    }
    

    Output:

    1661352282240 milliseconds are 19228 days, 14 hours, 44 minutes, 42 seconds and 240 milliseconds
    

    If you suspect the result of duration.toMillis() not to be the length of the video but , for example, the creation timestamp (in epoch millis) or the age in millis, don't use the outdated API (Date, SimpleDateFormat and so on) but use java.time. You can use those millis to create an Instant which you can then use to create a ZonedDateTime of OffsetDateTime:

    // create a Temporal using an Instant and a fixed offset (UTC / +00:00 here)
    OffsetDateTime odt = Instant.EPOCH.plus(duration)
                                      .atOffset(ZoneOffset.UTC);
    // print the result
    System.out.println(odt);
    

    Output:

    2022-08-24T14:44:42.240Z
    

    Different idea:

    You can subtract the parsed Duration from a current moment in time, which – under circumstances – may give you the moment in time of the first media presentation (like when it was released):

    Instant instant = Instant.now().minus(duration);
    OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
    System.out.println(odt);
    

    This just output the following:

    1970-01-01T21:37:52.460090Z
    

    This approach is just an idea and it heavily depends on the duration between receiving the media presentation time (your String) and the calculation involving Instant.now(), which should ideally be the same moment in time in order to get the (most) correct time of the media presentation.