Git Product home page Git Product logo

videojs-chromecast's Introduction

Silvermine VideoJS Chromecast Plugin

Build Status Coverage Status Dependency Status Dev Dependency Status

What is it?

A plugin for videojs versions 6+ that adds a button to the control bar which will cast videos to a Chromecast.

How do I use it?

The @silvermine/videojs-chromecast plugin includes 3 types of assets: JavaScript, CSS, and images.

You can either build the plugin locally and use the assets that are output from the build process directly, or you can install the plugin as an NPM module, include the JavaScript and SCSS source in your project using a Common-JS module loader and SASS build process, and copy the images from the image source folder to your project.

Note that regardless of whether you are using this plugin via the pre-built JS or as a module, the Chromecast framework will need to be included after the plugin. For example:

<script src="https://unpkg.com/[email protected]/dist/video.js"></script>
<script src="./dist/silvermine-videojs-chromecast.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Building the plugin locally

  1. Either clone this repository or install the @silvermine/videojs-chromecast module using npm install @silvermine/videojs-chromecast.
  2. Ensure that @silvermine/videojs-chromecast's devDependencies are installed by running npm install from within the videojs-chromecast folder.
  3. Run grunt build to build and copy the JavaScript, CSS and image files to the videojs-chromecast/dist folder.
  4. Copy the plugin's files from the dist folder into your project as needed.
  5. Ensure that the images in the dist/images folder are accessible at ./images/, relative to where the plugin's CSS is located. If, for example, your CSS is located at https://example.com/plugins/silvermine-videojs-chromecast.css, then the plugin's images should be located at https://example.com/plugins/images/.
  6. Follow the steps in the "Configuration" section below.

Note: when adding the plugin's JavaScript to your web page, include the silvermine-videojs-chromecast.min.js JavaScript file in your HTML after loading Video.js. The plugin's built JavaScript file expects there to be a reference to Video.js at window.videojs and will throw an error if it does not exist.

