aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/source.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/source.js')
-rw-r--r--src/js/source.js144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/js/source.js b/src/js/source.js
new file mode 100644
index 00000000..80620bdf
--- /dev/null
+++ b/src/js/source.js
@@ -0,0 +1,144 @@
+// ==========================================================================
+// Plyr source update
+// ==========================================================================
+
+import { providers } from './types';
+import utils from './utils';
+import media from './media';
+import ui from './ui';
+import support from './support';
+
+const source = {
+ // Add elements to HTML5 media (source, tracks, etc)
+ insertElements(type, attributes) {
+ if (utils.is.string(attributes)) {
+ utils.insertElement(type, this.media, {
+ src: attributes,
+ });
+ } else if (utils.is.array(attributes)) {
+ attributes.forEach(attribute => {
+ utils.insertElement(type, this.media, attribute);
+ });
+ }
+ },
+
+ // Update source
+ // Sources are not checked for support so be careful
+ change(input) {
+ if (!utils.is.object(input) || !('sources' in input) || !input.sources.length) {
+ this.debug.warn('Invalid source format');
+ return;
+ }
+
+ // Cancel current network requests
+ media.cancelRequests.call(this);
+
+ // Destroy instance and re-setup
+ this.destroy.call(
+ this,
+ () => {
+ // TODO: Reset menus here
+
+ // Remove elements
+ utils.removeElement(this.media);
+ this.media = null;
+
+ // Reset class name
+ if (utils.is.element(this.elements.container)) {
+ this.elements.container.removeAttribute('class');
+ }
+
+ // Set the type and provider
+ this.type = input.type;
+ this.provider = !utils.is.empty(input.sources[0].provider) ? input.sources[0].provider : providers.html5;
+
+ // Check for support
+ this.supported = support.check(this.type, this.provider, this.config.inline);
+
+ // Create new markup
+ switch (`${this.provider}:${this.type}`) {
+ case 'html5:video':
+ this.media = utils.createElement('video');
+ break;
+
+ case 'html5:audio':
+ this.media = utils.createElement('audio');
+ break;
+
+ case 'youtube:video':
+ case 'vimeo:video':
+ this.media = utils.createElement('div');
+ this.embedId = input.sources[0].src;
+ break;
+
+ default:
+ break;
+ }
+
+ // Inject the new element
+ this.elements.container.appendChild(this.media);
+
+ // Autoplay the new source?
+ if (utils.is.boolean(input.autoplay)) {
+ this.config.autoplay = input.autoplay;
+ }
+
+ // Set attributes for audio and video
+ if (this.isHTML5) {
+ if (this.config.crossorigin) {
+ this.media.setAttribute('crossorigin', '');
+ }
+ if (this.config.autoplay) {
+ this.media.setAttribute('autoplay', '');
+ }
+ if ('poster' in input) {
+ this.media.setAttribute('poster', input.poster);
+ }
+ if (this.config.loop.active) {
+ this.media.setAttribute('loop', '');
+ }
+ if (this.config.muted) {
+ this.media.setAttribute('muted', '');
+ }
+ if (this.config.inline) {
+ this.media.setAttribute('playsinline', '');
+ }
+ }
+
+ // Restore class hook
+ ui.addStyleHook.call(this);
+
+ // Set new sources for html5
+ if (this.isHTML5) {
+ source.insertElements.call(this, 'source', input.sources);
+ }
+
+ // Set video title
+ this.config.title = input.title;
+
+ // Set up from scratch
+ media.setup.call(this);
+
+ // HTML5 stuff
+ if (this.isHTML5) {
+ // Setup captions
+ if ('tracks' in input) {
+ source.insertElements.call(this, 'track', input.tracks);
+ }
+
+ // Load HTML5 sources
+ this.media.load();
+ }
+
+ // If HTML5 or embed but not fully supported, setupInterface and call ready now
+ if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {
+ // Setup interface
+ ui.build.call(this);
+ }
+ },
+ true
+ );
+ },
+};
+
+export default source;