Git Product home page Git Product logo

castreceiver's People

Contributors

c0d3base avatar gomez-andres avatar jtromo avatar stefanovualto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

castreceiver's Issues

Add Custom Header

I am developing a custom receiver app for an ott platform where we need to send an authorization token as a request header for decrypting our content. Can anyone help me with how I can add the custom header for hls content?

Having some problems following the instructions to get the receiver working.

I have been following the instructions in the README.md file -

I got to point 5 -
Using the Chromecast setup application, make sure [x] send your serial number to Google is checked. This is the only way that you can access your unpublished receiver

I can't find that option on the Google Home app - but equally, I'm not sure what the [x] signifies - does that mean that this is not longer required?

I carried on with the instructions.
Step 7 says :
Enter the App ID of your receiver application into your sender application or one of our sample sender applications listed above.

there are no sample sender applications listed above. Clicking on the link to https://developers.google.com/cast/docs/sample-apps (am I missing something?)

Customised widevine request

We are a DRM provider and as part of our product we need to customise the Widevine request that is sent to the license server. We are seeing that the CAF framework encrypts the post request, as such the license server cannot decrypt the request. We use a token based system, the token need to be added to the request body before being sent. The POST needs to be unencrypted in order for us to use the KID and token to server a license.

I am trying to use the playbackConfig.licenseRequestHandler to add the token and if I breakpoint there and take the request and fire it at our license servers using Curl it works. I am confident it is the framework/CDM encrypting the request, but we don't see this issue in Chrome. any help or suggestions would be happily received.

I have included our licenseRequestHandler function below

function licenseRequestHandler(request) {
        request.body = JSON.stringify({
            token: token,
            drm_info: Array.apply(null, new Uint8Array(request.content)),
            kid: kid
        });

        request.headers['Content-Type'] = 'application/json';
        return request;
    }

HLS with surround sound (5.1) does not work for me.

Hello.
I have a CAF configured, I can change the audio track but when I select an audio track with 5.1 sound, it changes to that track but the receiver does not change to 5.1. Someone can tell me if it requires any extra configuration that tells you to change to 6 channels.

Thx!.

Migration for GameManager APIs?

Hello everyone, I seem to be unfortunately late to the google-cast dev party and wanted to develop a simple casual game for the cast and after looking the reference docs I've seen that they have seem to deprecate the possibility to create games, which is a real shame honestly :/ APIs like the GameManager seemed to be totally awesome, but is now deprecated.
I've seen now that the current API (CAF) doesn't really have the same useful APIs I've seen from the previous v2 for games, so I'd like to know if they were a clear path to migrating to CAF for casual game development, because the official docs don't seem to say anything about this.

Maybe @jtromo has any light to shine on this?
Thank you very much

HLS freeze and authomatic shutdown

Hi,

ISSUE
I'm trying to load a live stream playlist in HLS format but custom receiver is not working. Video is freezing in random moments during any time. After 20 minutes or 30 minutes, chromecast leave session and shutdown it.

MEDIA FORMAT
We are using HLS v3 and HLS v4 version.

FIXES
We try to fix it with HLSSegmentFromat TS or AAC and StreamType LIVE. This configuration is not working.

Have you any idea about what is the problem?

Thank you,
Jesús Martínez

Handling multiple senders in web receiver

Hi Team,

I'm trying a find a solution where multiple senders should not be connected to a receiver.

If a receiver is already connect to a sender and another sender tries to connect, it should disconnect the previous connected sender and connect to the new sender.

Please let me know, how it can be done?

Chromecast receiver with custom header

Hello I have created the chromecast receiver correctly and I can cast dash , mp4 and hls videos correctly. I also implemented drm license request using licenserequesthandler.

I want to know how can I add custom headers to manifestrequest and segment request? I want to check specific headers for media to be streamed like custom User-Agent, adding extra header.

so far I have done:

playbackConfig.manifestRequestHandler = requestInfo => {

 // requestInfo.withCredentials = true;
  requestInfo.headers['User-Agent'] = 'Mozilla 6.0 firefox';
  
  
   };

Cast Receiver Idle timeout

On SDK document, it's said

A Web Receiver app may tear down when "The Web Receiver app has been idle for a defined period of time without any connected senders and decides to end the application session".

Looks it's 5 mins.

Is there some api on receiver or sender side to customize this time?

Thanks

HLS manifests that include in-stream (subtitle) text track(s) fail to load on Chromecast (gen. 1)

sample HLS manifests:

  1. https://cdn.theoplayer.com/video/elephants-dream/playlist-single-audio.m3u8
  2. https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8

rather than going into excruciating detail, I'll summarize:

  • tested on Chromecast gen. 1
  • tested with:
    • Cast Receiver v2
    • Cast Receiver v3 (CAF)
    • chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
  • sample streams won't play
    • other HLS manifests that don't include any in-stream (subtitle) text tracks do play well
      • this generalization also applies to HLS manifests that contain video streams with embedded/muxed closed captions

questions:

  • is this a known issue or limitation
    • I only own gen. 1 devices and haven't tested on newer hardware, which shouldn't matter as this is clearly a software issue
  • do these streams work for you?

questions (not directly related to issue):

  • assuming this issue were fixed, what is the correct way for the sender to manage the visibility of in-stream (subtitle) text tracks?
    • should the master manifest be parsed by the sender and the URL of each inner #EXT-X-MEDIA:TYPE=SUBTITLES manifest be added and managed as an external text track?
  • is there a similar API to manage the visibility of embedded/muxed closed captions?
    • can they even be displayed on the Chromecast?

update: docs for the TextTracksManager class seems to answer these questions

[BUG] setLoggerLevel don't work

I am trying to disable the receiver logs but even running the following command it still displays the logs:

cast.framework.CastReceiverContext.getInstance().setLoggerLevel(cast.framework.LoggerLevel.NONE);

This started to happen after the update on September 9, 2019.

Debug output from Chromecast

Is there a way to get a debug output from the Chromecast? I can successfully cast some videos, but some don't work, and I am having a hard time understanding why (it's an HLS setup).