Initialization options

  • preloadWebComponents (default: false) - The Chromecast framework relies on the webcomponents.js polyfill when a browser does not have document.registerElement in order to create the <google-cast-button> custom component (which is not used by this plugin). If you are using jQuery, this polyfill must be loaded and initialized before jQuery is initialized. Unfortunately, the Chromecast framework loads the webcomponents.js polyfill via a dynamically created <script> tag. This causes a race condition (see #17). Also, including webcomponents.js anywhere on the page will break jQuery's fix for bubbling some events to document (e.g. onchange events for <select>, see #21). Setting preloadWebComponents to true will "fix" these 2 problems by (1) making this plugin add the webcomponents polyfill synchronously when the polyfill is needed and (2) using the webcomponents-lite.js version as it does not include the shadow DOM polyfills, but still provides the registerElement polyfill that the Chromecast framework needs. If you use the preloadWebComponents: true option, you should make sure that this plugin is loaded before jQuery. Then include the Chromecast framework after this plugin as you normally would.

    Note: There is a caveat to using the preloadWebComponents setting. Because the Chromecast plugin uses the shadow DOM to create the <google-cast-button> custom component, the <google-cast-button> custom component may partly render, but it will not be functional. This tag is not used by this plugin. However if you must use this tag elsewhere, you should not use the preloadWebComponents flag.

    tl;dr: if you use jQuery, you should use the preloadWebComponents: true option in this plugin.

Providing initialization options via require()

If requiring this plugin via NPM, any desired initialization options can be supplied to the constructor function exported by the module. For example:

require('@silvermine/videojs-chromecast')(videojs, { preloadWebComponents: true });

Providing initialization options via <script>

If using the prebuilt JS, the initialization options can be provided via window.SILVERMINE_VIDEOJS_CHROMECAST_CONFIG. Note that these options need to be set before the <script> tag to include the plugin.

<script>
   window.SILVERMINE_VIDEOJS_CHROMECAST_CONFIG = {
      preloadWebComponents: true,
   };
</script>
<script src="path/to/silvermine-videojs-chromecast.js"></script>

Configuration

Once the plugin has been loaded and registered, configure it and add it to your Video.js player using Video.js' plugin configuration option (see the section under the heading "Setting up a Plugin" on Video.js' plugin documentation page.

Important: In addition to defining plugin configuration, you are required to define the player's techOrder option, setting 'chromecast' as the first Tech in the list. Below is an example of the minimum required configuration for the Chromecast plugin to function:

var options;

options = {
   controls: true,
   techOrder: [ 'chromecast', 'html5' ], // You may have more Tech, such as Flash or HLS
   plugins: {
      chromecast: {}
   }
};

videojs(document.getElementById('myVideoElement'), options);

Please note that even if you choose not to use any of the configuration options, you must either provide a chromecast entry in the plugins option for Video.js to initialize the plugin for you:

options = {
   plugins: {
      chromecast: {}
   }
};

or you must initialize the plugin manually:

var player = videojs(document.getElementById('myVideoElement'));

player.chromecast(); // initializes the Chromecast plugin

Configuration options

Plugin configuration
  • plugins.chromecast.receiverAppID - the string ID of a custom Chromecast receiver app to use. Defaults to the default Media Receiver ID.
  • plugins.chromecast.addButtonToControlBar - a boolean flag that tells the plugin whether or not it should automatically add the Chromecast button to the Video.js player's control bar component. Defaults to true.
  • plugins.chromecast.buttonPositionIndex - a zero-based number specifying the index of the Chromecast button among the control bar's child components (if addButtonToControlBar is set to true). By default the Chromecast Button is added as the last child of the control bar. A value less than 0 puts the button at the specified position from the end of the control bar. Note that it's likely not all child components of the control bar are visible.
  • plugins.chromecast.addCastLabelToButton (default: false) - by default, the Chromecast button component will display only an icon. Setting addCastLabelToButton to true will display a label titled "Cast" alongside the default icon.
Chromecast Tech configuration
  • chromecast.requestTitleFn - a function that this plugin calls when it needs a string that will be the title shown in the UI that is shown when a Chromecast session is active and connected. When the this plugin calls the requestTitleFn, it passes it the current source object and expects a string in return. If nothing is returned or if this option is not defined, no title will be shown.
  • chromecast.requestSubtitleFn - a function that this plugin calls when it needs a string that will be the sub-title shown in the UI that is shown when a Chromecast session is active and connected. When the this plugin calls the requestSubtitleFn, it passes it the current source object and expects a string in return. If nothing is returned or if this option is not defined, no sub-title will be shown.
  • chromecast.requestCustomDataFn - a function that this plugin calls when it needs an object that contains custom information necessary for a Chromecast receiver app when a session is active and connected. When the this plugin calls the requestCustomDataFn, it passes it the current source object and expects an object in return. If nothing is returned or if this option is not defined, no custom data will be sent. This option is intended to be used with a custom receiver application to extend its default capabilities.
  • chromecast.modifyLoadRequestFn - a function that this plugin calls before doing the request to load media. The function gets called with the LoadRequest object as argument and expects it in return.

Here is an example configuration object that makes full use of all required and optional configuration:

var titles, subtitles, customData, options;

titles = {
   'https://example.com/videos/video-1.mp4': 'Example Title',
   'https://example.com/videos/video-2.mp4': 'Example Title2',
};

subtitles = {
   'https://example.com/videos/video-1.mp4': 'Subtitle',
   'https://example.com/videos/video-2.mp4': 'Subtitle2',
};

customData = {
   'https://example.com/videos/video-1.mp4': { 'customColor': '#0099ee' },
   'https://example.com/videos/video-2.mp4': { 'customColor': '#000080' },
};

options = {
   // Must specify the 'chromecast' Tech first
   techOrder: [ 'chromecast', 'html5' ], // Required
   // Configuration for the Chromecast Tech
   chromecast: {
      requestTitleFn: function(source) { // Not required
         return titles[source.url];
      },
      requestSubtitleFn: function(source) { // Not required
         return subtitles[source.url];
      },
      requestCustomDataFn: function(source) { // Not required
         return customData[source.url];
      },
      modifyLoadRequestFn: function (loadRequest) { // HLS support
         loadRequest.media.hlsSegmentFormat = 'fmp4';
         loadRequest.media.hlsVideoSegmentFormat = 'fmp4';
         return loadRequest;
      }
   },
   plugins: {
      chromecast: {
         receiverAppID: '1234' // Not required
         addButtonToControlBar: false, // Defaults to true
      },
   }
};
Localization

The ChromecastButton component has two translated strings: "Open Chromecast menu" and "Cast".

  • The "Open Chromecast menu" string appears in both of the standard places for Button component accessibility text: inside the .vjs-control-text span and as the <button> element's title attribute.
  • The "Cast" string appears in an optional label within the Button component: inside the .vjs-chromecast-button-label span.

To localize the Chromecast button strings, follow the steps in the Video.js Languages tutorial to add "Open Chromecast menu" and "Cast" keys to the map of translation strings.

Using the NPM module

If you are using a module loader such as Browserify or Webpack, first install @silvermine/videojs-chromecast using npm install. Then, use require('@silvermine/videojs-chromecast') to require @silvermine/videojs-chromecast into your project's source code. require('@silvermine/videojs-chromecast') returns a function that you can use to register the plugin with Video.js by passing in a reference to videojs:

var videojs = require('video.js');

// Initialize the Chromecast plugin
require('@silvermine/videojs-chromecast')(videojs);

Then, follow the steps in the "Configuration" section above.

This plugin's source code uses ES6+ syntax and keywords, such as class and static. If you need to support browsers that do not support newer JavaScript syntax, you will need to use a tool like Babel to transpile and polyfill your code.

Alternatively, you can require('@silvermine/videojs-chromecast/dist/silvermine-videojs-chromecast.js') to use a JavaScript file that has already been polyfilled/transpiled down to ES5 compatibility.

Using the CSS and images

If you are using SCSS in your project, you can simply reference the plugin's main SCSS file in your project's SCSS:

@import "path/to/node_modules/@silvermine/videojs-chromecast/src/scss/videojs-chromecast";

Optionally, you can override the SCSS variables that contain the paths to the icon image files:

  • $icon-chromecast--default - the path to the icon image that is displayed when the Chromecast button is in its normal, default state. Defaults to "images/ic_cast_white_24dp.png".
  • $icon-chromecast--hover - the path to the icon image that is displayed when the user hovers over the Chromecast button when it is in its normal, default state. Defaults to "images/ic_cast_white_24dp.png".
  • $icon-chromecast-casting - the path to the icon image that is displayed when the Chromecast button is in the "casting" state (when a Chromecast session is active and connected). Defaults to "images/ic_cast_connected_white_24dp.png".
  • $icon-chromecast-casting--hover - the path to the icon image that is displayed when the user hovers over the Chromecast button when it is in the "casting" state (when a Chromecast session is active and connected). Defaults to "images/ic_cast_connected_white_24dp.png".
  • $chromecast-icon-size - the width and height of the icon (the button and icon is a square). Defaults to 12px.
  • $chromecast-title-font-size - the font size of the title on the screen that is shown while a Chromecast session is active and connected. Defaults to 22px.
  • $chromecast-subtitle-font-size - the font size of the sub-title on the screen that is shown while a Chromecast session is active and connected. Defaults to 18px.
  • $chromecast-poster-width - the width of the poster image on the screen that that is shown while a Chromecast session is active and connected. Defaults to 100px.
  • $chromecast-poster-max-height - the maximum height of the poster image on the screen that is shown while a Chromecast session is active and connected. Defaults to 180px.

Images

The plugin's images are located at videojs-chromecast/src/images. If you have not overridden the icon image path variables in the SCSS, then copy the images from the src/images folder to a folder that is accessible at ./images/, relative to where the plugin's CSS is located. If, for example, your CSS is located at https://example.com/plugins/silvermine-videojs-chromecast.css, then the plugin's images should be located at https://example.com/plugins/images/.

In addition, the ic_cast_white_24dp.png icon image that is used as the default icon for all four button states ("default", "default + hover", "casting", "casting + hover"), the images folder contains grey, black, and blue versions of the icons.

Events

  • chromecastConnected - Triggers when Chromecast connected
  • chromecastDisconnected - Triggers when Chromecast disconnected
  • chromecastDevicesAvailable - Triggers on state change when Chromecast devices are available
  • chromecastDevicesUnavailable - Triggers on state change when Chromecast devices are unavailable
  • chromecastRequested: Triggers when the user has requested Chromecast playback using this plugin's Chromecast button

How do I contribute?

We genuinely appreciate external contributions. See our extensive documentation on how to contribute.

License

This software is released under the MIT license. See the license file for more details.

videojs-chromecast's People

Contributors

andreasgangso avatar dcpesses avatar edgarsn avatar goveo avatar izkmdz avatar jandor64 avatar jimjenkins5 avatar jthomerson avatar kontrollanten avatar onebytegone avatar pbredenberg avatar yokuze 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

videojs-chromecast's Issues

Build a version

Hi

thanks for this addon

I am having a really hard time to build a version of it. I will need to self-host the script so I can not use an external link.

That is my output


~/Downloads/videojs-chromecast-master$ npm install

> [email protected] install /home/daniel/Downloads/videojs-chromecast-master/node_modules/node-sass
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v4.11.0/linux-x64-57_binding.node
Download complete  ] - :
Binary saved to /home/daniel/Downloads/videojs-chromecast-master/node_modules/node-sass/vendor/linux-x64-57/binding.node
Caching binary to /home/daniel/.npm/node-sass/4.11.0/linux-x64-57_binding.node

