mirror of
https://github.com/videojs/video.js.git
synced 2025-07-15 01:34:23 +02:00
feat: add 'playsinline' player option (#4348)
Video.js players can accept a number of standard <video> element options (autoplay, muted, loop, etc), but not currently playsinline, which is now part of the [HTML spec](https://html.spec.whatwg.org/multipage/embedded-content.html#attr-video-playsinline). We should add it to the list of <video> attributes that can be provided to the player as options.
This commit is contained in:
committed by
Gary Katsevman
parent
35df35143f
commit
8d80a5846e
@ -860,6 +860,7 @@ class Player extends Component {
|
|||||||
'playerId': this.id(),
|
'playerId': this.id(),
|
||||||
'techId': `${this.id()}_${titleTechName}_api`,
|
'techId': `${this.id()}_${titleTechName}_api`,
|
||||||
'autoplay': this.options_.autoplay,
|
'autoplay': this.options_.autoplay,
|
||||||
|
'playsinline': this.options_.playsinline,
|
||||||
'preload': this.options_.preload,
|
'preload': this.options_.preload,
|
||||||
'loop': this.options_.loop,
|
'loop': this.options_.loop,
|
||||||
'muted': this.options_.muted,
|
'muted': this.options_.muted,
|
||||||
@ -2473,6 +2474,31 @@ class Player extends Component {
|
|||||||
return this.techGet_('autoplay', value);
|
return this.techGet_('autoplay', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or unset the playsinline attribute.
|
||||||
|
* Playsinline tells the browser that non-fullscreen playback is preferred.
|
||||||
|
*
|
||||||
|
* @param {boolean} [value]
|
||||||
|
* - true means that we should try to play inline by default
|
||||||
|
* - false means that we should use the browser's default playback mode,
|
||||||
|
* which in most cases is inline. iOS Safari is a notable exception
|
||||||
|
* and plays fullscreen by default.
|
||||||
|
*
|
||||||
|
* @return {string|Player}
|
||||||
|
* - the current value of playsinline
|
||||||
|
* - the player when setting
|
||||||
|
*
|
||||||
|
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
|
||||||
|
*/
|
||||||
|
playsinline(value) {
|
||||||
|
if (value !== undefined) {
|
||||||
|
this.techCall_('setPlaysinline', value);
|
||||||
|
this.options_.playsinline = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return this.techGet_('playsinline');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or set the loop attribute on the video element.
|
* Get or set the loop attribute on the video element.
|
||||||
*
|
*
|
||||||
|
@ -234,7 +234,7 @@ class Html5 extends Tech {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update specific tag settings, in case they were overridden
|
// Update specific tag settings, in case they were overridden
|
||||||
const settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
|
const settingsAttrs = ['autoplay', 'preload', 'loop', 'muted', 'playsinline'];
|
||||||
|
|
||||||
for (let i = settingsAttrs.length - 1; i >= 0; i--) {
|
for (let i = settingsAttrs.length - 1; i >= 0; i--) {
|
||||||
const attr = settingsAttrs[i];
|
const attr = settingsAttrs[i];
|
||||||
@ -668,6 +668,43 @@ class Html5 extends Tech {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of `playsinline` from the media element. `playsinline` indicates
|
||||||
|
* to the browser that non-fullscreen playback is preferred when fullscreen
|
||||||
|
* playback is the native default, such as in iOS Safari.
|
||||||
|
*
|
||||||
|
* @method Html5#playsinline
|
||||||
|
* @return {boolean}
|
||||||
|
* - The value of `playsinline` from the media element.
|
||||||
|
* - True indicates that the media should play inline.
|
||||||
|
* - False indicates that the media should not play inline.
|
||||||
|
*
|
||||||
|
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
|
||||||
|
*/
|
||||||
|
playsinline() {
|
||||||
|
return this.el_.hasAttribute('playsinline');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of `playsinline` from the media element. `playsinline` indicates
|
||||||
|
* to the browser that non-fullscreen playback is preferred when fullscreen
|
||||||
|
* playback is the native default, such as in iOS Safari.
|
||||||
|
*
|
||||||
|
* @method Html5#setPlaysinline
|
||||||
|
* @param {boolean} playsinline
|
||||||
|
* - True indicates that the media should play inline.
|
||||||
|
* - False indicates that the media should not play inline.
|
||||||
|
*
|
||||||
|
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
|
||||||
|
*/
|
||||||
|
setPlaysinline(value) {
|
||||||
|
if (value) {
|
||||||
|
this.el_.setAttribute('playsinline', 'playsinline');
|
||||||
|
} else {
|
||||||
|
this.el_.removeAttribute('playsinline');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets available media playback quality metrics as specified by the W3C's Media
|
* Gets available media playback quality metrics as specified by the W3C's Media
|
||||||
* Playback Quality API.
|
* Playback Quality API.
|
||||||
|
@ -743,6 +743,20 @@ class Tech extends Component {
|
|||||||
*/
|
*/
|
||||||
setPoster() {}
|
setPoster() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method to check for the presence of the 'playsinine' <video> attribute.
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
playsinline() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A method to set or unset the 'playsinine' <video> attribute.
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
setPlaysinline() {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the tech can support the given mime-type.
|
* Check if the tech can support the given mime-type.
|
||||||
*
|
*
|
||||||
|
@ -791,6 +791,35 @@ QUnit.test('should restore attributes from the original video tag when creating
|
|||||||
assert.equal(el.getAttribute('webkit-playsinline'), '', 'webkit-playsinline attribute was set properly');
|
assert.equal(el.getAttribute('webkit-playsinline'), '', 'webkit-playsinline attribute was set properly');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (Html5.isSupported()) {
|
||||||
|
QUnit.test('player.playsinline() should be able to get/set playsinline attribute', function(assert) {
|
||||||
|
assert.expect(5);
|
||||||
|
|
||||||
|
const video = document.createElement('video');
|
||||||
|
const player = TestHelpers.makePlayer({techOrder: ['html5']}, video);
|
||||||
|
|
||||||
|
// test setter
|
||||||
|
assert.ok(!player.tech_.el().hasAttribute('playsinline'), 'playsinline has not yet been added');
|
||||||
|
|
||||||
|
player.playsinline(true);
|
||||||
|
|
||||||
|
assert.ok(player.tech_.el().hasAttribute('playsinline'), 'playsinline attribute added');
|
||||||
|
|
||||||
|
player.playsinline(false);
|
||||||
|
|
||||||
|
assert.ok(!player.tech_.el().hasAttribute('playsinline'), 'playsinline attribute removed');
|
||||||
|
|
||||||
|
// test getter
|
||||||
|
player.tech_.el().setAttribute('playsinline', 'playsinline');
|
||||||
|
|
||||||
|
assert.ok(player.playsinline(), 'correctly detects playsinline attribute');
|
||||||
|
|
||||||
|
player.tech_.el().removeAttribute('playsinline');
|
||||||
|
|
||||||
|
assert.ok(!player.playsinline(), 'correctly detects absence of playsinline attribute');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QUnit.test('if tag exists and movingMediaElementInDOM, re-use the tag', function(assert) {
|
QUnit.test('if tag exists and movingMediaElementInDOM, re-use the tag', function(assert) {
|
||||||
// simulate attributes stored from the original tag
|
// simulate attributes stored from the original tag
|
||||||
const tag = Dom.createEl('video');
|
const tag = Dom.createEl('video');
|
||||||
|
@ -7,12 +7,13 @@ QUnit.test('should set options from data-setup even if autoSetup is not called b
|
|||||||
const el = TestHelpers.makeTag();
|
const el = TestHelpers.makeTag();
|
||||||
|
|
||||||
el.setAttribute('data-setup',
|
el.setAttribute('data-setup',
|
||||||
'{"controls": true, "autoplay": false, "preload": "auto"}');
|
'{"controls": true, "autoplay": false, "preload": "auto", "playsinline": true}');
|
||||||
|
|
||||||
const player = TestHelpers.makePlayer({}, el);
|
const player = TestHelpers.makePlayer({}, el);
|
||||||
|
|
||||||
assert.ok(player.options_.controls === true);
|
assert.ok(player.options_.controls === true);
|
||||||
assert.ok(player.options_.autoplay === false);
|
assert.ok(player.options_.autoplay === false);
|
||||||
assert.ok(player.options_.preload === 'auto');
|
assert.ok(player.options_.preload === 'auto');
|
||||||
|
assert.ok(player.options_.playsinline === true);
|
||||||
player.dispose();
|
player.dispose();
|
||||||
});
|
});
|
||||||
|
@ -50,6 +50,19 @@ QUnit.module('HTML5', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('should be able to set playsinline attribute', function(assert) {
|
||||||
|
assert.expect(2);
|
||||||
|
|
||||||
|
tech.createEl();
|
||||||
|
tech.setPlaysinline(true);
|
||||||
|
|
||||||
|
assert.ok(tech.el().hasAttribute('playsinline'), 'playsinline attribute was added');
|
||||||
|
|
||||||
|
tech.setPlaysinline(false);
|
||||||
|
|
||||||
|
assert.ok(!tech.el().hasAttribute('playsinline'), 'playsinline attribute was removed');
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('should detect whether the volume can be changed', function(assert) {
|
QUnit.test('should detect whether the volume can be changed', function(assert) {
|
||||||
|
|
||||||
if (!{}.__defineSetter__) {
|
if (!{}.__defineSetter__) {
|
||||||
|
Reference in New Issue
Block a user