Would be great if I could see why the Chromecast is not happy, like "Some CORS headers are missing" or "invalid video format" or something, instead of blind guessing.

Is there a way to do that?

How to make video loop on Custom Cast Receiver

On the custom cast receiver, I'm able to play videos successfully. However, once the video ends, the player goes to the IDLE state and shows the default home screen. What I want is to make the same video loop continuously. How to make this happen?

My Index.html

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="css/receiver.css" media="screen" />
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

<body>
  <cast-media-player></cast-media-player>
    <script src="js/receiver.js" type="module"></script>
  </footer>
</body>

</html>

This is how I build my media Request

function buildMediaRequest(exerciseData) {
  const loadRequestData = new cast.framework.messages.LoadRequestData();
  loadRequestData.media = new cast.framework.messages.MediaInformation();
  const metadata = new cast.framework.messages.GenericMediaMetadata();
  metadata.title = exerciseData.exerciseWrap.exercise.name;
  metadata.images = exerciseData.exerciseWrap.exercise.thumbnail;
  loadRequestData.media.contentUrl = exerciseData.exerciseWrap.exercise.media[0].url;
  loadRequestData.media.contentType = 'video/mp4';
  loadRequestData.media.metadata = metadata;
  return loadRequestData;
}

And this is how I play the media

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
...
function playVideo(mediaRequest) {
  playerManager.load(mediaRequest)
    .then(function () {
      playerManager.play();
    });
}

How can I make the same video play continuously once it ends ?

HLS Videos not working

Queue loading fails with " The passed in queueData is not completely valid"

Hello

original case: https://issuetracker.google.com/issues/162640292

Has taken a very long time to get to this point. I have a test case where queue loading fails with this error. I have no idea why as it was working in the past. This api is poorly documented.

It hangs and refuses to play

"cast_receiver_framework.js:114 [ 3.144s] [cast.receiver.MediaQueue] The passed in queueData is not completely valid: [object Object] "

https://dev.electroteque.org/chromecast/

function addItem(index) {
var mediaInfo = new chrome.cast.media.MediaInfo(
mediaContents[index]['sources'][0], 'video/mp4');

        mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
        mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
        mediaInfo.metadata.title = mediaContents[index]['title'];
        mediaInfo.metadata.images = [
            {'url': MEDIA_SOURCE_ROOT + mediaContents[index]['thumb']}];

        return mediaInfo;
    }

       

 /*   var request = new chrome.cast.media.LoadRequest(mediaInfo);
    castSession.loadMedia(request).then(
        this.playerHandler.loaded.bind(this.playerHandler),
        function (errorCode) {
            this.playerState = PLAYER_STATE.ERROR;
            console.log('Remote media load error: ' +
                CastPlayer.getErrorMessage(errorCode));
        }.bind(this));*/

    

    const queueItems = [
        new chrome.cast.media.QueueItem(addItem(0)),
        new chrome.cast.media.QueueItem(addItem(1))
    ];

    console.log("items", queueItems);

    const request = new chrome.cast.media.QueueLoadRequest(queueItems);

    request.startIndex = 0;
    request.currentTime = 0;


    castSession.getSessionObj().queueLoad(request,  () => {
       // console.log(this.session.getMediaSession());
        console.log("queue loaded");
    }, (e) => {
        console.log("queue load error");
    });

Capture

I'm being hassled about queue loading completely broken. Can't figure out what has changed. Any ideas ?

everything I try fails. It seems to try to load the clip but getting a decode error ?

[ 4.183s] [cast.receiver.MediaQueue] The passed in queueData is not completely valid: [object Object]
Fg @ cast_receiver_framework.js:114
cast_receiver_framework.js:114 [ 4.211s] [cast.framework.common.EventHandler] onEvent for load
cast_receiver_framework.js:114 [ 4.386s] [cast.receiver.MediaManager] No need to prefetch more for now.
cast_receiver_framework.js:114 [ 4.404s] [cast.framework.PlayerManager] MediaManagerLoad
cast_receiver_framework.js:114 [ 4.647s] [cast.framework.media.SimplePlayer] loadContent: autoplay = true, initial_time = 9.31929
cast_receiver_framework.js:114 [ 4.676s] [cast.receiver.CastReceiverManager] Dispatching system volume changed event [1, false]
receiver.html:127 Received Metadata Pq
cast_receiver_framework.js:114 [ 8.267s] [cast.framework.media.Player] Setting startAbsoluteTime null
cast_receiver_framework.js:114 [ 8.270s] [cast.receiver.MediaManager] Metadata loaded
receiver.html:118 Media Loaded Vq
receiver.html:151 Media Error Nq
cast_receiver_framework.js:114 [ 8.557s] [cast.receiver.MediaManager] Sending error message to :
cast_receiver_framework.js:114 [ 8.579s] [cast.framework.media.Player] player event: error
cast_receiver_framework.js:114 [ 8.582s] [cast.receiver.MediaManager] Sending error message to :
cast_receiver_framework.js:114 [ 8.616s] [cast.receiver.MediaManager] After 1 jump, transition is: QUEUE_ACTIVE
cast_receiver_framework.js:114 [ 8.621s] [cast.receiver.MediaManager] Dispatching MediaManager load event
cast_receiver_framework.js:114 [ 8.624s] [cast.receiver.MediaManager] Load message received:{"type":"LOAD","requestId":0,"mediaSessionId":1,"media":{"contentId":"//videos.electroteque.org/bitrate/elephants_dream_600k.mp4","streamType":"BUFFERED","contentType":"video/mp4","metadata":{"type":0,"metadataType":0,"title":"Elephants Dream","subtitle":"Subtitle","images":[{"url":"//static.electroteque.org/images/stills/ed_still.jpg"}],"activeTextId":-1,"defaultDolbyAudioIndex":-1},"textTrackStyle":{"foregroundColor":"#FFFFFFFF","backgroundColor":"#FFFFFF00"},"customData":{}},"autoplay":true,"currentTime":0}
cast_receiver_framework.js:114 [ 8.645s] [cast.framework.common.EventHandler] onEvent for load
cast_receiver_framework.js:114 [ 8.737s] [cast.receiver.MediaManager] No need to prefetch more for now.
cast_receiver_framework.js:114 [ 8.749s] [cast.framework.PlayerManager] MediaManagerLoad
cast_receiver_framework.js:114 [ 8.756s] [cast.framework.media.Player] endInternal()
cast_receiver_framework.js:114 [ 8.865s] [cast.framework.media.EmbeddedPlayer] ended
receiver.html:142 Media Finished Tq
cast_receiver_framework.js:114 [ 8.960s] [cast.framework.media.SimplePlayer] loadContent: autoplay = true, initial_time = 0
receiver.html:127 Received Metadata Pq {type: "LOADED_METADATA", currentMediaTime: 0}
cast_receiver_framework.js:114 [ 14.784s] [cast.framework.media.Player] Setting startAbsoluteTime null
cast_receiver_framework.js:114 [ 14.805s] [cast.receiver.MediaManager] Metadata loaded
receiver.html:118 Media Loaded Vq {type: "PLAYER_LOAD_COMPLETE", media: {…}}
receiver.html:151 Media Error Nq {type: "ERROR", detailedErrorCode: 102, reason: undefined, error: undefined}
cast_receiver_framework.js:114 [ 15.322s] [cast.receiver.MediaManager] Sending error message to :
cast_receiver_framework.js:114 [ 15.392s] [cast.framework.media.Player] player event: error
cast_receiver_framework.js:114 [ 15.403s] [cast.receiver.MediaManager] Sending error message to :
cast_receiver_framework.js:114 [ 15.467s] [cast.framework.media.Player] reset()
cast_receiver_framework.js:114 [ 15.497s] [cast.framework.media.Player] endInternal()
cast_receiver_framework.js:114 [ 15.924s] [cast.framework.media.EmbeddedPlayer] ended
receiver.html:142 Media Finished Tq {type: "MEDIA_FINISHED", currentMediaTime: 0, endedReason: "ERROR"}

