Search code examples
iosvideo-streamingchromecast

Streaming live .m3u8 from iOS to Chromecast


Following Google's documentation I can stream both .mp4 and .m3u8 on-demand streams to my Chromecast. When I try to Cast a live stream however the Cast icon fades away then reappears a second later.

Here is a working on-demand stream:

GCKMediaInformation *mediaInformation =
    [[GCKMediaInformation alloc] initWithContentID:
     @"http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8"
                                        streamType:GCKMediaStreamTypeLive
                                       contentType:@"application/x-mpegURL"
                                          metadata:[self getMetadata]
                                    streamDuration:INFINITY
                                        customData:nil];

And here is a non-working live stream.

GCKMediaInformation *mediaInformation =
    [[GCKMediaInformation alloc] initWithContentID:
     @"http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/appleman.m3u8"
                                        streamType:GCKMediaStreamTypeLive
                                       contentType:@"application/x-mpegURL"
                                          metadata:[self getMetadata]
                                    streamDuration:INFINITY
                                        customData:nil];

I've tested both of these in VLC to ensure the streams are actually active.


Solution

  • The second stream doesn't have CORS headers and that is a requirement for adaptive content on Chromecast. You can check that by calling curl -v <url> and then inspecting the headers:

    $ curl -v http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/appleman.m3u8
    *   Trying 8.253.43.126...
    * Connected to vevoplaylist-live.hls.adaptive.level3.net (8.253.43.126) port 80 (#0)
    > GET /vevo/ch1/appleman.m3u8 HTTP/1.1
    > Host: vevoplaylist-live.hls.adaptive.level3.net
    > User-Agent: curl/7.43.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Cache-Control: max-age=2
    < Date: Tue, 24 Nov 2015 15:44:12 GMT
    < Content-Length: 427
    < Content-Type: application/vnd.apple.mpegurl
    < ETag: "6880298-1ab-51c1fc3e9da00"
    < Last-Modified: Thu, 30 Jul 2015 23:07:20 GMT
    < Accept-Ranges: bytes
    < Server: Footprint Distributor V4.11
    < Vary: Accept-Encoding
    < Expires: Tue, 24 Nov 2015 15:44:14 GMT
    < Connection: keep-alive
    

    If you do the same for the first one (that works), you'll get:

    $ curl -v http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8
    *   Trying 23.67.247.168...
    * Connected to qthttp.apple.com.edgesuite.net (23.67.247.168) port 80 (#0)
    > GET /1010qwoeiuryfg/sl.m3u8 HTTP/1.1
    > Host: qthttp.apple.com.edgesuite.net
    > User-Agent: curl/7.43.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Server: Apache
    < ETag: "2b476bddec5a6410f01593dd3244bb86:1299516757"
    < Last-Modified: Mon, 07 Mar 2011 16:52:37 GMT
    < Content-Length: 940
    < Expires: Tue, 24 Nov 2015 15:47:02 GMT
    < Cache-Control: max-age=0, no-cache, no-store
    < Pragma: no-cache
    < Date: Tue, 24 Nov 2015 15:47:02 GMT
    < Connection: keep-alive
    < Set-Cookie: AKID=650047DEB61A8134C38CECC9EC836DF8;expires=Fri, 11-27-2015 00:00:00 GMT; path=/; domain=qthttp.apple.com.edgesuite.net
    < Content-Type: application/x-mpegURL
    < Access-Control-Allow-Origin: *
    < Set-Cookie: CLIENT_SESSION_COOKIE=csid=235AB97C3466663B398A6EC6DA38428C#ct=1448380022#master=sl.m3u8; path=/1010qwoeiuryfg; domain=qthttp.apple.com.edgesuite.net
    < Set-Cookie: CLIENT_VIEWER_COOKIE=78FCBFC2DF7B7BD10F99EEC583042328;expires=Tue, 10-06-2014 00:00:00 GMT; path=/; domain=qthttp.apple.com.edgesuite.net
    

    Note the presence of Access-Control-Allow-Origin: * in the second one and not in the first one.