chromecastgoogle-casthttp-live-streaminggoogle-cast-sdkhls.js

Why is Chromecast unable to stream this HLS video? "Neither ID3 nor ADTS header was found" / Error NETWORK/315


I'm trying to stream some URLs to my Chromecast through a sender app. They're HLS/m3u8 URLs.

Here's one such example URL: https://qa-apache-php7.dev.kaltura.com/p/1091/sp/109100/playManifest/entryId/0_wifqaipd/protocol/https/format/applehttp/flavorIds/0_h65mfj7f,0_3flmvnwc,0_m131krws,0_5407xm9j/a.m3u8

However they never seem to load on the Chromecast, despite other HLS/m3u8 URLs working (example of an HLS stream that does work).

It's not related to CORS as they indeed have the proper CORS headers.

I notice they have separate audio groups in the root HLS manifest file.

When I hook it up to a custom receiver app, I get the following logs:

enter image description here

The relevant bits being (I think): Neither ID3 nor ADTS header was found at 0 and cast.player.api.ErrorCode.NETWORK/315 (which I believe is a result of the first)

These are perfectly valid/working HLS URLs. They play back in Safari on iOS and desktop perfectly, as well as VLC.

Is there something I need to be doing (either in my sender app or my receiver app) to enable something like the audio tracks? The docs seem to indicate something about that.

I also found this Google issue where a person had a similar issue, but solved it somehow that I can't understand. https://issuetracker.google.com/u/1/issues/112277373

How would I playback this URL on Chromecast properly? Am I to do something in code?


Solution

  • This already has a solution here but I will add this answer in case someone looks up the exact error message / code.

    The problem lies in the hlsSegmentFormat which is initialized to TS for multiplexed segments but currently defaults to packed audio for HLS with alternate audio tracks.

    The solution is to intercept the CAF LOAD request and set the correct segment format:

    const context = cast.framework.CastReceiverContext.getInstance();
    const playerManager = context.getPlayerManager();
    // intercept the LOAD request
    playerManager.setMessageInterceptor(cast.framework.messages.MessageType.LOAD, loadRequestData => {
                loadRequestData.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.TS;
                return loadRequestData;
    });
    context.start();
    


    Source: Google Cast issue tracker