Built In TV chromecast not being recognized

I have an Android sender app that is working fine with a Web Receiver, using the chromecast device connected to the TV.
But I also have a TV with a built in chromecast that is not being recognized by the sender app. Apparently only YouTube and Netflix are able to discover the built in chromecast.
Do I need an Android TV application to be able to discover the TV built in chromecast?

Example not working, websocket failed

Receiver code doesn't work, there is an issue with debugger and 'is_device_registered' of null error.
Disabling debugger fails with websocket error:
WebSocket connection to 'ws://localhost:8008/v2/ipc' failed:

--playback-logo-image not working...

Hi, I have set up the CastReceiver and published it to surge. It is showing correctly when using the web sender project, apart from this issue - the playback-logo-image is not showing up on the while playing on the device. I've tried using the same image as a watermark in the css file and it shows correctly then. Any ideas?

Cast firmware version: 1.56.275994

2100 Error when casting IPTV Stream

Hello,

I'm trying to figure out why doesnt work when I send to my Chromecast a m3u link.

http://xxxxxxxxxxxxcom:8080/live/RKDKB8Cr4V37/8JfpnuE7rpb8/51739.m3u8 Here is my url(if i try it with vlc it works, i can put mp4 or hls extension and it works.

I tried also using postman to see if i can get any information and this is the respond:


