├── .browserslistrc
├── .editorconfig
├── .eslintrc.json
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .jsdoc
├── .markdownlint-cli2.cjs
├── .npmignore
├── .nvmrc
├── .nycrc.json
├── .stylelintrc.yml
├── CHANGELOG.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── commitlint.config.js
├── docs
└── demo
│ └── index.html
├── package-lock.json
├── package.json
├── src
├── .eslintrc.json
├── images
│ ├── ic_cast_black_24dp.png
│ ├── ic_cast_blue_24dp.png
│ ├── ic_cast_connected_black_24dp.png
│ ├── ic_cast_connected_blue_24dp.png
│ ├── ic_cast_connected_grey_24dp.png
│ ├── ic_cast_connected_white_24dp.png
│ ├── ic_cast_grey_24dp.png
│ └── ic_cast_white_24dp.png
├── js
│ ├── chromecast
│ │ └── ChromecastSessionManager.js
│ ├── components
│ │ └── ChromecastButton.js
│ ├── enableChromecast.js
│ ├── index.js
│ ├── preloadWebComponents.js
│ ├── standalone.js
│ └── tech
│ │ ├── ChromecastTech.js
│ │ └── ChromecastTechUI.js
└── scss
│ ├── _chromecastButton.scss
│ ├── _tech.scss
│ └── videojs-chromecast.scss
└── tests
├── .eslintrc.json
├── ChromcastButton.test.js
├── ChromcastTech.test.js
└── Placeholder.test.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | ./node_modules/@silvermine/standardization/browserslist/.browserslistrc-broad-support
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ./node_modules/@silvermine/standardization/.editorconfig
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "extends": "@silvermine/eslint-config/node"
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [ push, pull_request ]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | outputs:
9 | nvmrc: ${{ steps.makeNodeVersionOutput.outputs.nvmrc }}
10 | steps:
11 | -
12 | uses: actions/checkout@v4
13 | with:
14 | fetch-depth: 0 # Fetch all history
15 | -
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version-file: '.nvmrc'
19 | -
20 | name: Put NVM version in output
21 | id: makeNodeVersionOutput
22 | run: echo "nvmrc=$(cat .nvmrc)" >> "$GITHUB_OUTPUT"
23 | - run: npm ci
24 | - run: npm run check-node-version
25 | - run: npm run standards
26 | - run: npm run build
27 | -
28 | name: Check for uncommitted changes # Done after dependency install and build to ensure code isn't compromised
29 | run: if [ -n "$(git status --porcelain)" ]; then echo 'There are uncommitted changes.'; exit 1; fi
30 | test:
31 | needs: [ build ]
32 | runs-on: ubuntu-latest
33 | strategy:
34 | fail-fast: false
35 | matrix:
36 | node-version: [ 16, '${{ needs.build.outputs.nvmrc }}', 'lts/*', 'latest' ]
37 | steps:
38 | -
39 | uses: actions/checkout@v4
40 | with:
41 | fetch-depth: 0 # Fetch all history
42 | -
43 | name: Use Node.js ${{ matrix.node-version }}
44 | uses: actions/setup-node@v4
45 | with:
46 | node-version: ${{ matrix.node-version }}
47 | - run: npm ci # Reinstall the dependencies to ensure they install with the current version of node
48 | - run: npm run standards
49 | - run: npm run build # Ensure building is possible with this version of node
50 | - run: npm test
51 | -
52 | name: Coveralls
53 | uses: coverallsapp/github-action@v2
54 | with:
55 | parallel: true
56 | flag-name: ${{ matrix.node-version }}
57 | finish:
58 | needs: [ test ]
59 | runs-on: ubuntu-latest
60 | steps:
61 | -
62 | name: Close parallel build
63 | uses: coverallsapp/github-action@v2
64 | with:
65 | parallel-finished: true
66 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # build directory
12 | dist
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 | .nyc_output
17 |
18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
19 | .grunt
20 |
21 | # node-waf configuration
22 | .lock-wscript
23 |
24 | # Compiled binary addons (http://nodejs.org/api/addons.html)
25 | build/Release
26 |
27 | # Dependency directory
28 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
29 | node_modules
30 |
31 | # IDE
32 | **/.idea
33 |
34 | # VIM
35 | .*.sw?
36 |
37 | # OS
38 | .DS_Store
39 | .tmp
40 |
--------------------------------------------------------------------------------
/.jsdoc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [ "plugins/markdown" ]
3 | }
4 |
--------------------------------------------------------------------------------
/.markdownlint-cli2.cjs:
--------------------------------------------------------------------------------
1 | node_modules/@silvermine/standardization/.markdownlint-cli2.shared.cjs
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .eslintrc.json
2 | .travis.yml
3 | .npmignore
4 | Gruntfile.js
5 | tests/**
6 | .nyc_output
7 | coverage
8 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20.12.2
2 |
--------------------------------------------------------------------------------
/.nycrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": [
3 | "src/**/*.js"
4 | ],
5 | "extension": [
6 | ".js"
7 | ],
8 | "reporter": [
9 | "text-summary",
10 | "html",
11 | "lcov"
12 | ],
13 | "instrument": true,
14 | "sourceMap": true,
15 | "all": true
16 | }
17 |
--------------------------------------------------------------------------------
/.stylelintrc.yml:
--------------------------------------------------------------------------------
1 | extends: ./node_modules/@silvermine/standardization/.stylelintrc.yml
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [our coding standards][commit-messages] for commit guidelines.
5 |
6 | ## [1.5.0](https://github.com/silvermine/videojs-chromecast/compare/v1.4.1...v1.5.0) (2023-11-07)
7 |
8 |
9 | ### Features
10 |
11 | * Allow modifying the load request ([#123](https://github.com/silvermine/videojs-chromecast/issues/123), [#141](https://github.com/silvermine/videojs-chromecast/issues/141)) ([7cee052](https://github.com/silvermine/videojs-chromecast/commit/7cee052dcd5473448f882d67bb5bc9d8e9a1763c))
12 |
13 |
14 | ### Bug Fixes
15 |
16 | * Clear the close session timeout after new source starts playing ([4a8eb31](https://github.com/silvermine/videojs-chromecast/commit/4a8eb31faa241235c54c1f8dec897571360e7f19))
17 |
18 |
19 | ### [1.4.1](https://github.com/silvermine/videojs-chromecast/compare/v1.4.0...v1.4.1) (2023-03-21)
20 |
21 |
22 | ### Bug Fixes
23 |
24 | * remove deprecated `.extend` method ([994b5b9](https://github.com/silvermine/videojs-chromecast/commit/994b5b9ae6df89f657e2ff4a920056826094b54f)), closes [#152](https://github.com/silvermine/videojs-chromecast/issues/152) [#147](https://github.com/silvermine/videojs-chromecast/issues/147)
25 |
26 |
27 | ## [1.4.0](https://github.com/silvermine/videojs-chromecast/compare/v1.3.4...v1.4.0) (2023-03-21)
28 |
29 |
30 | ### Features
31 |
32 | * Add optional "Cast" label to button component ([220c362](https://github.com/silvermine/videojs-chromecast/commit/220c36247c9ac992b757b97257e24e665ac3feb5))
33 | * Change label to "Disconnect Cast" when connected ([a7f495b](https://github.com/silvermine/videojs-chromecast/commit/a7f495b78d8472322079a75a834440fd20858b3c))
34 | * Set image on cast device if the video has a poster ([902464c](https://github.com/silvermine/videojs-chromecast/commit/902464cecf468c554fb062bd93d09bae9e303922))
35 |
36 |
37 | ### Bug Fixes
38 |
39 | * Chromecast button with label styling breaking on cast/disconnect ([2a181de](https://github.com/silvermine/videojs-chromecast/commit/2a181dea847927050b57453f9474a2f47028fdca))
40 |
41 |
42 | [commit-messages]: https://github.com/silvermine/silvermine-info/blob/master/commit-history.md#commit-messages
43 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Jeremy Thomerson
3 | * Licensed under the MIT license.
4 | */
5 | 'use strict';
6 |
7 | var path = require('path'),
8 | getCodeVersion = require('silvermine-serverless-utils/src/get-code-version'),
9 | join = path.join.bind(path),
10 | sass = require('sass');
11 |
12 | module.exports = function(grunt) {
13 |
14 | var DEBUG = !!grunt.option('debug'),
15 | config;
16 |
17 | config = {
18 | js: {
19 | all: [ 'Gruntfile.js', 'src/**/*.js', 'tests/**/*.js' ],
20 | browserMainFile: join('src', 'js', 'standalone.js'),
21 | },
22 |
23 | sass: {
24 | all: [ '**/*.scss', '!**/node_modules/**/*' ],
25 | main: join('src', 'scss', 'videojs-chromecast.scss'),
26 | },
27 |
28 | images: {
29 | base: join('src', 'images'),
30 | },
31 |
32 | dist: {
33 | base: join(__dirname, 'dist'),
34 | },
35 | };
36 |
37 | config.dist.js = {
38 | bundle: join(config.dist.base, 'silvermine-videojs-chromecast.js'),
39 | minified: join(config.dist.base, 'silvermine-videojs-chromecast.min.js'),
40 | };
41 |
42 | config.dist.css = {
43 | base: config.dist.base,
44 | main: join(config.dist.base, 'silvermine-videojs-chromecast.css'),
45 | };
46 |
47 | config.dist.images = join(config.dist.base, 'images');
48 |
49 | grunt.initConfig({
50 |
51 | pkg: grunt.file.readJSON('package.json'),
52 | versionInfo: getCodeVersion.both(),
53 | config: config,
54 |
55 | clean: {
56 | build: [ config.dist.base ],
57 | },
58 |
59 | copy: {
60 | images: {
61 | files: [
62 | {
63 | expand: true,
64 | cwd: config.images.base,
65 | src: '**/*',
66 | dest: config.dist.images,
67 | },
68 | ],
69 | },
70 | },
71 |
72 | browserify: {
73 | main: {
74 | src: config.js.browserMainFile,
75 | dest: config.dist.js.bundle,
76 | options: {
77 | transform: [
78 | [
79 | 'babelify',
80 | {
81 | presets: [
82 | [
83 | '@babel/preset-env',
84 | {
85 | debug: DEBUG,
86 | useBuiltIns: 'usage',
87 | shippedProposals: true,
88 | corejs: 3,
89 | },
90 | ],
91 | ],
92 | },
93 | ],
94 | ],
95 | },
96 | },
97 | },
98 |
99 | uglify: {
100 | main: {
101 | files: {
102 | '<%= config.dist.js.minified %>': config.dist.js.bundle,
103 | },
104 | options: {
105 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> <%= versionInfo %> */\n',
106 | sourceMap: DEBUG,
107 | sourceMapIncludeSources: DEBUG,
108 | mangle: !DEBUG,
109 | // Disable the `merge_vars` option in the compression phase.
110 | // `merge_vars` aggressively reuses variable names, which can lead to
111 | // unexpected behavior or runtime errors in certain cases.
112 | compress: DEBUG ? false : { merge_vars: false }, // eslint-disable-line camelcase
113 | beautify: DEBUG,
114 | },
115 | },
116 | },
117 |
118 | sass: {
119 | main: {
120 | files: [
121 | {
122 | src: config.sass.main,
123 | dest: config.dist.css.main,
124 | ext: '.css',
125 | extDot: 'first',
126 | },
127 | ],
128 | },
129 | options: {
130 | implementation: sass,
131 | sourceMap: DEBUG,
132 | indentWidth: 3,
133 | outputStyle: DEBUG ? 'expanded' : 'compressed',
134 | sourceComments: DEBUG,
135 | },
136 | },
137 |
138 | postcss: {
139 | options: {
140 | map: DEBUG,
141 | processors: [
142 | require('autoprefixer')(), // eslint-disable-line global-require
143 | ],
144 | },
145 | styles: {
146 | src: config.dist.css.main,
147 | },
148 | },
149 |
150 | watch: {
151 | grunt: {
152 | files: [ 'Gruntfile.js' ],
153 | tasks: [ 'build' ],
154 | },
155 |
156 | js: {
157 | files: [ 'src/**/*.js' ],
158 | tasks: [ 'build-js' ],
159 | },
160 |
161 | css: {
162 | files: [ 'src/**/*.scss' ],
163 | tasks: [ 'build-css' ],
164 | },
165 | },
166 |
167 | });
168 |
169 | grunt.loadNpmTasks('grunt-contrib-clean');
170 | grunt.loadNpmTasks('grunt-contrib-uglify');
171 | grunt.loadNpmTasks('grunt-browserify');
172 | grunt.loadNpmTasks('grunt-contrib-copy');
173 | grunt.loadNpmTasks('grunt-contrib-watch');
174 | grunt.loadNpmTasks('grunt-sass');
175 | grunt.loadNpmTasks('grunt-postcss');
176 |
177 | grunt.registerTask('build-js', [ 'browserify', 'uglify' ]);
178 | grunt.registerTask('build-css', [ 'sass', 'postcss:styles' ]);
179 | grunt.registerTask('build', [ 'build-js', 'build-css', 'copy:images' ]);
180 | grunt.registerTask('develop', [ 'build', 'watch' ]);
181 | grunt.registerTask('default', [ 'build' ]);
182 |
183 | };
184 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2017 Jeremy Thomerson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | this software and associated documentation files (the "Software"), to deal in
6 | the Software without restriction, including without limitation the rights to
7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 | of the Software, and to permit persons to whom the Software is furnished to do
9 | so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Silvermine VideoJS Chromecast Plugin
2 |
3 |
4 | [](https://travis-ci.org/silvermine/videojs-chromecast)
5 | [](https://coveralls.io/github/silvermine/videojs-chromecast?branch=master)
6 | [](https://david-dm.org/silvermine/videojs-chromecast)
7 | [](https://david-dm.org/silvermine/videojs-chromecast#info=devDependencies&view=table)
8 |
9 |
10 |
11 | ## What is it?
12 |
13 | A plugin for [videojs](http://videojs.com/) versions 6+ that adds a button to the control
14 | bar which will cast videos to a Chromecast.
15 |
16 |
17 | ## How do I use it?
18 |
19 | The `@silvermine/videojs-chromecast` plugin includes 3 types of assets: JavaScript, CSS,
20 | and images.
21 |
22 | You can either build the plugin locally and use the assets that are output from the build
23 | process directly, or you can install the plugin as an NPM module, include the
24 | JavaScript and SCSS source in your project using a Common-JS module loader and SASS build
25 | process, and copy the images from the image source folder to your project.
26 |
27 | Note that regardless of whether you are using this plugin via the pre-built JS or as a
28 | module, the Chromecast framework will need to be included after the plugin. For example:
29 |
30 | ```html
31 |
32 |
33 |
34 | ```
35 |
36 | ### Building the plugin locally
37 |
38 | 1. Either clone this repository or install the `@silvermine/videojs-chromecast` module
39 | using `npm install @silvermine/videojs-chromecast`.
40 | 2. Ensure that `@silvermine/videojs-chromecast`'s `devDependencies` are installed by
41 | running `npm install` from within the `videojs-chromecast` folder.
42 | 3. Run `grunt build` to build and copy the JavaScript, CSS and image files to the
43 | `videojs-chromecast/dist` folder.
44 | 4. Copy the plugin's files from the `dist` folder into your project as needed.
45 | 5. Ensure that the images in the `dist/images` folder are accessible at `./images/`,
46 | relative to where the plugin's CSS is located. If, for example, your CSS is located
47 | at `https://example.com/plugins/silvermine-videojs-chromecast.css`, then the
48 | plugin's images should be located at `https://example.com/plugins/images/`.
49 | 6. Follow the steps in the "Configuration" section below.
50 |
51 | Note: when adding the plugin's JavaScript to your web page, include the
52 | `silvermine-videojs-chromecast.min.js` JavaScript file in your HTML *after* loading
53 | Video.js. The plugin's built JavaScript file expects there to be a reference to Video.js
54 | at `window.videojs` and will throw an error if it does not exist.
55 |
56 | ### Initialization options
57 |
58 | * **`preloadWebComponents`** (default: `false`) - The Chromecast framework relies on
59 | the `webcomponents.js` polyfill when a browser does not have
60 | `document.registerElement` in order to create the `` custom
61 | component (which is not used by this plugin). If you are using jQuery, this polyfill
62 | must be loaded and initialized before jQuery is initialized. Unfortunately, the
63 | Chromecast framework loads the `webcomponents.js` polyfill via a dynamically created
64 | `
105 |
106 | ```
107 |
108 | ### Configuration
109 |
110 | Once the plugin has been loaded and registered, configure it and add it to your Video.js
111 | player using Video.js' plugin configuration option (see the section under the heading
112 | "Setting up a Plugin" on [Video.js' plugin documentation page][videojs-docs].
113 |
114 | **Important: In addition to defining plugin configuration, you are required to define the
115 | player's `techOrder` option, setting `'chromecast'` as the first Tech in the list.** Below
116 | is an example of the minimum required configuration for the Chromecast plugin to function:
117 |
118 | ```js
119 | var options;
120 |
121 | options = {
122 | controls: true,
123 | techOrder: [ 'chromecast', 'html5' ], // You may have more Tech, such as Flash or HLS
124 | plugins: {
125 | chromecast: {}
126 | }
127 | };
128 |
129 | videojs(document.getElementById('myVideoElement'), options);
130 | ```
131 |
132 | Please note that even if you choose not to use any of the configuration options, you must
133 | either provide a `chromecast` entry in the `plugins` option for Video.js to initialize the
134 | plugin for you:
135 |
136 | ```js
137 | options = {
138 | plugins: {
139 | chromecast: {}
140 | }
141 | };
142 | ```
143 |
144 | or you must initialize the plugin manually:
145 |
146 | ```js
147 | var player = videojs(document.getElementById('myVideoElement'));
148 |
149 | player.chromecast(); // initializes the Chromecast plugin
150 | ```
151 |
152 | #### Configuration options
153 |
154 | ##### Plugin configuration
155 |
156 | * **`plugins.chromecast.receiverAppID`** - the string ID of a custom [Chromecast
157 | receiver app][cast-receiver] to use. Defaults to the [default Media Receiver
158 | ID][def-cast-id].
159 | * **`plugins.chromecast.addButtonToControlBar`** - a `boolean` flag that tells the
160 | plugin whether or not it should automatically add the Chromecast button to the
161 | Video.js player's control bar component. Defaults to `true`.
162 | * **`plugins.chromecast.buttonPositionIndex`** - a zero-based number specifying the
163 | index of the Chromecast button among the control bar's child components (if
164 | `addButtonToControlBar` is set to `true`). By default the Chromecast Button is added
165 | as the last child of the control bar. A value less than 0 puts the button at the
166 | specified position from the end of the control bar. Note that it's likely not all
167 | child components of the control bar are visible.
168 | * **`plugins.chromecast.addCastLabelToButton`** (default: `false`) - by default, the
169 | Chromecast button component will display only an icon. Setting `addCastLabelToButton`
170 | to `true` will display a label titled `"Cast"` alongside the default icon.
171 |
172 | ##### Chromecast Tech configuration
173 |
174 | * **`chromecast.requestTitleFn`** - a function that this plugin calls when it needs a
175 | string that will be the title shown in the UI that is shown when a Chromecast session
176 | is active and connected. When the this plugin calls the `requestTitleFn`, it passes
177 | it the [current `source` object][player-source] and expects a string in return. If
178 | nothing is returned or if this option is not defined, no title will be shown.
179 | * **`chromecast.requestSubtitleFn`** - a function that this plugin calls when it needs
180 | a string that will be the sub-title shown in the UI that is shown when a Chromecast
181 | session is active and connected. When the this plugin calls the `requestSubtitleFn`,
182 | it passes it the [current `source` object][player-source] and expects a string in
183 | return. If nothing is returned or if this option is not defined, no sub-title will be
184 | shown.
185 | * **`chromecast.requestCustomDataFn`** - a function that this plugin calls when it
186 | needs an object that contains custom information necessary for a Chromecast receiver
187 | app when a session is active and connected. When the this plugin calls the
188 | `requestCustomDataFn`, it passes it the [current `source` object][player-source] and
189 | expects an object in return. If nothing is returned or if this option is not defined,
190 | no custom data will be sent. This option is intended to be used with a [custom
191 | receiver][custom-receiver] application to extend its default capabilities.
192 | * **`chromecast.modifyLoadRequestFn`** - a function that this plugin calls before doing
193 | the request to [load media][chromecast-load-media]. The function gets called with
194 | the [LoadRequest][chromecast-load-request] object as argument and expects it in
195 | return.
196 |
197 | Here is an example configuration object that makes full use of all required and optional
198 | configuration:
199 |
200 | ```js
201 | var titles, subtitles, customData, options;
202 |
203 | titles = {
204 | 'https://example.com/videos/video-1.mp4': 'Example Title',
205 | 'https://example.com/videos/video-2.mp4': 'Example Title2',
206 | };
207 |
208 | subtitles = {
209 | 'https://example.com/videos/video-1.mp4': 'Subtitle',
210 | 'https://example.com/videos/video-2.mp4': 'Subtitle2',
211 | };
212 |
213 | customData = {
214 | 'https://example.com/videos/video-1.mp4': { 'customColor': '#0099ee' },
215 | 'https://example.com/videos/video-2.mp4': { 'customColor': '#000080' },
216 | };
217 |
218 | options = {
219 | // Must specify the 'chromecast' Tech first
220 | techOrder: [ 'chromecast', 'html5' ], // Required
221 | // Configuration for the Chromecast Tech
222 | chromecast: {
223 | requestTitleFn: function(source) { // Not required
224 | return titles[source.url];
225 | },
226 | requestSubtitleFn: function(source) { // Not required
227 | return subtitles[source.url];
228 | },
229 | requestCustomDataFn: function(source) { // Not required
230 | return customData[source.url];
231 | },
232 | modifyLoadRequestFn: function (loadRequest) { // HLS support
233 | loadRequest.media.hlsSegmentFormat = 'fmp4';
234 | loadRequest.media.hlsVideoSegmentFormat = 'fmp4';
235 | return loadRequest;
236 | }
237 | },
238 | plugins: {
239 | chromecast: {
240 | receiverAppID: '1234' // Not required
241 | addButtonToControlBar: false, // Defaults to true
242 | },
243 | }
244 | };
245 | ```
246 |
247 | ##### Localization
248 |
249 | The `ChromecastButton` component has two translated strings: "Open Chromecast menu" and
250 | "Cast".
251 |
252 | * The "Open Chromecast menu" string appears in both of the standard places for Button
253 | component accessibility text: inside the `.vjs-control-text` span and as the
254 | `