Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
2c8a337f26 | |||
c24e52d97d | |||
574f40949c | |||
cf3848fbd5 | |||
a19ad69038 | |||
d6f20e2756 | |||
e2fc20ca76 | |||
37c3f7109d | |||
99d5211a33 | |||
b97f143195 | |||
e8da4326b6 | |||
67f908aa8d | |||
65eb5c1b8b | |||
7d484c6e09 | |||
8252e13eb9 |
364
changelog.md
364
changelog.md
File diff suppressed because it is too large
Load Diff
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
@ -7,7 +7,8 @@
|
||||
font-family: 'Gordita';
|
||||
font-style: normal;
|
||||
font-weight: $font-weight-light;
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-light.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-light.woff') format('woff');
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-light.woff2') format('woff2'),
|
||||
url('https://cdn.plyr.io/static/fonts/gordita-light.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@ -33,7 +34,8 @@
|
||||
font-family: 'Gordita';
|
||||
font-style: normal;
|
||||
font-weight: $font-weight-bold;
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-bold.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-bold.woff') format('woff');
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-bold.woff2') format('woff2'),
|
||||
url('https://cdn.plyr.io/static/fonts/gordita-bold.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@ -41,5 +43,6 @@
|
||||
font-family: 'Gordita';
|
||||
font-style: normal;
|
||||
font-weight: $font-weight-black;
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-black.woff2') format('woff2'), url('https://cdn.plyr.io/static/fonts/gordita-black.woff') format('woff');
|
||||
src: url('https://cdn.plyr.io/static/fonts/gordita-black.woff2') format('woff2'),
|
||||
url('https://cdn.plyr.io/static/fonts/gordita-black.woff') format('woff');
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ $plyr-font-size-small: 12px;
|
||||
$plyr-font-size-time: 11px;
|
||||
$plyr-font-size-badges: 9px;
|
||||
|
||||
// Other
|
||||
$plyr-font-smoothing: true;
|
||||
|
||||
// Captions
|
||||
$plyr-font-size-captions-base: $plyr-font-size-base;
|
||||
$plyr-font-size-captions-small: $plyr-font-size-small;
|
||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
78
dist/plyr.js
vendored
78
dist/plyr.js
vendored
@ -570,15 +570,12 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
} // Element matches selector
|
||||
|
||||
function matches(element, selector) {
|
||||
var prototype = {
|
||||
Element: Element
|
||||
};
|
||||
|
||||
function match() {
|
||||
return Array.from(document.querySelectorAll(selector)).includes(this);
|
||||
}
|
||||
|
||||
var matches = prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || match;
|
||||
var matches = match;
|
||||
return matches.call(element, selector);
|
||||
} // Find all elements
|
||||
|
||||
@ -634,7 +631,9 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
} // Set regular focus
|
||||
|
||||
|
||||
element.focus(); // If we want to mimic keyboard focus via tab
|
||||
element.focus({
|
||||
preventScroll: true
|
||||
}); // If we want to mimic keyboard focus via tab
|
||||
|
||||
if (tabFocus) {
|
||||
toggleClass(element, this.config.classNames.tabFocus);
|
||||
@ -739,26 +738,20 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
_inputType$split2 = _slicedToArray(_inputType$split, 1),
|
||||
mediaType = _inputType$split2[0];
|
||||
|
||||
var type = inputType; // Verify we're using HTML5 and there's no media type mismatch
|
||||
|
||||
if (!this.isHTML5 || mediaType !== this.type) {
|
||||
return false;
|
||||
}
|
||||
} // Add codec if required
|
||||
|
||||
var type;
|
||||
|
||||
if (inputType && inputType.includes('codecs=')) {
|
||||
// Use input directly
|
||||
type = inputType;
|
||||
} else if (inputType === 'audio/mpeg') {
|
||||
// Skip codec
|
||||
type = 'audio/mpeg;';
|
||||
} else if (inputType in defaultCodecs) {
|
||||
// Use codec
|
||||
type = "".concat(inputType, "; codecs=\"").concat(defaultCodecs[inputType], "\"");
|
||||
if (Object.keys(defaultCodecs).includes(type)) {
|
||||
type += "; codecs=\"".concat(defaultCodecs[inputType], "\"");
|
||||
}
|
||||
|
||||
try {
|
||||
return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));
|
||||
} catch (err) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@ -3192,7 +3185,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.6/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.7/plyr.svg',
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
// Quality default
|
||||
@ -4315,7 +4308,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}); // Check for audio tracks on load
|
||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||
|
||||
on.call(player, player.media, 'canplay', function () {
|
||||
on.call(player, player.media, 'canplay loadeddata', function () {
|
||||
toggleHidden(elements.volume, !player.hasAudio);
|
||||
toggleHidden(elements.buttons.mute, !player.hasAudio);
|
||||
}); // Handle the media finishing
|
||||
@ -4710,9 +4703,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
|
||||
var loadjs_umd = createCommonjsModule(function (module, exports) {
|
||||
(function(root, factory) {
|
||||
if (typeof undefined === 'function' && undefined.amd) {
|
||||
undefined([], factory);
|
||||
} else {
|
||||
{
|
||||
module.exports = factory();
|
||||
}
|
||||
}(commonjsGlobal, function() {
|
||||
@ -5069,12 +5060,13 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Set aspect ratio
|
||||
// For Vimeo we have an extra 300% height <div> to hide the standard controls and UI
|
||||
setAspectRatio: function setAspectRatio(input) {
|
||||
var _split = (is.string(input) ? input : this.config.ratio).split(':'),
|
||||
_split2 = _slicedToArray(_split, 2),
|
||||
x = _split2[0],
|
||||
y = _split2[1];
|
||||
var _split$map = (is.string(input) ? input : this.config.ratio).split(':').map(Number),
|
||||
_split$map2 = _slicedToArray(_split$map, 2),
|
||||
x = _split$map2[0],
|
||||
y = _split$map2[1];
|
||||
|
||||
var padding = 100 / x * y;
|
||||
vimeo.padding = padding;
|
||||
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%");
|
||||
|
||||
if (this.supported.ui) {
|
||||
@ -5278,8 +5270,8 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}); // Set aspect ratio based on video size
|
||||
|
||||
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(function (dimensions) {
|
||||
var ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(_this2, ratio);
|
||||
vimeo.ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(_this2, vimeo.ratio);
|
||||
}); // Set autopause
|
||||
|
||||
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
||||
@ -5370,6 +5362,24 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
player.embed.on('error', function (detail) {
|
||||
player.media.error = detail;
|
||||
triggerEvent.call(player, player.media, 'error');
|
||||
}); // Set height/width on fullscreen
|
||||
|
||||
player.on('enterfullscreen exitfullscreen', function (event) {
|
||||
var target = player.fullscreen.target; // Ignore for iOS native
|
||||
|
||||
if (target !== player.elements.container) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toggle = event.type === 'enterfullscreen';
|
||||
|
||||
var _vimeo$ratio$split$ma = vimeo.ratio.split(':').map(Number),
|
||||
_vimeo$ratio$split$ma2 = _slicedToArray(_vimeo$ratio$split$ma, 2),
|
||||
x = _vimeo$ratio$split$ma2[0],
|
||||
y = _vimeo$ratio$split$ma2[1];
|
||||
|
||||
var dimension = x > y ? 'width' : 'height';
|
||||
target.style[dimension] = toggle ? "".concat(vimeo.padding, "%") : null;
|
||||
}); // Rebuild UI
|
||||
|
||||
setTimeout(function () {
|
||||
@ -6547,18 +6557,20 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
|
||||
if (_this2.isHTML5) {
|
||||
// Setup captions
|
||||
if ('tracks' in input) {
|
||||
if (Object.keys(input).includes('tracks')) {
|
||||
source.insertElements.call(_this2, 'track', input.tracks);
|
||||
} // Load HTML5 sources
|
||||
|
||||
|
||||
_this2.media.load();
|
||||
}
|
||||
} // If HTML5 or embed but not fully supported, setupInterface and call ready now
|
||||
|
||||
|
||||
if (_this2.isHTML5 || _this2.isEmbed && !_this2.supported.ui) {
|
||||
// Setup interface
|
||||
ui.build.call(_this2);
|
||||
}
|
||||
|
||||
if (_this2.isHTML5) {
|
||||
// Load HTML5 sources
|
||||
_this2.media.load();
|
||||
} // Update the fullscreen support
|
||||
|
||||
|
||||
|
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
84
dist/plyr.polyfilled.js
vendored
84
dist/plyr.polyfilled.js
vendored
@ -1480,7 +1480,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Set @@toStringTag to native iterators
|
||||
_setToStringTag(IteratorPrototype, TAG, true);
|
||||
// fix for some old engines
|
||||
if (typeof IteratorPrototype[ITERATOR$3] != 'function') _hide(IteratorPrototype, ITERATOR$3, returnThis);
|
||||
if (!_library && typeof IteratorPrototype[ITERATOR$3] != 'function') _hide(IteratorPrototype, ITERATOR$3, returnThis);
|
||||
}
|
||||
}
|
||||
// fix Array#{values, @@iterator}.name in V8 / FF
|
||||
@ -1489,7 +1489,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
$default = function values() { return $native.call(this); };
|
||||
}
|
||||
// Define iterator
|
||||
if (BUGGY || VALUES_BUG || !proto[ITERATOR$3]) {
|
||||
if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR$3])) {
|
||||
_hide(proto, ITERATOR$3, $default);
|
||||
}
|
||||
// Plug for library
|
||||
@ -2650,7 +2650,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
return capability.promise;
|
||||
}
|
||||
});
|
||||
_export(_export.S + _export.F * (!USE_NATIVE), PROMISE, {
|
||||
_export(_export.S + _export.F * (_library || !USE_NATIVE), PROMISE, {
|
||||
// 25.4.4.6 Promise.resolve(x)
|
||||
resolve: function resolve(x) {
|
||||
return _promiseResolve(_library && this === Wrapper ? $Promise : this, x);
|
||||
@ -3195,15 +3195,12 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
} // Element matches selector
|
||||
|
||||
function matches(element, selector) {
|
||||
var prototype = {
|
||||
Element: Element
|
||||
};
|
||||
|
||||
function match() {
|
||||
return Array.from(document.querySelectorAll(selector)).includes(this);
|
||||
}
|
||||
|
||||
var matches = prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || match;
|
||||
var matches = match;
|
||||
return matches.call(element, selector);
|
||||
} // Find all elements
|
||||
|
||||
@ -3259,7 +3256,9 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
} // Set regular focus
|
||||
|
||||
|
||||
element.focus(); // If we want to mimic keyboard focus via tab
|
||||
element.focus({
|
||||
preventScroll: true
|
||||
}); // If we want to mimic keyboard focus via tab
|
||||
|
||||
if (tabFocus) {
|
||||
toggleClass(element, this.config.classNames.tabFocus);
|
||||
@ -3363,26 +3362,20 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
_inputType$split2 = _slicedToArray(_inputType$split, 1),
|
||||
mediaType = _inputType$split2[0];
|
||||
|
||||
var type = inputType; // Verify we're using HTML5 and there's no media type mismatch
|
||||
|
||||
if (!this.isHTML5 || mediaType !== this.type) {
|
||||
return false;
|
||||
}
|
||||
} // Add codec if required
|
||||
|
||||
var type;
|
||||
|
||||
if (inputType && inputType.includes('codecs=')) {
|
||||
// Use input directly
|
||||
type = inputType;
|
||||
} else if (inputType === 'audio/mpeg') {
|
||||
// Skip codec
|
||||
type = 'audio/mpeg;';
|
||||
} else if (inputType in defaultCodecs) {
|
||||
// Use codec
|
||||
type = "".concat(inputType, "; codecs=\"").concat(defaultCodecs[inputType], "\"");
|
||||
if (Object.keys(defaultCodecs).includes(type)) {
|
||||
type += "; codecs=\"".concat(defaultCodecs[inputType], "\"");
|
||||
}
|
||||
|
||||
try {
|
||||
return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));
|
||||
} catch (err) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
@ -5855,7 +5848,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.6/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.7/plyr.svg',
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
// Quality default
|
||||
@ -6988,7 +6981,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}); // Check for audio tracks on load
|
||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||
|
||||
on.call(player, player.media, 'canplay', function () {
|
||||
on.call(player, player.media, 'canplay loadeddata', function () {
|
||||
toggleHidden(elements.volume, !player.hasAudio);
|
||||
toggleHidden(elements.buttons.mute, !player.hasAudio);
|
||||
}); // Handle the media finishing
|
||||
@ -7404,9 +7397,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
|
||||
var loadjs_umd = createCommonjsModule(function (module, exports) {
|
||||
(function(root, factory) {
|
||||
if (typeof undefined === 'function' && undefined.amd) {
|
||||
undefined([], factory);
|
||||
} else {
|
||||
{
|
||||
module.exports = factory();
|
||||
}
|
||||
}(commonjsGlobal, function() {
|
||||
@ -7762,12 +7753,13 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Set aspect ratio
|
||||
// For Vimeo we have an extra 300% height <div> to hide the standard controls and UI
|
||||
setAspectRatio: function setAspectRatio(input) {
|
||||
var _split = (is$1.string(input) ? input : this.config.ratio).split(':'),
|
||||
_split2 = _slicedToArray(_split, 2),
|
||||
x = _split2[0],
|
||||
y = _split2[1];
|
||||
var _split$map = (is$1.string(input) ? input : this.config.ratio).split(':').map(Number),
|
||||
_split$map2 = _slicedToArray(_split$map, 2),
|
||||
x = _split$map2[0],
|
||||
y = _split$map2[1];
|
||||
|
||||
var padding = 100 / x * y;
|
||||
vimeo.padding = padding;
|
||||
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%");
|
||||
|
||||
if (this.supported.ui) {
|
||||
@ -7971,8 +7963,8 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}); // Set aspect ratio based on video size
|
||||
|
||||
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(function (dimensions) {
|
||||
var ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(_this2, ratio);
|
||||
vimeo.ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(_this2, vimeo.ratio);
|
||||
}); // Set autopause
|
||||
|
||||
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
||||
@ -8063,6 +8055,24 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
player.embed.on('error', function (detail) {
|
||||
player.media.error = detail;
|
||||
triggerEvent.call(player, player.media, 'error');
|
||||
}); // Set height/width on fullscreen
|
||||
|
||||
player.on('enterfullscreen exitfullscreen', function (event) {
|
||||
var target = player.fullscreen.target; // Ignore for iOS native
|
||||
|
||||
if (target !== player.elements.container) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toggle = event.type === 'enterfullscreen';
|
||||
|
||||
var _vimeo$ratio$split$ma = vimeo.ratio.split(':').map(Number),
|
||||
_vimeo$ratio$split$ma2 = _slicedToArray(_vimeo$ratio$split$ma, 2),
|
||||
x = _vimeo$ratio$split$ma2[0],
|
||||
y = _vimeo$ratio$split$ma2[1];
|
||||
|
||||
var dimension = x > y ? 'width' : 'height';
|
||||
target.style[dimension] = toggle ? "".concat(vimeo.padding, "%") : null;
|
||||
}); // Rebuild UI
|
||||
|
||||
setTimeout(function () {
|
||||
@ -9237,18 +9247,20 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
|
||||
if (_this2.isHTML5) {
|
||||
// Setup captions
|
||||
if ('tracks' in input) {
|
||||
if (Object.keys(input).includes('tracks')) {
|
||||
source.insertElements.call(_this2, 'track', input.tracks);
|
||||
} // Load HTML5 sources
|
||||
|
||||
|
||||
_this2.media.load();
|
||||
}
|
||||
} // If HTML5 or embed but not fully supported, setupInterface and call ready now
|
||||
|
||||
|
||||
if (_this2.isHTML5 || _this2.isEmbed && !_this2.supported.ui) {
|
||||
// Setup interface
|
||||
ui.build.call(_this2);
|
||||
}
|
||||
|
||||
if (_this2.isHTML5) {
|
||||
// Load HTML5 sources
|
||||
_this2.media.load();
|
||||
} // Update the fullscreen support
|
||||
|
||||
|
||||
|
2
dist/plyr.polyfilled.js.map
vendored
2
dist/plyr.polyfilled.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js
vendored
2
dist/plyr.polyfilled.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js.map
vendored
2
dist/plyr.polyfilled.min.js.map
vendored
File diff suppressed because one or more lines are too long
40
gulpfile.js
40
gulpfile.js
@ -12,7 +12,6 @@ const concat = require('gulp-concat');
|
||||
const filter = require('gulp-filter');
|
||||
const sass = require('gulp-sass');
|
||||
const cleancss = require('gulp-clean-css');
|
||||
const run = require('run-sequence');
|
||||
const header = require('gulp-header');
|
||||
const prefix = require('gulp-autoprefixer');
|
||||
const gitbranch = require('git-branch');
|
||||
@ -106,13 +105,15 @@ const babelrc = (polyfill = false) => ({
|
||||
});
|
||||
|
||||
// Clean out /dist
|
||||
gulp.task('clean', () => {
|
||||
gulp.task('clean', done => {
|
||||
const dirs = [paths.plyr.output, paths.demo.output].map(dir => path.join(dir, '**/*'));
|
||||
|
||||
// Don't delete the mp4
|
||||
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
|
||||
|
||||
del(dirs);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
const build = {
|
||||
@ -201,31 +202,25 @@ build.sass(bundles.demo.sass, 'demo');
|
||||
build.js(bundles.demo.js, 'demo', { format: 'iife' });
|
||||
|
||||
// Build all JS
|
||||
gulp.task('js', () => {
|
||||
run(tasks.js);
|
||||
});
|
||||
gulp.task('js', () => gulp.parallel(tasks.js));
|
||||
|
||||
// Watch for file changes
|
||||
gulp.task('watch', () => {
|
||||
// Plyr core
|
||||
gulp.watch(paths.plyr.src.js, tasks.js);
|
||||
gulp.watch(paths.plyr.src.sass, tasks.sass);
|
||||
gulp.watch(paths.plyr.src.sprite, tasks.sprite);
|
||||
gulp.watch(paths.plyr.src.js, gulp.parallel(tasks.js));
|
||||
gulp.watch(paths.plyr.src.sass, gulp.parallel(tasks.sass));
|
||||
gulp.watch(paths.plyr.src.sprite, gulp.parallel(tasks.sprite));
|
||||
|
||||
// Demo
|
||||
gulp.watch(paths.demo.src.js, tasks.js);
|
||||
gulp.watch(paths.demo.src.sass, tasks.sass);
|
||||
gulp.watch(paths.demo.src.js, gulp.parallel(tasks.js));
|
||||
gulp.watch(paths.demo.src.sass, gulp.parallel(tasks.sass));
|
||||
});
|
||||
|
||||
// Build distribution
|
||||
gulp.task('build', () => {
|
||||
run(tasks.clean, tasks.js, tasks.sass, tasks.sprite);
|
||||
});
|
||||
gulp.task('build', gulp.series(tasks.clean, gulp.parallel(tasks.js, tasks.sass, tasks.sprite)));
|
||||
|
||||
// Default gulp task
|
||||
gulp.task('default', () => {
|
||||
run('build', 'watch');
|
||||
});
|
||||
gulp.task('default', gulp.series('build', 'watch'));
|
||||
|
||||
// Publish a version to CDN and demo
|
||||
// --------------------------------------------
|
||||
@ -452,7 +447,16 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
|
||||
});
|
||||
|
||||
// Do everything
|
||||
gulp.task('deploy', () =>
|
||||
run('version', tasks.clean, tasks.js, tasks.sass, tasks.sprite, 'cdn', 'purge', 'demo', 'open'),
|
||||
gulp.task(
|
||||
'deploy',
|
||||
gulp.series(
|
||||
'version',
|
||||
tasks.clean,
|
||||
gulp.parallel(tasks.js, tasks.sass, tasks.sprite),
|
||||
'cdn',
|
||||
'demo',
|
||||
'purge',
|
||||
'open',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
23
package.json
23
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.7",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "https://plyr.io",
|
||||
"author": "Sam Potts <sam@potts.es>",
|
||||
@ -35,19 +35,19 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"@babel/core": "^7.1.5",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/preset-env": "^7.1.5",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^5.7.0",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"eslint-config-prettier": "^3.1.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"fastly-purge": "^1.0.1",
|
||||
"git-branch": "^2.0.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-autoprefixer": "^6.0.0",
|
||||
"gulp-better-rollup": "^3.3.0",
|
||||
"gulp-better-rollup": "^3.4.0",
|
||||
"gulp-clean-css": "^3.10.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-filter": "^5.1.0",
|
||||
@ -64,23 +64,22 @@
|
||||
"gulp-svgstore": "^7.0.0",
|
||||
"gulp-uglify-es": "^1.0.4",
|
||||
"gulp-util": "^3.0.8",
|
||||
"postcss-custom-properties": "^8.0.8",
|
||||
"postcss-custom-properties": "^8.0.9",
|
||||
"prettier-eslint": "^8.8.2",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"remark-cli": "^5.0.0",
|
||||
"remark-cli": "^6.0.0",
|
||||
"remark-validate-links": "^7.1.0",
|
||||
"rollup-plugin-babel": "^4.0.3",
|
||||
"rollup-plugin-commonjs": "^9.2.0",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"run-sequence": "^2.2.1",
|
||||
"stylelint": "^9.6.0",
|
||||
"stylelint": "^9.7.1",
|
||||
"stylelint-config-prettier": "^4.0.0",
|
||||
"stylelint-config-recommended": "^2.1.0",
|
||||
"stylelint-config-sass-guidelines": "^5.2.0",
|
||||
"stylelint-order": "^1.0.0",
|
||||
"stylelint-scss": "^3.3.2",
|
||||
"stylelint-scss": "^3.4.0",
|
||||
"stylelint-selector-bem-pattern": "^2.0.0",
|
||||
"through2": "^2.0.3"
|
||||
"through2": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^2.5.7",
|
||||
|
11
readme.md
11
readme.md
@ -132,13 +132,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.4.6/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.4.7/plyr.js"></script>
|
||||
```
|
||||
|
||||
...or...
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.4.6/plyr.polyfilled.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.4.7/plyr.polyfilled.js"></script>
|
||||
```
|
||||
|
||||
### CSS
|
||||
@ -152,13 +152,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.6/plyr.css">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.7/plyr.css">
|
||||
```
|
||||
|
||||
### SVG Sprite
|
||||
|
||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.6/plyr.svg`.
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.7/plyr.svg`.
|
||||
|
||||
## Ads
|
||||
|
||||
@ -417,7 +417,7 @@ player.fullscreen.active; // false;
|
||||
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. |
|
||||
| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
|
||||
| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
|
||||
| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
|
||||
| `pip`² | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
|
||||
|
||||
1. YouTube only. HTML5 will follow.
|
||||
2. HTML5 only
|
||||
@ -714,6 +714,7 @@ Plyr costs money to run, not only my time. I donate my time for free as I enjoy
|
||||
- [koel - A personal music streaming server that works.](http://koel.phanan.net/)
|
||||
- [Oscar Radio](http://oscar-radio.xyz/)
|
||||
- [Sparkk TV](https://www.sparkktv.com/)
|
||||
- [@halfhalftravel](https://www.halfhalftravel.com/)
|
||||
|
||||
Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the above list. It'd be awesome to see how you're using Plyr :-)
|
||||
|
||||
|
@ -60,7 +60,7 @@ const defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
iconPrefix: 'plyr',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.6/plyr.svg',
|
||||
iconUrl: 'https://cdn.plyr.io/3.4.7/plyr.svg',
|
||||
|
||||
// Blank video (used to prevent errors on source change)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
|
@ -317,7 +317,7 @@ class Listeners {
|
||||
|
||||
// Check for audio tracks on load
|
||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||
on.call(player, player.media, 'canplay', () => {
|
||||
on.call(player, player.media, 'canplay loadeddata', () => {
|
||||
toggleHidden(elements.volume, !player.hasAudio);
|
||||
toggleHidden(elements.buttons.mute, !player.hasAudio);
|
||||
});
|
||||
|
@ -70,8 +70,9 @@ const vimeo = {
|
||||
// Set aspect ratio
|
||||
// For Vimeo we have an extra 300% height <div> to hide the standard controls and UI
|
||||
setAspectRatio(input) {
|
||||
const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');
|
||||
const [x, y] = (is.string(input) ? input : this.config.ratio).split(':').map(Number);
|
||||
const padding = (100 / x) * y;
|
||||
vimeo.padding = padding;
|
||||
this.elements.wrapper.style.paddingBottom = `${padding}%`;
|
||||
|
||||
if (this.supported.ui) {
|
||||
@ -299,8 +300,8 @@ const vimeo = {
|
||||
|
||||
// Set aspect ratio based on video size
|
||||
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {
|
||||
const ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(this, ratio);
|
||||
vimeo.ratio = getAspectRatio(dimensions[0], dimensions[1]);
|
||||
vimeo.setAspectRatio.call(this, vimeo.ratio);
|
||||
});
|
||||
|
||||
// Set autopause
|
||||
@ -404,6 +405,22 @@ const vimeo = {
|
||||
triggerEvent.call(player, player.media, 'error');
|
||||
});
|
||||
|
||||
// Set height/width on fullscreen
|
||||
player.on('enterfullscreen exitfullscreen', event => {
|
||||
const { target } = player.fullscreen;
|
||||
|
||||
// Ignore for iOS native
|
||||
if (target !== player.elements.container) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toggle = event.type === 'enterfullscreen';
|
||||
const [x, y] = vimeo.ratio.split(':').map(Number);
|
||||
const dimension = x > y ? 'width' : 'height';
|
||||
|
||||
target.style[dimension] = toggle ? `${vimeo.padding}%` : null;
|
||||
});
|
||||
|
||||
// Rebuild UI
|
||||
setTimeout(() => ui.build.call(player), 0);
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v3.4.6
|
||||
// plyr.js v3.4.7
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr Polyfilled Build
|
||||
// plyr.js v3.4.6
|
||||
// plyr.js v3.4.7
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
@ -114,12 +114,9 @@ const source = {
|
||||
// HTML5 stuff
|
||||
if (this.isHTML5) {
|
||||
// Setup captions
|
||||
if ('tracks' in input) {
|
||||
if (Object.keys(input).includes('tracks')) {
|
||||
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
|
||||
@ -128,6 +125,11 @@ const source = {
|
||||
ui.build.call(this);
|
||||
}
|
||||
|
||||
if (this.isHTML5) {
|
||||
// Load HTML5 sources
|
||||
this.media.load();
|
||||
}
|
||||
|
||||
// Update the fullscreen support
|
||||
this.fullscreen.update();
|
||||
},
|
||||
|
@ -70,25 +70,21 @@ const support = {
|
||||
// Related: http://www.leanbackplayer.com/test/h5mt.html
|
||||
mime(inputType) {
|
||||
const [mediaType] = inputType.split('/');
|
||||
let type = inputType;
|
||||
|
||||
// Verify we're using HTML5 and there's no media type mismatch
|
||||
if (!this.isHTML5 || mediaType !== this.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let type;
|
||||
if (inputType && inputType.includes('codecs=')) {
|
||||
// Use input directly
|
||||
type = inputType;
|
||||
} else if (inputType === 'audio/mpeg') {
|
||||
// Skip codec
|
||||
type = 'audio/mpeg;';
|
||||
} else if (inputType in defaultCodecs) {
|
||||
// Use codec
|
||||
type = `${inputType}; codecs="${defaultCodecs[inputType]}"`;
|
||||
// Add codec if required
|
||||
if (Object.keys(defaultCodecs).includes(type)) {
|
||||
type += `; codecs="${defaultCodecs[inputType]}"`;
|
||||
}
|
||||
|
||||
try {
|
||||
return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));
|
||||
} catch (err) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
@ -293,7 +293,7 @@ export function setFocus(element = null, tabFocus = false) {
|
||||
}
|
||||
|
||||
// Set regular focus
|
||||
element.focus();
|
||||
element.focus({ preventScroll: true });
|
||||
|
||||
// If we want to mimic keyboard focus via tab
|
||||
if (tabFocus) {
|
||||
|
@ -12,7 +12,7 @@ $plyr-range-thumb-border: 2px solid transparent !default;
|
||||
$plyr-range-thumb-shadow: 0 1px 1px rgba(#000, 0.15), 0 0 0 1px rgba($plyr-color-gunmetal, 0.2) !default;
|
||||
|
||||
// Track
|
||||
$plyr-range-track-height: 6px !default;
|
||||
$plyr-range-track-height: 4px !default;
|
||||
$plyr-range-max-height: ($plyr-range-thumb-active-shadow-width * 2) + $plyr-range-thumb-height !default;
|
||||
|
||||
// Fill
|
||||
|
@ -17,4 +17,4 @@ $plyr-font-weight-bold: 600 !default;
|
||||
|
||||
$plyr-line-height: 1.7 !default;
|
||||
|
||||
$plyr-font-smoothing: true !default;
|
||||
$plyr-font-smoothing: false !default;
|
||||
|
Reference in New Issue
Block a user