#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1678748892
#EXTINF:10.000000,
/play/hls-nginx/d12dbe3a-c0d6-428a-ae75-95250533f484/d12dbe3a-c0d6-428a-ae75-95250533f484_1678748892.ts?token=eyJpdiI6IlAxUDFObUtHSFQ4QmV4aHZtc0Q5R0E9PSIsInZhbHVlIjoiaTFMdUVocUtkc1BOZHA0N3k3aW93cEVOSXZ6clRxaFdOQjFjOXVUK01WTEt5QWpEblZkMHJSTFdyQ2N5SkJaTyIsIm1hYyI6ImUyYTBhNzY0ZGEzZjI1ZjJjNTVjZmYwOTI3MGNlMmFjMDIyYmYzNGVlMGIyMjk1MTkyOTUzMDVmYTRiZTg0NmUiLCJ0YWciOiIifQ%3D%3D&h=0a07dfdd03cb1b1146948306c052a99f&r=64844b&rt=b2daff51c1cee53bcbacd440bbcb4c8a&lvtoken=eyJpdiI6IjhmcHd5dWQxdUhqcjF4QjA2VDFVeFE9PSIsInZhbHVlIjoiZS9MN0FCMUlaYWpvUGlaS0dwcHBQbkhRSzdyblFZdjZYZHNUbHNsSGIvYk1HWUlpMHNEUGFkUUFGVlcva0kwZ3Z4dFNEN1RKSXV6bm9RamNLcmpGcUo3MFNvRVBZTDkxOXA3QTR0NDdBVGE4NllYb0pzR1VaSUxPVUVoY0F3ZTBYUENrZ0pjRys3aTF4WFpVcTdJSFBKY0FhUjE4S3A5R3JId2FWMmpkREtBZDhYcmo5d3dXNnlrek43a1Awd3ZzVDdmNFZEci9YYkkxOFJidC9PaHFBZz09IiwibWFjIjoiZWE1MzE0OTQyNmZjMzI0M2FiMDkwYTUzMTkwMzk1MTlmZTdiZTlhMWE2MzE4ZThkZmNiOGRiNWEwYTBhNWFjMCIsInRhZyI6IiJ9
#EXTINF:10.000000,
/play/hls-nginx/d12dbe3a-c0d6-428a-ae75-95250533f484/d12dbe3a-c0d6-428a-ae75-95250533f484_1678748893.ts?token=eyJpdiI6IlAxUDFObUtHSFQ4QmV4aHZtc0Q5R0E9PSIsInZhbHVlIjoiaTFMdUVocUtkc1BOZHA0N3k3aW93cEVOSXZ6clRxaFdOQjFjOXVUK01WTEt5QWpEblZkMHJSTFdyQ2N5SkJaTyIsIm1hYyI6ImUyYTBhNzY0ZGEzZjI1ZjJjNTVjZmYwOTI3MGNlMmFjMDIyYmYzNGVlMGIyMjk1MTkyOTUzMDVmYTRiZTg0NmUiLCJ0YWciOiIifQ%3D%3D&h=84047e9182986a42281c985676a0005c&r=64844b&rt=b2daff51c1cee53bcbacd440bbcb4c8a&lvtoken=eyJpdiI6IjhmcHd5dWQxdUhqcjF4QjA2VDFVeFE9PSIsInZhbHVlIjoiZS9MN0FCMUlaYWpvUGlaS0dwcHBQbkhRSzdyblFZdjZYZHNUbHNsSGIvYk1HWUlpMHNEUGFkUUFGVlcva0kwZ3Z4dFNEN1RKSXV6bm9RamNLcmpGcUo3MFNvRVBZTDkxOXA3QTR0NDdBVGE4NllYb0pzR1VaSUxPVUVoY0F3ZTBYUENrZ0pjRys3aTF4WFpVcTdJSFBKY0FhUjE4S3A5R3JId2FWMmpkREtBZDhYcmo5d3dXNnlrek43a1Awd3ZzVDdmNFZEci9YYkkxOFJidC9PaHFBZz09IiwibWFjIjoiZWE1MzE0OTQyNmZjMzI0M2FiMDkwYTUzMTkwMzk1MTlmZTdiZTlhMWE2MzE4ZThkZmNiOGRiNWEwYTBhNWFjMCIsInRhZyI6IiJ9
#EXTINF:10.000000,
/play/hls-nginx/d12dbe3a-c0d6-428a-ae75-95250533f484/d12dbe3a-c0d6-428a-ae75-95250533f484_1678748894.ts?token=eyJpdiI6IlAxUDFObUtHSFQ4QmV4aHZtc0Q5R0E9PSIsInZhbHVlIjoiaTFMdUVocUtkc1BOZHA0N3k3aW93cEVOSXZ6clRxaFdOQjFjOXVUK01WTEt5QWpEblZkMHJSTFdyQ2N5SkJaTyIsIm1hYyI6ImUyYTBhNzY0ZGEzZjI1ZjJjNTVjZmYwOTI3MGNlMmFjMDIyYmYzNGVlMGIyMjk1MTkyOTUzMDVmYTRiZTg0NmUiLCJ0YWciOiIifQ%3D%3D&h=8ef1cd3b36fe086a3896aa62d8869314&r=64844b&rt=b2daff51c1cee53bcbacd440bbcb4c8a&lvtoken=eyJpdiI6IjhmcHd5dWQxdUhqcjF4QjA2VDFVeFE9PSIsInZhbHVlIjoiZS9MN0FCMUlaYWpvUGlaS0dwcHBQbkhRSzdyblFZdjZYZHNUbHNsSGIvYk1HWUlpMHNEUGFkUUFGVlcva0kwZ3Z4dFNEN1RKSXV6bm9RamNLcmpGcUo3MFNvRVBZTDkxOXA3QTR0NDdBVGE4NllYb0pzR1VaSUxPVUVoY0F3ZTBYUENrZ0pjRys3aTF4WFpVcTdJSFBKY0FhUjE4S3A5R3JId2FWMmpkREtBZDhYcmo5d3dXNnlrek43a1Awd3ZzVDdmNFZEci9YYkkxOFJidC9PaHFBZz09IiwibWFjIjoiZWE1MzE0OTQyNmZjMzI0M2FiMDkwYTUzMTkwMzk1MTlmZTdiZTlhMWE2MzE4ZThkZmNiOGRiNWEwYTBhNWFjMCIsInRhZyI6IiJ9
#EXTINF:10.000000,
/play/hls-nginx/d12dbe3a-c0d6-428a-ae75-95250533f484/d12dbe3a-c0d6-428a-ae75-95250533f484_1678748895.ts?token=eyJpdiI6IlAxUDFObUtHSFQ4QmV4aHZtc0Q5R0E9PSIsInZhbHVlIjoiaTFMdUVocUtkc1BOZHA0N3k3aW93cEVOSXZ6clRxaFdOQjFjOXVUK01WTEt5QWpEblZkMHJSTFdyQ2N5SkJaTyIsIm1hYyI6ImUyYTBhNzY0ZGEzZjI1ZjJjNTVjZmYwOTI3MGNlMmFjMDIyYmYzNGVlMGIyMjk1MTkyOTUzMDVmYTRiZTg0NmUiLCJ0YWciOiIifQ%3D%3D&h=7fb169d8011c5ba4aceea8c2aeeee36e&r=64844b&rt=b2daff51c1cee53bcbacd440bbcb4c8a&lvtoken=eyJpdiI6IjhmcHd5dWQxdUhqcjF4QjA2VDFVeFE9PSIsInZhbHVlIjoiZS9MN0FCMUlaYWpvUGlaS0dwcHBQbkhRSzdyblFZdjZYZHNUbHNsSGIvYk1HWUlpMHNEUGFkUUFGVlcva0kwZ3Z4dFNEN1RKSXV6bm9RamNLcmpGcUo3MFNvRVBZTDkxOXA3QTR0NDdBVGE4NllYb0pzR1VaSUxPVUVoY0F3ZTBYUENrZ0pjRys3aTF4WFpVcTdJSFBKY0FhUjE4S3A5R3JId2FWMmpkREtBZDhYcmo5d3dXNnlrek43a1Awd3ZzVDdmNFZEci9YYkkxOFJidC9PaHFBZz09IiwibWFjIjoiZWE1MzE0OTQyNmZjMzI0M2FiMDkwYTUzMTkwMzk1MTlmZTdiZTlhMWE2MzE4ZThkZmNiOGRiNWEwYTBhNWFjMCIsInRhZyI6IiJ9
#EXTINF:10.000000,
/play/hls-nginx/d12dbe3a-c0d6-428a-ae75-95250533f484/d12dbe3a-c0d6-428a-ae75-95250533f484_1678748896.ts?token=eyJpdiI6IlAxUDFObUtHSFQ4QmV4aHZtc0Q5R0E9PSIsInZhbHVlIjoiaTFMdUVocUtkc1BOZHA0N3k3aW93cEVOSXZ6clRxaFdOQjFjOXVUK01WTEt5QWpEblZkMHJSTFdyQ2N5SkJaTyIsIm1hYyI6ImUyYTBhNzY0ZGEzZjI1ZjJjNTVjZmYwOTI3MGNlMmFjMDIyYmYzNGVlMGIyMjk1MTkyOTUzMDVmYTRiZTg0NmUiLCJ0YWciOiIifQ%3D%3D&h=bb9fc9d66cc59c0394154329de3983e4&r=64844b&rt=b2daff51c1cee53bcbacd440bbcb4c8a&lvtoken=eyJpdiI6IjhmcHd5dWQxdUhqcjF4QjA2VDFVeFE9PSIsInZhbHVlIjoiZS9MN0FCMUlaYWpvUGlaS0dwcHBQbkhRSzdyblFZdjZYZHNUbHNsSGIvYk1HWUlpMHNEUGFkUUFGVlcva0kwZ3Z4dFNEN1RKSXV6bm9RamNLcmpGcUo3MFNvRVBZTDkxOXA3QTR0NDdBVGE4NllYb0pzR1VaSUxPVUVoY0F3ZTBYUENrZ0pjRys3aTF4WFpVcTdJSFBKY0FhUjE4S3A5R3JId2FWMmpkREtBZDhYcmo5d3dXNnlrek43a1Awd3ZzVDdmNFZEci9YYkkxOFJidC9PaHFBZz09IiwibWFjIjoiZWE1MzE0OTQyNmZjMzI0M2FiMDkwYTUzMTkwMzk1MTlmZTdiZTlhMWE2MzE4ZThkZmNiOGRiNWEwYTBhNWFjMCIsInRhZyI6IiJ9


