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.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/js/source.js b/src/js/source.js
new file mode 100644
index 00000000..d2d5f61a
--- /dev/null
+++ b/src/js/source.js
@@ -0,0 +1,162 @@
+// ==========================================================================
+// Plyr source update
+// ==========================================================================
+
+import types 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)) {
+ this.warn(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.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.htmlElement(this.elements.container)) {
+ this.elements.container.removeAttribute('class');
+ }
+
+ // Set the type
+ if ('type' in input) {
+ this.type = input.type;
+
+ // Get child type for video (it might be an embed)
+ if (this.type === 'video') {
+ const firstSource = input.sources[0];
+
+ if ('type' in firstSource && types.embed.includes(firstSource.type)) {
+ this.type = firstSource.type;
+ }
+ }
+ }
+
+ // Check for support
+ this.supported = support.check(this.type, this.config.inline);
+
+ // Create new markup
+ switch (this.type) {
+ case 'video':
+ this.media = utils.createElement('video');
+ break;
+
+ case 'audio':
+ this.media = utils.createElement('audio');
+ break;
+
+ case 'youtube':
+ case 'vimeo':
+ 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 hooks
+ utils.toggleClass(
+ this.elements.container,
+ this.config.classNames.captions.active,
+ this.supported.ui && this.captions.enabled
+ );
+
+ 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;