░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/datadrive/moodledata/filedir/df/76
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: df76ae09d0ddd6a1dadf7e12246666228c635776
/** @namespace H5P */ H5P.Video = (function ($, ContentCopyrights, MediaCopyright, handlers) { /** * The ultimate H5P video player! * * @class * @param {Object} parameters Options for this library. * @param {Object} parameters.visuals Visual options * @param {Object} parameters.playback Playback options * @param {Object} parameters.a11y Accessibility options * @param {Boolean} [parameters.startAt] Start time of video * @param {Number} id Content identifier * @param {Object} [extras] Extra parameters. */ function Video(parameters, id, extras = {}) { var self = this; self.oldTime = extras.previousState?.time; self.contentId = id; self.WAS_RESET = false; self.startAt = parameters.startAt || 0; // Ref youtube.js - ipad & youtube - issue self.pressToPlay = false; // Reference to the handler var handlerName = ''; // Initialize event inheritance H5P.EventDispatcher.call(self); // Default language localization parameters = $.extend(true, parameters, { l10n: { name: 'Video', loading: 'Video player loading...', noPlayers: 'Found no video players that supports the given video format.', noSources: 'Video source is missing.', aborted: 'Media playback has been aborted.', networkFailure: 'Network failure.', cannotDecode: 'Unable to decode media.', formatNotSupported: 'Video format not supported.', mediaEncrypted: 'Media encrypted.', unknownError: 'Unknown error.', vimeoPasswordError: 'Password-protected Vimeo videos are not supported.', vimeoPrivacyError: 'The Vimeo video cannot be used due to its privacy settings.', vimeoLoadingError: 'The Vimeo video could not be loaded.', invalidYtId: 'Invalid YouTube ID.', unknownYtId: 'Unable to find video with the given YouTube ID.', restrictedYt: 'The owner of this video does not allow it to be embedded.' } }); parameters.a11y = parameters.a11y || []; parameters.playback = parameters.playback || {}; parameters.visuals = $.extend( true, { disableFullscreen: false }, parameters.visuals ); /** @private */ var sources = []; if (parameters.sources) { for (var i = 0; i < parameters.sources.length; i++) { // Clone to avoid changing of parameters. var source = $.extend(true, {}, parameters.sources[i]); // Create working URL without html entities. source.path = $cleaner.html(source.path).text(); sources.push(source); } } /** @private */ var tracks = []; parameters.a11y.forEach(function (track) { // Clone to avoid changing of parameters. var clone = $.extend(true, {}, track); // Create working URL without html entities if (clone.track && clone.track.path) { clone.track.path = $cleaner.html(clone.track.path).text(); tracks.push(clone); } }); /** * Handle autoplay. If autoplay is disabled, it will still autopause when * video is not visible. * * @param {*} $container */ const handleAutoPlayPause = function ($container) { // Keep the current state let state; self.on('stateChange', function(event) { state = event.data; }); // Keep record of autopauses. // I.e: we don't wanna autoplay if the user has excplicitly paused. self.autoPaused = !self.pressToPlay; new IntersectionObserver(function (entries) { const entry = entries[0]; // This video element became visible if (entry.isIntersecting) { // Autoplay if autoplay is enabled and it was not explicitly // paused by a user if (parameters.playback.autoplay && self.autoPaused) { self.autoPaused = false; self.play(); } } else if (state !== Video.PAUSED && state !== Video.ENDED) { self.autoPaused = true; self.pause(); } }, { root: null, threshold: [0, 1] // Get events when it is shown and hidden }).observe($container.get(0)); }; /** * Attaches the video handler to the given container. * Inserts text if no handler is found. * * @public * @param {jQuery} $container */ self.attach = function ($container) { $container.addClass('h5p-video').html(''); if (self.appendTo !== undefined) { self.appendTo($container); // Avoid autoplaying in authoring tool if (window.H5PEditor === undefined) { handleAutoPlayPause($container); } } else if (sources.length) { $container.text(parameters.l10n.noPlayers); } else { $container.text(parameters.l10n.noSources); } }; /** * Get name of the video handler * * @public * @returns {string} */ self.getHandlerName = function() { return handlerName; }; /** * @public * Get current state for resume support. * * @returns {object} Current state. */ self.getCurrentState = function () { if (self.getCurrentTime) { return { time: self.getCurrentTime() || self.oldTime, }; } }; /** * The two functions below needs to be defined in this base class, * since it is used in this class even if no handler was found. */ self.seek = () => {}; self.pause = () => {}; /** * @public * Reset current state (time). * */ self.resetTask = function () { delete self.oldTime; self.resetPlayback(parameters.startAt || 0); }; /** * Default implementation of resetPlayback. May be overridden by sub classes. * * @param {*} startAt */ self.resetPlayback = startAt => { self.seek(startAt); self.pause(); self.WAS_RESET = true; }; // Resize the video when we know its aspect ratio self.on('loaded', function () { self.trigger('resize'); // reset time if wasn't done immediately if (self.WAS_RESET) { self.seek(parameters.startAt || 0); if (!parameters.playback.autoplay) { self.pause(); } self.WAS_RESET = false; } }); // Find player for video sources if (sources.length) { const options = { controls: parameters.visuals.controls, autoplay: parameters.playback.autoplay, loop: parameters.playback.loop, fit: parameters.visuals.fit, poster: parameters.visuals.poster === undefined ? undefined : parameters.visuals.poster, tracks: tracks, disableRemotePlayback: parameters.visuals.disableRemotePlayback === true, disableFullscreen: parameters.visuals.disableFullscreen === true, deactivateSound: parameters.playback.deactivateSound, } if (!self.WAS_RESET) { options.startAt = self.oldTime !== undefined ? self.oldTime : (parameters.startAt || 0); } var html5Handler; for (var i = 0; i < handlers.length; i++) { var handler = handlers[i]; if (handler.canPlay !== undefined && handler.canPlay(sources)) { handler.call(self, sources, options, parameters.l10n); handlerName = handler.name; return; } if (handler === H5P.VideoHtml5) { html5Handler = handler; handlerName = handler.name; } } // Fallback to trying HTML5 player if (html5Handler) { html5Handler.call(self, sources, options, parameters.l10n); } } } // Extends the event dispatcher Video.prototype = Object.create(H5P.EventDispatcher.prototype); Video.prototype.constructor = Video; // Player states /** @constant {Number} */ Video.ENDED = 0; /** @constant {Number} */ Video.PLAYING = 1; /** @constant {Number} */ Video.PAUSED = 2; /** @constant {Number} */ Video.BUFFERING = 3; /** * When video is queued to start * @constant {Number} */ Video.VIDEO_CUED = 5; // Used to convert between html and text, since URLs have html entities. var $cleaner = H5P.jQuery('<div/>'); /** * Help keep track of key value pairs used by the UI. * * @class * @param {string} label * @param {string} value */ Video.LabelValue = function (label, value) { this.label = label; this.value = value; }; /** * Determine whether video can be autoplayed. * @returns {Promise<boolean>} Whether autoplay is allowed. */ Video.isAutoplayAllowed = async () => { if (document.featurePolicy?.allowsFeature('autoplay')) { return true; // Browser supports `featurePolicy` and can tell directly } const video = document.createElement('video'); /* * Without a video source, the play Promise will be rejected with an error * if it cannot be autoplayed, but not resolve at all if it can be * autoplayed. Using a timeout to detect the latter case here. */ const timeoutMs = 50; // If play promise rejects, then within few ms const timeoutPromise = new Promise((resolve) => { window.setTimeout(() => { resolve(true); // Timeout reached, autoplay is allowed }, timeoutMs); }); let result; try { result = (await Promise.race([video.play(), timeoutPromise])) ?? true; } catch (error) { result = false; } return result; }; /** @constant {Boolean} */ Video.IE11_PLAYBACK_RATE_FIX = (navigator.userAgent.match(/Trident.*rv[ :]*11\./) ? true : false); return Video; })(H5P.jQuery, H5P.ContentCopyrights, H5P.MediaCopyright, H5P.videoHandlers || []);
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 df766f21c261343f7b7f4682b5a7c2f334593376
?
7.8 KB
2025-02-01 12:32
EDIT
📄 df76ae09d0ddd6a1dadf7e12246666228c635776
?
9.5 KB
2026-04-01 13:33
EDIT