And the respond to http://xxxxxxxx.com:8080/player_api.php?username=nSqriPE5Zi&password=xrMcCgsp7r&action=get_vod_info&vod_id=51739 :

{ "info": { "movie_image": "", "name": "LA 1 HD 720P", "tmdb_id": "", "backdrop": "", "youtube_trailer": "", "genre": "", "plot": "", "cast": "", "rating": "", "director": "", "releasedate": "", "backdrop_path": [], "duration_secs": 0, "duration": "" }, "movie_data": { "stream_id": 51739, "name": "LA 1 HD 720P", "added": "1615332545", "category_id": "48", "container_extension": "", "custom_sid": "", "direct_source": "" } }

and respond to : http://xxxxxxxxxxxx.com:8080/player_api.php?username=nSqriPE5Zi&password=xrMcCgsp7r

{ "user_info": { "username": "nSqriPE5Zi", "password": "xrMcCgsp7r", "message": "", "auth": 1, "status": "Active", "exp_date": "1680553979", "is_trial": "0", "active_cons": "0", "created_at": "1672969309", "max_connections": "2", "allowed_output_formats": [ "m3u8", "ts" ] }, "server_info": { "url": "xxxxxxxxxxxx.com", "port": "8080", "https_port": "", "server_protocol": "http", "rtmp_port": "0", "timezone": "UTC", "timestamp_now": 1678749598, "time_now": "2023-03-13 23:19:58", "process": true } }

I tried this one for example https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/hls/DesigningForGoogleCast.m3u8 and it works perfectly so im a little bit lost.

Why my url is not working?

I also tried using https://casttool.appspot.com/cactool but i couldn't see any relevant log or information.

Hope you can help me.

ENH: Chromecast Receiver API (?): "Like API"

As a Chromecast and Google Home and Google Assistant User, I would like to "Like" the currently playing media track in a standard way.

Use cases:

How to get remote control interactions

I have a Chromecast 3rd generation (USB dongle) and I would like to know how it is possible to know if a user has pressed a button on the remote. Please note that the use of <button> does not work.

After spending 5 hours reading the documentation, I still haven't found any information to do this.
What's the point of allowing to get rid of <cast-media-player> if it's not possible to retrieve the remote control's interactions?

Cast receiver unable to play video url having redirection

We have developed a Custom Cast Receiver (registered on Cast Console)

The cast receiver smoothly plays a video whose URL does not have any redirection.
However, if the video URL contains a redirection, the cast receiver fails with a 311 error.

I'm posting the curl responses for both types of videos URL

Type 1: Video URL without any redirection (this video plays on the receiver)

Screenshot 2022-01-27 at 6 13 55 PM

Type 2: Video URL with redirection (this video does not play on the receiver)

Screenshot 2022-01-27 at 6 15 06 PM

Also posting the error-response from cast receiver

Screenshot 2022-01-27 at 6 19 28 PM

Looks like, the custom receiver is unable to handle URL redirection. Any way to enable redirection?

Sample for googlecast-v2 custom receiver code

Hi, I am looking for sample code of custom receiver of v2 SDK, this doesn't seem to be working. Since we are on v2 SDK we need a reference for the example to check few things. Can you please help me in finding this?

BreakClip mime-type "application/x-mpegURL" error

Hello,

I am getting this error when i am trying to add Ad Breaks a VMAP Ad URL.
I tested with the doubleclick ad server.
When the VAST INLINE reponse from the ad server provides a MediaFile withe the mime-type "application/x-mpegURL", the Cast SDK throws and error 104.
Find below some logs :

app.js:1433 MediaCast.onPlayerLoadComplete
app.js:1433 sendStreamInformation: {"version":1,"action":"stream_information","duration":2108}
cast_receiver_framework.js:116 [ 6.103s] [cast.framework.media.util] cannot guess mime type from given contenId/Type. Assume that this is video/mp4
th @ cast_receiver_framework.js:116
2app.js:1433 Media Manager MEDIA STATUS
app.js:1433 MediaCast.onLoadStart
app.js:1433 MediaCast.setState LOAD
app.js:454 ---> STATE :: LOAD
app.js:1433 MediaCast.isMediaState
app.js:1433 MediaCast.clearTimerState
cast_receiver_framework.js:116 [ 6.219s] [StitchingPlayer] player event: break clip error
cast_receiver_framework.js:116 [ 6.224s] [cast.receiver.MediaManager] Sending error message to :
app.js:1433 Media Manager ERROR: {"type":"ERROR","detailedErrorCode":104}
app.js:1433 MediaCast.onError