> [email protected] postinstall /home/daniel/Downloads/videojs-chromecast-master/node_modules/node-sass
> node scripts/build.js

Binary found at /home/daniel/Downloads/videojs-chromecast-master/node_modules/node-sass/vendor/linux-x64-57/binding.node
Testing binary
Binary is fine
npm WARN prepublish-on-install As of npm@5, `prepublish` scripts are deprecated.
npm WARN prepublish-on-install Use `prepare` for build steps and `prepublishOnly` for upload-only.
npm WARN prepublish-on-install See the deprecation note in `npm help scripts` for more information.

> @silvermine/[email protected] prepublish /home/daniel/Downloads/videojs-chromecast-master
> grunt build

fatal: not a git repository (or any of the parent directories): .git
Loading "Gruntfile.js" tasks...ERROR
>> Error: Command failed: git describe --always --dirty --tags
>> fatal: not a git repository (or any of the parent directories): .git
Warning: Task "build" not found. Use --force to continue.

Aborted due to warnings.
npm ERR! code ELIFECYCLE
npm ERR! errno 3
npm ERR! @silvermine/[email protected] prepublish: `grunt build`
npm ERR! Exit status 3
npm ERR! 
npm ERR! Failed at the @silvermine/[email protected] prepublish script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/daniel/.npm/_logs/2019-03-23T10_14_36_358Z-debug.log

Chromecast connects, but wont play media

Hi, first of all, thank you for making this plugin.

The plugin loads fine, but when i try to cast, i get the usual chromecast prompt to choose a chromecast device, then i get a blue cast icon in the chromecast tv screen, and after pausing for a second the media player keeps playing in the browser.

If i inspect player.chromecastSessionManager i can see that it claims to be connected (isConnected: true) but also, that media couldnt load (isMediaLoaded: false)

image

