Search code examples
google-castchromecastsmooth-streamingttml

Chromecast add TTML URL to Smooth Stream manifest


I want to update the SmoothStreaming chromecast player with a TTML captions URL in my receiver application. My manifest file does not contain this URL from the start, so I need to add it with:

cast.player.enableCaptions(true, 'ttml', subtitleUrl);

I do this right after the player starts and the meta data is loaded to the media element (as recommended in other post), but when looking at the

protocol.getStreamCount();

I only get two streams: one for video and one for audio. I see no sign of captions there. I have also tried to override the manifest info in the host object (which works well for the license url):

host.updateCaptionsRequestInfo = function (request){
    requestInfo.url=subtitleUrl;
}

But this function is not called until i call the enableCaptions function (and only called if I add the third argument, at which point the third argument is unnecessary since it is overwritten by the updateCationsRequestInfo function).

Do anyone know how to check if the captions request is accepted or rejected somewhere, and how to handle this? It would be better to not use updateCationsRequestInfo() since I then can change subtitles during playback.

Can the issue be that the url doesnt look like a ttml link (it is another format passed through a converter)?

Thank you for the help!

Update concerning CORS:

I logged the ttml-url right before calling player.enableCaptions(), and if i follow the url, I get the ttml file (response headers: Content-Type: text/xml and some CORS-related headers). In google dev tools I cant see anything related to player.enableCaptions(), no errors or success messages. So it is not connected to CORS issues.


Solution

  • I found the part that went wrong! My application had set the captions correctly from the beginning, and when I looked at

    document.getElementById('video').textTracks[0]
    

    in dev tools I saw that it was there (with length===1). But it had nothing under the "cues" key, i.e. no content was loaded from the ttml file. After some testing I found that the problem was with the syntax of presenting times in the ttml file. First row works, second row does not work:

    <p begin="00:00:05.83" end="01:00:15.00"></p>
    <p begin="8.0s" end="1000.0s"></p>
    

    As I have understood, both formats are supported in the ttml format (http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression). It seems that this is something that is not supported by the chromecast browser, or that I have missed something with how ttml time syntax works.

    TTML file for test reference:

    This is the test TTML file that I used when checking where the issue was:

    <tt xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling" xmlns="http://www.w3.org/2006/04/ttaf1">
    <head>
      <styling>
      <style id="defaultCaption" tts:fontSize="24" tts:fontFamily="Arial" tts:fontWeight="normal" tts:fontStyle="normal" tts:textDecoration="none" tts:color="white" tts:backgroundColor="black" tts:textAlign="center"/>
      </styling>
    </head>
      <body style="defaultCaption" id="thebody">
        <div>
        <p begin="00:00:05.83" end="01:00:15.00">
          <metadata ccrow="0" cccol="15"/>
          On screen for 10 sec
        </p>
        <p begin="8.0s" end="1000.0s">
          <metadata ccrow="5" cccol="15"/>
          CCROW 8 COL 15 for 5 sec
        </p>
        </div>
      </body>
    </tt>
    

    And this is what came up in the dev tools:

    document.getElementById('video').textTracks[0]
      > TextTrack {oncuechange: null, activeCues: TextTrackCueList, cues: TextTrackCueList, mode: "showing", language: ""…}
        >  activeCues: TextTrackCueList
        >  cues: TextTrackCueList
          >  0: TextTrackCue
         length: 1
          >  __proto__: TextTrackCueList
           kind: "captions"
           label: ""
           language: ""
           mode: "showing"
           oncuechange: null
        >  __proto__: TextTrack
    

    Under the key textTracks[0].cues there is one object, and that is the one representing the caption that uses the "hh:mm:ss.fraction" syntax. The other is lost when loadaed to the browser. Is this something that might be supported in the future on the chromecast?