It seems to be case sensitive issue. When i try with an other static URL where i can change the type to "application/x-mpegurl", it works.
In SDK Cast, i do not find an api to set the list of accepted mime-types.

Have someone already experienced this error ?

window size small, how to change width and height?

Hi, i am developing an app to show a html5 site in Angular and send commands whit another site. but in Chromecast Ultra the site is showing size 1280 x 720, now I change to Chromecast 4 whit google TV and the size is 960 x 540, is there a way to configure this size in receiver?

thanks
chromecast size

Local network HTTP media stream no longer functional

It isn't uncommon for people to have media servers where there is a published Cast receiver app which plays an audio stream from a local network URL, e.g. http://10.0.0.6:1234/stream.mp3. (I am the developer of one such device.)

Until a few days ago this worked. Now (since a recent Cast firmware update) it does not. Looking in the Chrome debug console, the issue is that, even though loadRequestData.media.contentUrl is correct (e.g. 'http://10.0.0.6:1234/stream.mp3'), the actual request coming from the Cast device is the same but HTTPS (e.g. 'https://10.0.0.6:1234/stream.mp3'). So the media server's HTTP server sees an incoming connection and instead of seeing GET /stream.mp3 HTTP/1.1 in plaintext it sees a binary SSL handshake and goes crazy.

There doesn't appear to be any sensible way around this. 'Fixing' the media server to run an HTTPS server instead of HTTP, the Cast request still fails because now there's a self-signed cert.

Is this a deliberate 'break' or an accident, and in either case how do I proceed? Thank you!

Edit: this still works fine when casting to the default media receiver. It only breaks for custom receivers. Is there some new setting (not documented?) I need to set in the custom receiver to allow this?

AES-128 encryption in receiver app

Hi, I'm working on custom web-receiver and can't get it to work properly. Current flow:

  1. I receive m3u8 which looks like this (short version) :
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:9
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://custom_link_to_get_key/",IV="someCode"
#EXTINF:9.010222,
hls_0.ts
#EXTINF:9.010222,
hls_1.ts

  1. Receiver app takes URI="https://custom_link_to_get_key/ and fails with 314 error code. Detailed error from backend tells me that i'm not sending required headers. I have almost 0 knowledge in javascript so please check the short version of my receiver app (i suspect that i might be setting headers in the wrong way, i'm also 100 percent sure that when .LOAD request is intercepted all of the headers are available (A,B,C etc)) :
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const playbackConfig = new cast.framework.PlaybackConfig();

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
        const requestData = JSON.stringify(request);
        const requestObj = JSON.parse(requestData);
        const headers = {};
        headers['A'] = requestObj.media.customData.A;
        headers['B'] = requestObj.media.customData.B;
        headers['C'] = requestObj.media.customData.C;
        headers['D'] = requestObj.media.customData.D;
        headers['E'] = requestObj.media.customData.E;
        headers['F'] = requestObj.media.customData.F;

        request.media.contentType = HLS_STREAM_TYPE;
        request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.TS;

        const playbackConfig = (Object.assign(new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
        playbackConfig.autoResumeNumberOfSegments = 1;

        playbackConfig.manifestRequestHandler = requestInfo => {
            requestInfo.headers = {headers};
            requestInfo.withCredentials = true;
        };

        playbackConfig.segmentRequestHandler = requestInfo => {
            requestInfo.headers = {headers};
            requestInfo.withCredentials = true;
        };

        playbackConfig.licenseRequestHandler= requestInfo => {
            requestInfo.headers = {headers};
            requestInfo.withCredentials = true;
        };

        playerManager.setPlaybackConfig(playbackConfig);
        return request;
    });