for the sake of simplicity and debugging im using a simple mp4 file instead of the hls playlist i plan to use after i make this work.

I dont know where to start debugging this, since i've tried many versions of video.js with no success, and i get no console errors.

here is the simplest example of the bug being reproducible:
(NOTE: dont open the html locally since the CastFramework wont load using file:// protocol)

index.html.zip

Sorry about the raw HTML, but codepen wont allow RepresentationApi to be used, if there is another similar service that you know can work just let me know and i'll upload it there...

customData not passed to custom receiver.

I have a custom receiver setup with the following code.

<html>
<head>

  <script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>

</head>
<body>
 	
 	<cast-media-player></cast-media-player>
  	
  	<script>

  		const context = cast.framework.CastReceiverContext.getInstance();
		const playbackConfig = new cast.framework.PlaybackConfig();
		// Customize the license url for playback
		playbackConfig.licenseUrl = '';
		playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
		playbackConfig.licenseRequestHandler = requestInfo => {
		  requestInfo.withCredentials = false;
		};
		context.start({playbackConfig: playbackConfig});

		// Update playback config licenseUrl according to provided value in load request.
		context.getPlayerManager().setMediaPlaybackInfoHandler((loadRequest, playbackConfig) => {

			console.log(loadRequest);
	
		  	return playbackConfig;

		});

  	</script>
</body>
</html>

I am using the plugin customData to try and send data to the receiver like below.

var customData;

customData = {
    'https://00000000000.cloudfront.net/00000000000/master.mpd': {
        'licenseUrl': 'my license url'
    },
};

options = {
    techOrder: ['chromecast', 'html5'],
    chromecast: {
        requestCustomDataFn: function(source) {
            return customData[source.url];
        }
    },
    plugins: {
        chromecast: {},
    }
};

I am debugging and I am not getting any customData sent below is the console log from the custom receiver loadRequest.
Screenshot 2020-10-18 at 23 56 18

Using plugin with VueJS

Hi

I am trying to use this plugin with VueJS but cannot seem to get it to work, can anyone point to be some helpful documentation or give me some guidance, please?

I have run:
npm install @silvermine/videojs-chromecast

Extracts from my Vue Component:
import videojs from 'video.js'
import '@silvermine/videojs-chromecast/src/scss/videojs-chromecast.scss'
require('@silvermine/videojs-chromecast')(videojs);

I get his error when trying npm run serve:
These relative modules were not found:

  • ./images/ic_cast_connected_white_24dp.png in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-3-1!./node_modules/postcss-loader/src??ref--8-oneOf-3-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-3-3!./node_modules/@silvermine/videojs-chromecast/src/scss/videojs-chromecast.scss
  • ./images/ic_cast_white_24dp.png in ./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-3-1!./node_modules/postcss-loader/src??ref--8-oneOf-3-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-3-3!./node_modules/@silvermine/videojs-chromecast/src/scss/videojs-chromecast.scss

Cast video from native chrome buttons

Currently, when playing a video with this plugin (for example, in demo), you can only cast from within the player.
Pressing the overflow menu in chrome, clicking cast, and selecting where to cast - doesn't cast anything.
It should be possible to cast the video from chromes native casting button.
See YouTube's behavior, for example.

Possibly related to #58

Cast not working on videojs 7.3.0

I've successfully built the module locally and added all files in the right place. The player shows the cast icon and after clicking it generates the dialog with a list of available devices. But, after selecting a device the screen is only showing a blue chromecast icon. No video and audio is casting.

I've tested it on a iPhone X and Samsung S7. Both in Chrome browser.

Any idea?

Webcomponents Polyfill still interferes with jQuery

Problem

The fix for #17 prevents the race condition between webcomponents.js and jQuery. Unfortunately, there are other conflicts between the 2 libraries.

Cause

Because webcomponents.js wraps every element except for document, jQuery is not able to provide it's fix for bubbling events to document consistently. Because of this code such as $(document).on('change', 'select', function() { alert('fired'); }); will never fire in some browsers (mainly webkit).

Proposed Fix

webcomponents.js is very intensive and polyfills functionality that is not needed by the Chromecast framework, or this function. The Web Components polyfill comes in 2 flavors (for v0.7.24): webcomponents.js and webcomponents-lite.js. The "lite" version polyfills the functionality that the Chromecast framework needs without wrapping every element to support shadow DOM. This causes less interference with jQuery while still allowing the Chromecast framework to do it's job.

tl;dr: We should use the webcomponents-lite.js file in the preloadWebComponents script instead of the full version.

chromecast api is always undefined

Everything seem to be loader properly but no button added to the player.
ChromecastSessionManager.isChromecastAPIAvailable() always return undefined so it get stuck.

Im on Mac, with chrome 83.0.4103.61

Looks like property: window.chrome.cast is undefined

Am I doing something wrong?

Seeking video location is not working

When I go to seek from the video on the computer that is casting to a television it does not allow for an update of the position in the video. It just stays in the video version.

I am using latest version of this plugin and video.js 7.2.2

I can not be certain but I feel this was working at some point in time.

If can't import then can repo be added to cdnjs

It would be helpful if the releases were available on https://cdnjs.com. Then we could get the files from a cdn. cdnjs is free too!

I found I could not merely instantiate the plugin with a plugins object addition and an import statement like other plugins. I had to include the dist file in my head to get it to work.

Example:

plugins: {
            chromecast:{
              receiverAppID:'3x2083xxxx',
              addButtonToControlBar: false,
            },

followed by an import statement of:

import 'videojs-hotkeys';
// more plugins.
import '@silvermine/videojs-chromecast';

Helpful links.
https://github.com/cdnjs/cdnjs
https://github.com/cdnjs/cdnjs/blob/master/CONTRIBUTING.md

DASH AudioStream Selection

Hi,

thanks for your helpful plugin.

Yet, we're facing the issue, that selecting an audio-stream from a DASH source during casting, is not reflected onto the chromecast.

Do you know, whether the cast protocol allows such a thing, or whether it would be possible do re-send the source with the selected audio stream and re-start from the current position?

Greeting

Chromecast doesnot load the video

Hi ,
I am using videojs and videojs-chromecast with react for following site

beamafilm.com. It shows the cast icon on video but when I try to cast movie it shows the blank screen,

and doesnot load on tv.

Add missing required Tech methods

While investigating #30 and #32, I found that there are several functions that Video.js requires a custom Tech to implement that are not documented.

I attempted to make a comprehensive list of required methods and submitted it to Video.js here: videojs/video.js#5737

Additionally, it was unclear what values should be returned for the seekable and buffered functions because that information is not available via the Chromecast API. I asked Video.js what they thought those functions should return, and their response is documented here: videojs/video.js#5742

This issue is a request to add the missing Tech functions to the ChromecastTech.

You can see a demonstration of the error that's thrown when a player function that delegates to a missing Tech function is called here: https://codepen.io/mluedke/pen/zyaVjX

Can't get videojs-chromecast to load

I'm not a js expert but I think I have this loaded correctly. Compiling with webpack.

import videojs from 'video.js';

require('@silvermine/videojs-chromecast')(videojs);

document.addEventListener('DOMContentLoaded', function() {

    var options = {
       controls: true,
       fluid: true,
       techOrder: [ 'chromecast', 'html5' ],
           plugins: {
            chromecast: {
                preloadWebComponents: true,
                addButtonToControlBar: true,
            },
        }
    };

    var video = videojs('livestream', options).ready(function(){
      var player = this;
      getNextSource(player);
      player.on('ended', function() {
        getNextSource(player);
      });

      player.on('error', function() {
        getNextSource(player);
      });
    });
//Rest of the file
});

Then I'm loading on page with two script calls.

<script src="/js/video.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Video plays and everything is good but I'm not getting the chromecast button and the built in chromecast option isnt working either.

I can cast from other sites, so I know its not a local issue.

Any help would be appreciated.

Error when resetting player before playback begins

If the player is loaded and then player.reset() is called before the playback ever begins, this plugin throws the following error:

Uncaught TypeError: Cannot read property 'src' of null
    at constructor._playSource (silvermine-videojs-chromecast.min.js:4005)
    at new constructor (silvermine-videojs-chromecast.min.js:3968)
    at Player.loadTech_ (video.js:24403)
    at Player.doReset_ (video.js:26795)
    at Player.reset (video.js:26779)
    at <anonymous>:1:8

This is causing a problem in my case due to how we're handling the player lifetime. We create the player on page load, in a hidden Bootstrap modal. When the user clicks on a video, it opens the modal and sets the player source. When the modal is closed, we have an event listener fire on the modal close event that will grab the player instance and then call player.reset() to clear the source and other things. The error thrown by this plugin then causes the the event listener to prematurely end, and the modal never closes.

In testing, I've determined that this error will always appear any time the player is reset before playback begins. It won't always be a breaking error depending on what's going on, but it does throw an error where it should not.

I've tested with Video.js 7.8.2 and 7.10.2 and the Chromecast plugin 1.2.2.

Widevine DRM Compatibility

Hi All,

I am just wondering what steps would need to be taken to make this plugin support Widevine DRM. I am using Widevine DRM with the videojs plugin https://github.com/videojs/videojs-contrib-eme and from the docs and looking around the web it seems all you need to do us pass your license URL in the custom data.

See here: https://stackoverflow.com/questions/25539054/widevine-drm-playback-on-chromecast

I have tried this with the plugin see setup below.

var customData;

customData = {
    'https://00000000000.cloudfront.net/00000000000/master.mpd': {
        'licenseUrl': 'my license url'
    },
};

options = {
    techOrder: ['chromecast', 'html5'],
    chromecast: {
        requestCustomDataFn: function(source) {
            return customData[source.url];
        }
    },
    plugins: {
        chromecast: {},
    }
};

Is there anything obvious I might be missing has anyone successfully got this working with DRM?

Thanks

Unsafe eval required in Content Security Policy

When adding XSS protections, it looks like Class.extend requires unsafe-eval to be allowed.

I have created a CodePen to show this, the Content Security Policy is in the Settings of the pen. You can see the eval error in your browser console.

I attempted to modify that code but didn't get very far, would be happy for your help!

Not Working with VideoJS 6.13 and VueJS and NuxtJS

I am using video.js 6.13.0 inside a nuxt-vue-app.
Here is my config:

var _video = require('video.js');
require('@silvermine/videojs-airplay')(_video)
require('@silvermine/videojs-chromecast')(_video, { preloadWebComponents: true });

playerOptions: {
               muted: false,
               controls: true,
               techOrder: ['chromecast', 'html5'],
               controlBar: {
                   volumePanel: {
                       inline: false,
                   }
               },
               plugins: {
                   airPlay: {
                      addButtonToControlBar: true 
                   },
                   chromecast: {
                       addButtonToControlBar: true
                   }
               },
               language: 'en',
               sources: [{
                   type: "video/mp4",
                   src: "path/to/video.mp4"
               }],
               //poster : "/static/images/author.jpg",
           }

I can't get any issues on the chrome console, but the chromecast button will not be appear in the buttonbar. Where is my issue and how can i solve it?

VOD HLS stuck on high bitrate segments [continued]

So my previous issue was closed, but I want to post my new findings here because this may be related to the plugin after all.

After purchasing a Chromecast Ultra and testing out the same HLS streams as specified before, the results are the same: it will hang at high bitrate segments.

Like I stated before, the segments are 1920x1080 [email protected] AVC 24fps, where some of those segments can hit bitrates of 30/40 Mbps. My connection is 200/50, so videos with high bitrate shouldn't be a problem. I've also tested the same streams with VLC, which can cast the entire video without any issues.

Also, I've merged the stream segments back together into a MP4 file, and tried it again with that. Surprisingly enough, this also doesn't show any playback issues, even for 1080P@60fps.

I don't know what the exact cause is, maybe it has to do with VideoJS, this plugin, or possibly even something on Google's end, like the cast_sender.js.

I don't know if this can or will be fixed anytime soon, but I'll just change everything back to MP4 in the meantime. Thank you for your time.

How to lower the volume when in chrome cast mode

I figured out how to set it up, it was due to another function in my code

The cast works fine now. But i still have an issue

Now by default the volume of videos js is 100% and when i cast it does to distinguish between system volume and player volume and makes it the same. So what happens is that when the cast starts the volume is peaked at 100% which is really bad

So id there like a if statement or can i configure/set the volume while in casting mode Thanks

And also is it possible to uncast with a function ?

UPDATE : solved the issue

    _onChromecastConnected: function() {
            this._isChromecastConnected = true;
            this._reloadCSSClasses();
            this.player().volume(0.1);    //change
            this.player().play();    
        },
        _onChromecastDisconnected: function() {
            this._isChromecastConnected = false;
            this._reloadCSSClasses();
            this.player().volume(1);   //change
        },

make this change here. This solves the issue

Also you can add autoplay by adding this.player().play();

"ended" event does not fire at the end of the media item

Sometimes the "ended" event does not fire when a media item ends.

This means that the player will continue to show the Chromecast Tech even after the item has ended, instead of closing the Chromecast session after the SESSION_TIMEOUT is up.

This seems to be caused by this if statement. The PlayerState is sometimes null after an item ends.

Cannot find module declaration of 'webcomponents.js/webcomponents-lite'.

After installing videojs-chromecast package in my react app when I try to build the project I get this error.
Cannot find module declaration of 'webcomponents.js/webcomponents-lite'.
This error throws in the preloadWebComponenets.js file which is located at this path --'npm_modules/@silvermine/videojs-chromecast/src/js/preloadWebcomponents.js'

Any suggestion or help will be very much appreciated. Thanks

Error: TypeError: tech[method] is not a function

I get the following error message while the video is playing over chromecast:

VIDEOJS: ERROR: TypeError: tech[method] is not a function
at get (index.js:23720)
at Player.techGet_ (index.js:36305)
at Player.(anonymous function) [as seekable] (http://.......index.js:38496:17)
at LiveTracker.seekableEnd (index.js:31945)
at SeekBar.update_ (index.js:27181)
at SeekBar.update (index.js:27210)
at Player.bound (index.js:16694)
at HTMLDivElement.bound (index.js:16694)
at HTMLDivElement.data.dispatcher (index.js:16344)
at trigger (index.js:16480)

Dependencies
Nuxt: 2.3.4
video.js: 7.4.1

Does anyone have an idea why that happens?

EDIT: I find out, that the required method "seekable" is not implemented. Seems like that's the problem. Have you planned to implement the method?

Can't find repository in NPM

I tried installing using npm, but the repo was not found. The log shows error 404 Not Found: silvermine-videojs-chromecast@latest. Is this plugin maintained anymore?

VTT Support

Hello,

is there any way to send VTT to Chromecast? because at the moment it seems impossible currently.

Thanks, I'll be grateful if someone can help me to do so

Regards

Chromecast poster image height is constrained, but width left open to site styling

When the Chromecast plugin is in its "casting" state for videos, the plugin displays a poster (if one is set) in the player UI.

The default styling for the poster image constrains the height of the image to a max-height. However, there is no default styling rule for the width, which leaves the image open to default site-wide styling.

It's common practice to set the site-wide styling of images to width: 100%, but without a corresponding constraint on the width of the Chromecast plugin's poster image, the image will be stretched out.

This fix belongs in this plugin's repo because the max-height styling without a corresponding width style is an incomplete solution.

chromecastSessionManager not defined?

Hi,

Not sure what if I'm setting this up incorrectly, or if I've run into a bug. It seems as if chromecastSessionManager isn't being defined. I've added chromecast first in the techOrder, and into the list of plugins. Using Video.js 6.7.1

Here's the error I'm getting in the console:
Uncaught TypeError: Cannot read property 'getRemotePlayer' of undefined
at new constructor (silvermine-videojs-chromecast.js:2305)
at e.loadTech_ (video.min.js:6)
at e.reset (video.min.js:6)
at loadNextVideoSegment (player.js:58)
at e. (player.js:39)
at r (video.min.js:2)

Thanks for the assist!

Some jQuery functions do not work when loading the Chromecast framework on iOS Chrome

If the Chromecast framework and jQuery are included on the same page, there is a race between the initialization of jQuery and webcomponents.js (which is loaded by the Chromecast framework when the browser does not have document.registerElement, e.g. Chrome on iOS). A demo of this can be seen here. If the demo is opened in Safari on iOS, the blue box will animate up and down (using jQuery.animate()). However if the demo is opened on Chrome on iOS, the box will stay at the bottom of its container and not move.

box-that-should-move

When the box fails to move, it is due an error thrown by the assertIsNodeWrapper assertion that webcomponents.js added to insertBefore. That assertion will fail when jQuery wins the initialization race against webcomponents.js. On load, jQuery creates a div to use later for pixel position calculations. When webcomponents.js is loaded, it makes a number of changes to window.Node. Therefore if jQuery is initialized before webcomponents.js, the div jQuery created is of a different prototype than what assertIsNodeWrapper in webcomponents.js is expecting. However if webcomponents.js initializes before jQuery, both libraries look to play well together.

While this issue is not directly caused by this plugin (or Video.js), for this plug-in to be the most versatile, it seems we should provide an easy work-around for the problem. This plugin should be loaded before the Chromecast framework and does not depend on jQuery, therefore this provides an opportunity to "preload" webcomponents.js.

Effected browsers

Chrome on iOS 9+

Separate SCSS files according to function

We should separate the main videojs-chromecast.scss file into 3 files:

  1. tech.scss that contains all of the Video.js Chromecast Tech styles.
  2. chromecastButton.scss that contains all of the Chromecast Button styles.
  3. videojs-chromecast.scss that simply imports the first two files.

This way, users of this plugin can @import only the styles that they actually need. For example, someone may have their own Video.js skin that styles the Chromecast button, but still need the styling for the Tech (the screen that's displayed while Chromecast is connected / active).

This change would allow them to simply:

@import "silvermine-videojs-chromecast/src/scss/tech"

to get only the styles for the Tech and not have to override the button styles.

Native HLS Subtitle Support

Hi All,

Great plugin just wondering if this plugin supports Native hls subtitles like in this stream?

https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8

Example: https://codepen.io/raestrada/pen/rbZqQG

I see there is an option here.

https://developers.google.com/cast/docs/reference/player/cast.player.api.Player#enableCaptions

But I see in your code it is disabled

// Text tracks are not supported in this version
   ChromecastTechImpl.prototype.featuresNativeTextTracks = false;
   ChromecastTechImpl.prototype.featuresNativeAudioTracks = false;
   ChromecastTechImpl.prototype.featuresNativeVideoTracks = false; 

Just wanted to check if I am missing something.

Thanks

Shareable links as YouTube not working

Made over 30 different tests both via video source element and playlist/playlist Ui/YouTube plugin there the outcome is as below.
NOTE: All videos play as a charm in VideoJS (test made with v7.3.0 and 7.4.1). Some of bellow mentioned links are examples but you get the point.

Silvermine Chromecast test via video element link
<source src="http://www.caminandes.com/download/03_caminandes_llamigos_1080p.mp4" type="video/mp4">OK and working
<source src="https://youtu.be/BS4wTFZBLj0" type="video/youtube"> Not working
<source src="video/xxxxxx.mp4" type="video/mp4"> Not working
<source src="https://www.dropbox.com/xxxxxx.mp4?raw=1" type="video/mp4"> OK and working`

Silvermine Chromecast test via playlist/playlist Ui and YouTube plugin
YouTube
sources: [
{ src: 'https://youtu.be/ei_5R0CvLm4', type: 'video/youtube' },
], Not working

G-Drive
sources: [
{ src: 'https://drive.google.com/uc?export=download&id=xxxxxxxxxxxxxxxxxxxx', type: 'video/mp4' },
], OK and working

OneDrive
sources: [
{ src: 'https://onedrive.live.com/download?cid=xxxxxxxxxxxxxxxxxxxx', type: 'video/mp4' },
], OK and working

Dropbox
sources: [
{ src: 'https://www.dropbox.com/s/xxxxxxxxxxxxxxxxxxxx/xxx.mp4?raw=1', type: 'video/mp4' },
], OK and working

OneDrive (4K larger file)
sources: [
{ src: 'https://onedrive.live.com/download?cid=xxxxxxxxxxxxxxxxxxxx', type: 'video/mp4' },
], Not working

Caminandes.com
sources: [
{ src: 'http://www.caminandes.com/download/03_caminandes_llamigos_1080p.mp4', type: 'video/mp4' },
], OK and working

Local source
sources: [
{ src: 'video/xxxx.mp4', type: 'video/mp4' }
], Not working

Your demo index.html does not work for me

Hi,

i tried your index.html, just by opening it like this in my Chrome browser:
file:///F://index.html

I modified the html to get you script from unpkg:

<script src="https://unpkg.com/@silvermine/[email protected]/dist/silvermine-videojs-chromecast.min.js"></script>
<link href="https://unpkg.com/@silvermine/[email protected]/dist/silvermine-videojs-chromecast.css" rel="stylesheet">

Playing the video in my browser works, but i see no button to cast it to my chromecast device.

Have i missed something?

VideoJS 7 + HLS Support

It appears that HLS streams do not work correctly when coupled with VideoJS 7. The chromecast icon appears on the chromecast device, the progress bar shows briefly, then disappears, and then nothing happens.

You [should] be able reproduce with the included HTML. I'm not familiar with Chromecast development, so I'm not sure where to look for debug information. I see nothing of importance in Chrome's dev console. MPEG-DASH seems to work fine FWIW.

The HTML should be just a simple modification of your provided test file, with the changes being: VideoJS version and the source video file.

Let me know if there's any information I can provide, or anything I can do to help! I will look into Chromecast debugging in the meantime. Given that HLS streams works w/o Chromecast, and similar segmented streams (MPEG-DASH) work w/ & w/o Chromecast, I suspect it's some trivial error.

test_vjs7_hls.zip

VOD HLS stuck on high bitrate segments

I've been experimenting with this plugin for a while now, and I have noticed that for HLS streams with TS segments (1920x1080 [email protected] AVC) with relatively high bitrate (30 Mbps), the chromecast tends to bug out (loading icon on TV keeps on spinning). The issue doesn't seem to occur until it hits segments with a bitrate of over +/- 12 Mbps. The segments play fine in the browser and it's still possible to skip the "troublesome" segments (while casting) in order to watch the rest of the video.

While I'm not entirely sure if this is a direct issue with the plugin, it seems more likely that the Chromecast just can't handle the segments. So I was wondering if anyone else also noticed this behaviour and/or knows what the max bitrate is that the Chromecast 3 (and Ultra) can handle?

Anyway, if anyone can confirm this is indeed a problem with the Chromecast, I'll close this issue and head over to Google support. Thank you for your time.

Support localized control text for the Chromecast button

Currently, the Chromecast plugin allows you to pass a string literal option called buttonText that becomes the button's .vjs-control-text text. However, the Chromecast Button component overrides the createControlTextEl method and does not add the aria-label to the button as its parent does.

A simpler method would be to call this.controlText('Chromecast') from the constructor, and let the Button component handle adding the control text. This has the added advantage of integrating with Video.js' localization API.

It is possible to adjust the style of the chromecast subtitles (CC) based on the subtitle(CC) menu of videojs.

Hello, as the title says It is possible to adjust the style of the chromecast subtitles (CC) based on the subtitle(CC) menu of videojs seen in some applications of android that allows to adjust the design of the subitutles but I do not know if that function could be added.

I leave an example of HLS video with subtitles in case someone tries it.

https://codepen.io/raestrada/pen/rbZqQG

Thanks for taking the time.

Add option to disable automatic insertion of Chromecast button into the player's control bar

We should add a configuration option that allows users to disable the automatic insertion of the Chromecast button into the player's control bar.

Plugin users may want to specify where the Chromecast button appears in the player UI's component hierarchy using Video.js configuration options. With the way the plugin is now, the Chromecast button will be inserted into the control bar if the plugin does not find it at the root level of the controlBar component. If a plugin user specifies the Chromecast button to appear nested within an element in the controlBar, for example, the plugin will insert another Chromecast button at the root controlBar level.

Error: playbackRate is not a function

While casting an HLS media item, this error is logged in the console periodically:

VIDEOJS: ERROR: TypeError: _this2.tech_.playbackRate is not a function

This is because the ChromecastTech class does not implement a playbackRate function.

Silvermine Chromecast plugin doesn't work in v7.7.0

Description

Silvermine Chromecast plugin doesn't work in v7.7.0
https://codepen.io/DJ-PD/pen/jdWWEg

Steps to reproduce

Explain in detail the exact steps necessary to reproduce the issue.

  1. Under settings/html/head replace v7.6.6 to v7.7.0 both script and css ***SCRiPTS***/ ***STYLESHEETS***
  2. Test with above codepen e.g test 7
  3. Chromecast icon disappear

Results

Expected

Chromecast icon present and function works.

Actual

Chromecast icon disappear.

Error output

n/a

Additional Information

Will share this information with VideoJS team as well.

versions

videojs

7.6.x and 7.7.0

browsers

Chrome version 78.0.3904.108 and probably more.

OSes

Windows 10, Android, iOS

plugins

Silvermine chromecast

Chromecast and IMA Ads

Hello everybody:

I have a web page and my player and my ads is working but when I try send to the chromecast with the plugin silrvermine-videojs-chromecast the ads play in my browser and the video play in my chromecast and I want that all play it at the chromecast

https://sportsvr.tv

Thanks for all

Best regards

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.