context.start({playbackConfig: playbackConfig});
  1. As i understand playbackConfig.licenseRequestHandler is used when receiver app tries to get the "decryption key" and it looks like headers are in place, that's why i'm not sure what is wrong.

  2. Cast error code is 314, and short version of the error request status is {"errorCode:6, status:0, response headers: "", response:null}

If someone can tell me what i'm doing wrong here, it will be greatly appreciated. (or at least share code sample for WebReceiver app with AES 128 encryption)

Chromecast update results in crash when using serviceWorkers

Gen1, Gen2, Chromecast, ChromecastUltra, Build-in chromecast all crash when registering a service worker (While it works on a normal webpage)

When you run this code, the chromecast will just crash "Something went wrong"

navigator.serviceWorker.register('sw.js', {scope: './'}).then(function() {
  console.log('Success!')
}, function(err) {
  console.log(err)
})

https://github.com/google/shaka-player/issues/2205

This code worked fine on old firmware, but suddenly all cast devices crash on calling a service worker ( no matter the content of the worker)

Any ideas why this is?

Question : Is there anyway to catch timelineregionenter event from shaka player ?

Hi !

I am presently trying to do ad insertion. While I know this could be done with Ad Breaks, I was hoping to catch ad event directly from my manifest. At first I was trying to catch EMSG_EVENT with this manifest but no event where triggered :

<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" maxSegmentDuration="PT1.003S" mediaPresentationDuration="PT23M34.109792S" minBufferTime="PT0S" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static">
   <Period id="1" start="PT0S">
      <BaseURL>https://my-base-url</BaseURL>      
      <EventStream schemeIdUri="urn:mpeg:dash:event:callback:2015" timescale="1" value="1">
         <Event id="2" messageData="https://some-reporting-urn1" presentationTime="2"/>
         <Event id="3" messageData="https://some-reporting-urn2" presentationTime="5"/>
      </EventStream>
      <AdaptationSet bitstreamSwitching="true" contentType="video" group="1" id="1" maxFrameRate="30000/1001" maxHeight="1080" maxWidth="1920" mimeType="video/mp4" par="16:9" segmentAlignment="true" startWithSAP="1">
         <SegmentTemplate initialization="S!d0FEQVNIVP7...8Bnw__/QualityLevels($Bandwidth$)/Fragments(video=Init)" media="S!d0FEQVNIVP7...8Bnw__/QualityLevels($Bandwidth$)/Fragments(video=$Time$)" timescale="10000000">
            <SegmentTimeline>
               <S d="10010000" r="9"/>
               <S d="2000000" r="0"/>
            </SegmentTimeline>
         </SegmentTemplate>
         <Representation bandwidth="325950" codecs="avc1.4d4015" frameRate="30000/1001" height="270" id="dzE--QSf" sar="1:1" width="480"/>
         <Representation bandwidth="631425" codecs="avc1.4d401e" frameRate="30000/1001" height="360" id="dzGBogmf" sar="1:1" width="640"/>
         <Representation bandwidth="1236504" codecs="avc1.4d401e" frameRate="30000/1001" height="480" id="dzEY3hKf" sar="1:1" width="720"/>
         <Representation bandwidth="1939045" codecs="avc1.4d401f" frameRate="30000/1001" height="540" id="dzFllh2f" sar="1:1" width="960"/>
         <Representation bandwidth="3747150" codecs="avc1.64001f" frameRate="30000/1001" height="720" id="dzFOLTmf" sar="1:1" width="1280"/>
         <Representation bandwidth="4945982" codecs="avc1.64001f" frameRate="30000/1001" height="720" id="dzE-eEuf" sar="1:1" width="1280"/>
         <Representation bandwidth="5555565" codecs="avc1.640028" frameRate="30000/1001" height="1080" id="dzFtxVSf" sar="1:1" width="1920"/>
      </AdaptationSet>
      <AdaptationSet bitstreamSwitching="true" contentType="audio" group="2" id="2" lang="und" mimeType="audio/mp4" segmentAlignment="true">
         <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
         <SegmentTemplate initialization="S!d0FEQVNIVP7...8Bnw__/QualityLevels($Bandwidth$)/Fragments(audio_482_und=Init)" media="S!d0FEQVNIVP7...8Bnw__/QualityLevels($Bandwidth$)/Fragments(audio_482_und=$Time$)" presentationTimeOffset="14" timescale="32000">
            <SegmentTimeline>
               <S d="32767" r="0" t="14"/>
               <S d="31744" r="0"/>
               <S d="31745" r="0"/>
               <S d="32767" r="0"/>
               <S d="31745" r="0"/>
               <S d="31744" r="1"/>
               <S d="32767" r="0"/>
               <S d="31745" r="0"/>
               <S d="31744" r="0"/>
               <S d="7168" r="0"/>
            </SegmentTimeline>
         </SegmentTemplate>
         <Representation audioSamplingRate="32000" bandwidth="40000" codecs="mp4a.40.2" id="dyHiAZ8."/>
      </AdaptationSet>
   </Period>
</MPD>

Then I decided to try this manifest directly on Shaka player. I found out that the good events to listen to for this syntax of ad event where timelineregionenter and timelineregionexit. These events are triggered by Shaka when encountering EventStream with sub Event while emsg events are triggered when encountering InbandEventStream. I have the impression that CAF EMSG_EVENT will only be triggered by InbandEventStream.

So, my question : is there anyway to catch timelineregionenter or timelineregionexit events on CAF Receiver ?

Thank you :)

VMAP/Vast has a fixed wrapper limit (that is too small)

I am currently integrating ads into a cast receiver app via Google Ad Managers VMAP support.
Unfortunately, I noticed that it basically does not work for us for 99% of the time.

After digging around and enabling the debug mode I noticed the following:

[cast.framework.breaks.vast.VastManager] Fail to load VAST ads. Error: Number of redirects exceeded the set limit. 

I enabled the logger for this:

cast.debug.CastDebugLogger.getInstance().loggerLevelByTags = {
        "cast.framework.breaks.vast.VastManager": cast.framework.LoggerLevel.DEBUG,
    };

I then tried to find a way to configure this limit some where but noticed that the number is a constant in the code. (Screenshot via Chrome Dev Tools).

image

This is currently blocking the usage of the ad provider smartclip, a very large ad provider in Germany.
I would like to have a way to increase that number.

I can provide an ad call if necessary, privately would be appreciated.

I also created an issue here, because I was unsure where it belongs.

Behavior when stop Cast on android with Android TV receiver.

Currently, we implement chromecast on Android TV receiver. We have an issue bellow need you confirm: When use android 11 device cast to android TV receiver after that we disconnect cast on android 11 device then android TV receiver force to home (it is different with android under 11 devices. On android under 11 when disconnect on it then app on android TV receiver still playing). So we need confirm behavior when disconnect Cast on android device is force app to home or app still playing. Please help us confirm on it.

Thanks and regards,
Nam

Http authorization header isn't working

I am trying to create a receiver which can play hls / dash media with http authorization header
In the receiver.js I have done like this

    var header_now = {}
    if (customData.user_agent) {
        header_now['User-Agent'] = customData.user_agent
    }
    if (customData.origin) {
        header_now['Origin'] = customData.origin
    }
    if (customData.token) {
        header_now['Token'] = customData.token
    }
    if (customData.referer) {
        header_now['Referer'] = customData.referer
    }
    console.log("header " + header_now);

    playbackConfig.licenseRequestHandler = requestInfo => {
        if (header_now)
            requestInfo.headers = header_now;
        if (typeof customData.withCredentials === 'boolean') {
            requestInfo.withCredentials = customData.withCredentials;
        }
    };
    playbackConfig.manifestRequestHandler = requestInfo => {
        if (header_now)
            requestInfo.headers = header_now;
        if (typeof customData.withCredentials === 'boolean') {
            requestInfo.withCredentials = customData.withCredentials;
        }
    };
    playbackConfig.segmentRequestHandler = requestInfo => {
        if (header_now)
            requestInfo.headers = header_now;
        if (typeof customData.withCredentials === 'boolean') {
            requestInfo.withCredentials = customData.withCredentials;
        }
    };

but it's giving me 3116403 error , how to fix this

Switching from Media element to another media element

Hello ,

I am developing Chrome Cast Receiver App that casting normal videos and Youtube videos with custome code , loading youtube video working fine but once i switch to another player nothing work it keeps dely loading the veido segments
I use the following to set the media element for the youtube videos
playerManager.setMediaElement(yt_video_fake);
and for normal video i use this
playerManager.setMediaElement(document.getElementById('cast-player'));

the problem happen when switching from youtube video to non youtube I got the following errors

image
image

any help ?

How to replace the default controls overlay with the custom controls

Hi, I'm using a custom web receiver and added some custom controls to my player but I'm not able to interact to it with Chromecast remote due to default controls overlay. Is it possible to get rid of default control overlay and make custom controls interactive? If not, then how to add a skip intro button to the default controls overlay?

Custom Receiver

Friends have you any idea how to create custom receiver with css implement in android
Please help me

Netflix POST

Hey,

How can I start a Netflix movie or a Netflix series?

What I already tried:

var stream = nodecast.find();
stream.on('device', function(device) {
	console.log('Found device', device.name);
	var youtube = device.app('Netflix');
	youtube.start('movieid=80111501', function(err) {
		if (err) console.log('error starting', err);
		console.log('Started on', device.name);
	});
});

but I got this error:

     error: { Error: cannot POST /DIAL/apps/Netflix (415)
          at Response.toError (C:\Users\**\Desktop\Elias\Projects\JS\TestCast\node_modules\superagent\lib\node\response.js:94:15)
          at ResponseBase._setStatusProperties (C:\Users\**\Desktop\Elias\Projects\JS\TestCast\node_modules\superagent\lib\response-base.js:123:16)
          at new Response (C:\Users\**\Desktop\Elias\Projects\JS\TestCast\node_modules\superagent\lib\node\response.js:41:8)
          at Request._emitResponse (C:\Users\**\Desktop\Elias\Projects\JS\TestCast\node_modules\superagent\lib\node\index.js:752:20)
          at IncomingMessage.parser (C:\Users\**\Desktop\Elias\Projects\JS\TestCast\node_modules\superagent\lib\node\index.js:916:38)
          at IncomingMessage.emit (events.js:187:15)
          at endReadableNT (_stream_readable.js:1098:12)
          at process.internalTickCallback (internal/process/next_tick.js:72:19)
        status: 415```

Change codecs in manifest

  • The problem occurs on the physical device
  • Sender: Redmi Note 8 Pro
  • Device with chromecast: Android Box
  • Chromecast built-in: 1.56.276477
  • CAST SDK CAF Version: 3.0.0103

Now only videos with the “avc1.4D401F” codec work for me. Videos with codecs “avc1.64001E”, “avc1.640020”, “avc1.4D4029” do not work. Due to the fact that google cast supports the "avc1.4D401F" codec, I want to replace the non-working codecs in the manifest with "avc1.4D401F".

From the google cast documentation:

manifestHandler

Handler to process manifest data. The handler is passed the manifest, and returns the modified manifest.

Therefore, in manifestHandler I replace the line with codecs.

playbackConfig.manifestHandler = data => {
 updateManifest = function(manifest) {
  return manifest.replace(/avc1.(\w*)/gi, 'avc1.4D401F');
 };
 const newManifest = updateManifest(data);
  return new Promise((resolve, _reject) => {
   resolve(newManifest);
  });
};

I made sure that the function works and really changes the values in the manifest. Tested replacing different parts of the manifest.
However, when I try to change the codec, it does not help. Maybe something else needs to be changed along with the codec?

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const playbackConfig = new cast.framework.PlaybackConfig();

cast.framework.CastReceiverOptions.useLegacyDashSupport = true;

const ContentType = {
  DASH: 'application/dash+xml',
  HLS: 'application/x-mpegurl'
};
const mediaFormatID = {
  DASH: 2,
  HLS: 4
};

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);

// Show debug overlay
//castDebugLogger.showDebugLogs(true);

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
};

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    LOG_TAG: cast.framework.LoggerLevel.DEBUG,
};

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    return new Promise((resolve, _reject) => {

      // Configure player to parse DASH content
      if (request.media.metadata.mediaFormatID == mediaFormatID.DASH) {
        request.media.contentUrl = request.media.contentUrl;
        request.media.contentType = ContentType.DASH;

        // Customize the license url for playback
        if (request.media.metadata.licenseUrl) {
          playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
          playbackConfig.licenseUrl = request.media.metadata.licenseUrl;


          let token = request.media.metadata.token;
          let contentId = request.media.metadata.contentId;

          playbackConfig.licenseRequestHandler = requestInfo => {
            let body = {
                token: token,
                drm_info: Array.apply(null, new Uint8Array(requestInfo.content)),
                contentId: contentId
            };

            body = JSON.stringify(body);
            requestInfo.content = body;

            requestInfo.headers["Content-Type"] = "application/json";
          };
        }

      } else {
        request.media.contentType = ContentType.HLS;
        request.media.contentUrl = request.media.contentUrl;
        request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.TS;
        request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.MPEG2_TS;
      }

      castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

      // Add metadata
      let metadata = new cast.framework.messages.GenericMediaMetadata();

      metadata.title = request.media.metadata.title;
      metadata.subtitle = request.media.metadata.subtitle;

      request.media.metadata = metadata;

      resolve(request);

    });
  });

  playbackConfig.licenseHandler = data => {
    return new Promise((resolve, _reject) => {
      resolve(new Uint8Array(data));
    });
  };


  playbackConfig.manifestHandler = data => {
    updateManifest = function(manifest) {
      return manifest.replace(/avc1.(\w*)/gi, 'avc1.4D401F');
    };

    const newManifest = updateManifest(data);

    return new Promise((resolve, _reject) => {
      resolve(newManifest);
    });
  };

  context.start({playbackConfig: playbackConfig});

Switch to a new stream on cast receiver, if any error occurs on the primary stream

Hi,

1. I have created a custom receiver and i would like to switch to a secondary stream if any error occurs while streaming the primary stream url. Can we do this on receiver side?

If possible can you please share any example code to do the same.

2. Also if i need to restart the playback from receiver is it possible ? If possible, can you please share any example code to do the same?
Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.