mirror of
https://github.com/videojs/video.js.git
synced 2024-12-21 01:39:04 +02:00
Merge branch 'main' into main
This commit is contained in:
commit
0c70fce1d7
@ -1,3 +1,11 @@
|
|||||||
|
<a name="8.20.0"></a>
|
||||||
|
# [8.20.0](https://github.com/videojs/video.js/compare/v8.19.2...v8.20.0) (2024-11-19)
|
||||||
|
|
||||||
|
### Chores
|
||||||
|
|
||||||
|
* Correct changelog for 8.19.2 ([#8918](https://github.com/videojs/video.js/issues/8918)) ([964c40e](https://github.com/videojs/video.js/commit/964c40e))
|
||||||
|
* **package:** Update [@videojs](https://github.com/videojs)/http-streaming to 3.16.0 ([#8921](https://github.com/videojs/video.js/issues/8921)) ([7420467](https://github.com/videojs/video.js/commit/7420467)), closes [1000#0](https://github.com/1000/issues/0)
|
||||||
|
|
||||||
<a name="8.19.2"></a>
|
<a name="8.19.2"></a>
|
||||||
## [8.19.2](https://github.com/videojs/video.js/compare/v8.19.1...v8.19.2) (2024-11-14)
|
## [8.19.2](https://github.com/videojs/video.js/compare/v8.19.1...v8.19.2) (2024-11-14)
|
||||||
|
|
||||||
|
12
README.md
12
README.md
@ -22,8 +22,8 @@ Video.js was started in the middle of 2010 and is now used on over ~~50,000~~ ~~
|
|||||||
Thanks to the awesome folks over at [Fastly][fastly], there's a free, CDN hosted version of Video.js that anyone can use. Add these tags to your document's `<head>`:
|
Thanks to the awesome folks over at [Fastly][fastly], there's a free, CDN hosted version of Video.js that anyone can use. Add these tags to your document's `<head>`:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link href="//vjs.zencdn.net/8.19.2/video-js.min.css" rel="stylesheet">
|
<link href="//vjs.zencdn.net/8.20.0/video-js.min.css" rel="stylesheet">
|
||||||
<script src="//vjs.zencdn.net/8.19.2/video.min.js"></script>
|
<script src="//vjs.zencdn.net/8.20.0/video.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can include Video.js by getting it from [npm](https://videojs.com/getting-started/#install-via-npm), downloading it from [GitHub releases](https://github.com/videojs/video.js/releases) or by including it via [unpkg](https://unpkg.com) or another JavaScript CDN, like CDNjs.
|
Alternatively, you can include Video.js by getting it from [npm](https://videojs.com/getting-started/#install-via-npm), downloading it from [GitHub releases](https://github.com/videojs/video.js/releases) or by including it via [unpkg](https://unpkg.com) or another JavaScript CDN, like CDNjs.
|
||||||
@ -34,12 +34,12 @@ Alternatively, you can include Video.js by getting it from [npm](https://videojs
|
|||||||
<script src="https://unpkg.com/video.js/dist/video.min.js"></script>
|
<script src="https://unpkg.com/video.js/dist/video.min.js"></script>
|
||||||
|
|
||||||
<!-- unpkg : use a specific version of Video.js (change the version numbers as necessary) -->
|
<!-- unpkg : use a specific version of Video.js (change the version numbers as necessary) -->
|
||||||
<link href="https://unpkg.com/video.js@8.19.2/dist/video-js.min.css" rel="stylesheet">
|
<link href="https://unpkg.com/video.js@8.20.0/dist/video-js.min.css" rel="stylesheet">
|
||||||
<script src="https://unpkg.com/video.js@8.19.2/dist/video.min.js"></script>
|
<script src="https://unpkg.com/video.js@8.20.0/dist/video.min.js"></script>
|
||||||
|
|
||||||
<!-- cdnjs : use a specific version of Video.js (change the version numbers as necessary) -->
|
<!-- cdnjs : use a specific version of Video.js (change the version numbers as necessary) -->
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.19.2/video-js.min.css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.20.0/video-js.min.css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.19.2/video.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.20.0/video.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, using Video.js is as simple as creating a `<video>` element, but with an additional `data-setup` attribute. At a minimum, this attribute must have a value of `'{}'`, but it can include any Video.js [options][options] - just make sure it contains valid JSON!
|
Next, using Video.js is as simple as creating a `<video>` element, but with an additional `data-setup` attribute. At a minimum, this attribute must have a value of `'{}'`, but it can include any Video.js [options][options] - just make sure it contains valid JSON!
|
||||||
|
31
package-lock.json
generated
31
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "video.js",
|
"name": "video.js",
|
||||||
"version": "8.19.2",
|
"version": "8.20.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -1791,9 +1791,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@videojs/http-streaming": {
|
"@videojs/http-streaming": {
|
||||||
"version": "3.15.0",
|
"version": "3.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.16.0.tgz",
|
||||||
"integrity": "sha512-6rjaqEa87gVFqDFsHaLKXGrDqL3NhNZRNi6wkMw+uyt1lrLD2OFY0SfRQRNl7Vmmx0pt5FRJoRJYlnKsowyElA==",
|
"integrity": "sha512-VL8l+JGbc9KqZ1fY2pYgBS1u3i6iQ/5mRAE6bwrI5R0RAtKxur1hjipVGwkkJSYRzwLgArt5Wg5abEjfoJN7yA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@videojs/vhs-utils": "^4.1.1",
|
"@videojs/vhs-utils": "^4.1.1",
|
||||||
@ -1801,8 +1801,19 @@
|
|||||||
"global": "^4.4.0",
|
"global": "^4.4.0",
|
||||||
"m3u8-parser": "^7.2.0",
|
"m3u8-parser": "^7.2.0",
|
||||||
"mpd-parser": "^1.3.1",
|
"mpd-parser": "^1.3.1",
|
||||||
"mux.js": "7.0.3",
|
"mux.js": "7.1.0",
|
||||||
"video.js": "^7 || ^8"
|
"video.js": "^7 || ^8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"mux.js": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.11.2",
|
||||||
|
"global": "^4.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@videojs/vhs-utils": {
|
"@videojs/vhs-utils": {
|
||||||
@ -15050,18 +15061,18 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"video.js": {
|
"video.js": {
|
||||||
"version": "8.18.1",
|
"version": "8.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.19.1.tgz",
|
||||||
"integrity": "sha512-oQ4M/HD2fFgEPHfmVMWxGykRFIpOmVhK0XZ4PSsPTgN2jH6E6+92f/RI2mDXDb0yu+Fxv9fxMUm0M7Z2K3Zo9w==",
|
"integrity": "sha512-MVuayhXpzTBv5Jk3nYEU2akawPhuBBlizEbpQGx2i+6FiBmqxGjkrkLdDLOzG54ut7xapjp26IfWQLGSpeLmcQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@videojs/http-streaming": "^3.14.2",
|
"@videojs/http-streaming": "^3.15.0",
|
||||||
"@videojs/vhs-utils": "^4.1.1",
|
"@videojs/vhs-utils": "^4.1.1",
|
||||||
"@videojs/xhr": "2.7.0",
|
"@videojs/xhr": "2.7.0",
|
||||||
"aes-decrypter": "^4.0.2",
|
"aes-decrypter": "^4.0.2",
|
||||||
"global": "4.4.0",
|
"global": "4.4.0",
|
||||||
"m3u8-parser": "^7.2.0",
|
"m3u8-parser": "^7.2.0",
|
||||||
"mpd-parser": "^1.2.2",
|
"mpd-parser": "^1.3.1",
|
||||||
"mux.js": "^7.0.1",
|
"mux.js": "^7.0.1",
|
||||||
"videojs-contrib-quality-levels": "4.1.0",
|
"videojs-contrib-quality-levels": "4.1.0",
|
||||||
"videojs-font": "4.2.0",
|
"videojs-font": "4.2.0",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "video.js",
|
"name": "video.js",
|
||||||
"description": "An HTML5 video player that supports HLS and DASH with a common API and skin.",
|
"description": "An HTML5 video player that supports HLS and DASH with a common API and skin.",
|
||||||
"version": "8.19.2",
|
"version": "8.20.0",
|
||||||
"main": "./dist/video.cjs.js",
|
"main": "./dist/video.cjs.js",
|
||||||
"module": "./dist/video.es.js",
|
"module": "./dist/video.es.js",
|
||||||
"style": "./dist/video-js.css",
|
"style": "./dist/video-js.css",
|
||||||
@ -86,7 +86,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@videojs/http-streaming": "^3.15.0",
|
"@videojs/http-streaming": "^3.16.0",
|
||||||
"@videojs/vhs-utils": "^4.1.1",
|
"@videojs/vhs-utils": "^4.1.1",
|
||||||
"@videojs/xhr": "2.7.0",
|
"@videojs/xhr": "2.7.0",
|
||||||
"aes-decrypter": "^4.0.2",
|
"aes-decrypter": "^4.0.2",
|
||||||
|
@ -41,7 +41,8 @@
|
|||||||
|
|
||||||
// This increases the size of the progress holder so there is an increased
|
// This increases the size of the progress holder so there is an increased
|
||||||
// hit area for clicks/touches.
|
// hit area for clicks/touches.
|
||||||
.video-js .vjs-progress-control:hover .vjs-progress-holder {
|
.video-js .vjs-progress-control:hover .vjs-progress-holder,
|
||||||
|
.video-js.vjs-scrubbing.vjs-touch-enabled .vjs-progress-control .vjs-progress-holder {
|
||||||
font-size: 1.666666666666666666em;
|
font-size: 1.666666666666666666em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +144,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.video-js .vjs-progress-control:hover .vjs-time-tooltip,
|
.video-js .vjs-progress-control:hover .vjs-time-tooltip,
|
||||||
.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip {
|
.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,
|
||||||
|
.video-js.vjs-scrubbing.vjs-touch-enabled .vjs-progress-control .vjs-time-tooltip {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
// Ensure that we maintain a font-size of ~10px.
|
// Ensure that we maintain a font-size of ~10px.
|
||||||
@ -172,6 +174,10 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video-js.vjs-scrubbing.vjs-touch-enabled .vjs-progress-control .vjs-mouse-display {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display {
|
.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -141,7 +141,7 @@ class ProgressControl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.off(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
|
this.off(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
|
||||||
this.off(this.el_, 'mousemove', this.handleMouseMove);
|
this.off(this.el_, ['mousemove', 'touchmove'], this.handleMouseMove);
|
||||||
|
|
||||||
this.removeListenersAddedOnMousedownAndTouchstart();
|
this.removeListenersAddedOnMousedownAndTouchstart();
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ class ProgressControl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.on(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
|
this.on(['mousedown', 'touchstart'], this.handleMouseDownHandler_);
|
||||||
this.on(this.el_, 'mousemove', this.handleMouseMove);
|
this.on(this.el_, ['mousemove', 'touchmove'], this.handleMouseMove);
|
||||||
this.removeClass('disabled');
|
this.removeClass('disabled');
|
||||||
|
|
||||||
this.enabled_ = true;
|
this.enabled_ = true;
|
||||||
|
@ -8,6 +8,7 @@ import * as Dom from '../../utils/dom.js';
|
|||||||
import * as Fn from '../../utils/fn.js';
|
import * as Fn from '../../utils/fn.js';
|
||||||
import {formatTime} from '../../utils/time.js';
|
import {formatTime} from '../../utils/time.js';
|
||||||
import {silencePromise} from '../../utils/promise';
|
import {silencePromise} from '../../utils/promise';
|
||||||
|
import {merge} from '../../utils/obj';
|
||||||
import document from 'global/document';
|
import document from 'global/document';
|
||||||
|
|
||||||
/** @import Player from '../../player' */
|
/** @import Player from '../../player' */
|
||||||
@ -40,7 +41,23 @@ class SeekBar extends Slider {
|
|||||||
* The key/value store of player options.
|
* The key/value store of player options.
|
||||||
*/
|
*/
|
||||||
constructor(player, options) {
|
constructor(player, options) {
|
||||||
|
options = merge(SeekBar.prototype.options_, options);
|
||||||
|
|
||||||
|
// Avoid mutating the prototype's `children` array by creating a copy
|
||||||
|
options.children = [...options.children];
|
||||||
|
|
||||||
|
const shouldDisableSeekWhileScrubbingOnMobile = player.options_.disableSeekWhileScrubbingOnMobile && (IS_IOS || IS_ANDROID);
|
||||||
|
|
||||||
|
// Add the TimeTooltip as a child if we are on desktop, or on mobile with `disableSeekWhileScrubbingOnMobile: true`
|
||||||
|
if ((!IS_IOS && !IS_ANDROID) || shouldDisableSeekWhileScrubbingOnMobile) {
|
||||||
|
options.children.splice(1, 0, 'mouseTimeDisplay');
|
||||||
|
}
|
||||||
|
|
||||||
super(player, options);
|
super(player, options);
|
||||||
|
|
||||||
|
this.shouldDisableSeekWhileScrubbingOnMobile_ = shouldDisableSeekWhileScrubbingOnMobile;
|
||||||
|
this.pendingSeekTime_ = null;
|
||||||
|
|
||||||
this.setEventHandlers_();
|
this.setEventHandlers_();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +242,12 @@ class SeekBar extends Slider {
|
|||||||
* The percentage of media played so far (0 to 1).
|
* The percentage of media played so far (0 to 1).
|
||||||
*/
|
*/
|
||||||
getPercent() {
|
getPercent() {
|
||||||
|
// If we have a pending seek time, we are scrubbing on mobile and should set the slider percent
|
||||||
|
// to reflect the current scrub location.
|
||||||
|
if (this.pendingSeekTime_) {
|
||||||
|
return this.pendingSeekTime_ / this.player_.duration();
|
||||||
|
}
|
||||||
|
|
||||||
const currentTime = this.getCurrentTime_();
|
const currentTime = this.getCurrentTime_();
|
||||||
let percent;
|
let percent;
|
||||||
const liveTracker = this.player_.liveTracker;
|
const liveTracker = this.player_.liveTracker;
|
||||||
@ -260,7 +283,12 @@ class SeekBar extends Slider {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.videoWasPlaying = !this.player_.paused();
|
this.videoWasPlaying = !this.player_.paused();
|
||||||
|
|
||||||
|
// Don't pause if we are on mobile and `disableSeekWhileScrubbingOnMobile: true`.
|
||||||
|
// In that case, playback should continue while the player scrubs to a new location.
|
||||||
|
if (!this.shouldDisableSeekWhileScrubbingOnMobile_) {
|
||||||
this.player_.pause();
|
this.player_.pause();
|
||||||
|
}
|
||||||
|
|
||||||
super.handleMouseDown(event);
|
super.handleMouseDown(event);
|
||||||
}
|
}
|
||||||
@ -324,8 +352,12 @@ class SeekBar extends Slider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new time (tell player to seek to new time)
|
// if on mobile and `disableSeekWhileScrubbingOnMobile: true`, keep track of the desired seek point but we won't initiate the seek until 'touchend'
|
||||||
|
if (this.shouldDisableSeekWhileScrubbingOnMobile_) {
|
||||||
|
this.pendingSeekTime_ = newTime;
|
||||||
|
} else {
|
||||||
this.userSeek_(newTime);
|
this.userSeek_(newTime);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.player_.options_.enableSmoothSeeking) {
|
if (this.player_.options_.enableSmoothSeeking) {
|
||||||
this.update();
|
this.update();
|
||||||
@ -371,6 +403,13 @@ class SeekBar extends Slider {
|
|||||||
}
|
}
|
||||||
this.player_.scrubbing(false);
|
this.player_.scrubbing(false);
|
||||||
|
|
||||||
|
// If we have a pending seek time, then we have finished scrubbing on mobile and should initiate a seek.
|
||||||
|
if (this.pendingSeekTime_) {
|
||||||
|
this.userSeek_(this.pendingSeekTime_);
|
||||||
|
|
||||||
|
this.pendingSeekTime_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger timeupdate because we're done seeking and the time has changed.
|
* Trigger timeupdate because we're done seeking and the time has changed.
|
||||||
* This is particularly useful for if the player is paused to time the time displays.
|
* This is particularly useful for if the player is paused to time the time displays.
|
||||||
@ -513,10 +552,5 @@ SeekBar.prototype.options_ = {
|
|||||||
barName: 'playProgressBar'
|
barName: 'playProgressBar'
|
||||||
};
|
};
|
||||||
|
|
||||||
// MouseTimeDisplay tooltips should not be added to a player on mobile devices
|
|
||||||
if (!IS_IOS && !IS_ANDROID) {
|
|
||||||
SeekBar.prototype.options_.children.splice(1, 0, 'mouseTimeDisplay');
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.registerComponent('SeekBar', SeekBar);
|
Component.registerComponent('SeekBar', SeekBar);
|
||||||
export default SeekBar;
|
export default SeekBar;
|
||||||
|
@ -5567,7 +5567,8 @@ Player.prototype.options_ = {
|
|||||||
horizontalSeek: false
|
horizontalSeek: false
|
||||||
},
|
},
|
||||||
// Default smooth seeking to false
|
// Default smooth seeking to false
|
||||||
enableSmoothSeeking: false
|
enableSmoothSeeking: false,
|
||||||
|
disableSeekWhileScrubbingOnMobile: false
|
||||||
};
|
};
|
||||||
|
|
||||||
TECH_EVENTS_RETRIGGER.forEach(function(event) {
|
TECH_EVENTS_RETRIGGER.forEach(function(event) {
|
||||||
|
@ -223,6 +223,20 @@ QUnit.test('SeekBar should be filled on 100% when the video/audio ends', functio
|
|||||||
window.cancelAnimationFrame = oldCAF;
|
window.cancelAnimationFrame = oldCAF;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('Seek bar percent should represent scrub location if we are scrubbing on mobile and have a pending seek time', function(assert) {
|
||||||
|
const player = TestHelpers.makePlayer();
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
|
||||||
|
player.duration(100);
|
||||||
|
seekBar.pendingSeekTime_ = 20;
|
||||||
|
|
||||||
|
assert.equal(seekBar.getPercent(), 0.2, 'seek bar percent set correctly to pending seek time');
|
||||||
|
|
||||||
|
seekBar.pendingSeekTime_ = 50;
|
||||||
|
|
||||||
|
assert.equal(seekBar.getPercent(), 0.5, 'seek bar percent set correctly to next pending seek time');
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('playback rate button is hidden by default', function(assert) {
|
QUnit.test('playback rate button is hidden by default', function(assert) {
|
||||||
assert.expect(1);
|
assert.expect(1);
|
||||||
|
|
||||||
|
@ -3611,6 +3611,154 @@ QUnit.test('smooth seeking set to true should update the display time components
|
|||||||
player.dispose();
|
player.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('mouseTimeDisplay should be added as child when disableSeekWhileScrubbingOnMobile is true on mobile', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: true });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay');
|
||||||
|
|
||||||
|
assert.ok(mouseTimeDisplay, 'mouseTimeDisplay added as a child');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('mouseTimeDisplay should not be added as child on mobile when disableSeekWhileScrubbingOnMobile is false', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: false });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay');
|
||||||
|
|
||||||
|
assert.notOk(mouseTimeDisplay, 'mouseTimeDisplay not added as a child');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Seeking should occur while scrubbing on mobile when disableSeekWhileScrubbingOnMobile is false', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: false });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const userSeekSpy = sinon.spy(seekBar, 'userSeek_');
|
||||||
|
|
||||||
|
// Simulate a source loaded
|
||||||
|
player.duration(10);
|
||||||
|
|
||||||
|
// Simulate scrub
|
||||||
|
seekBar.handleMouseMove({ pageX: 200 });
|
||||||
|
|
||||||
|
assert.ok(userSeekSpy.calledOnce, 'Seek initiated while scrubbing');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Seeking should not occur while scrubbing on mobile when disableSeekWhileScrubbingOnMobile is true', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: true });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const userSeekSpy = sinon.spy(seekBar, 'userSeek_');
|
||||||
|
|
||||||
|
// Simulate a source loaded
|
||||||
|
player.duration(10);
|
||||||
|
|
||||||
|
// Simulate scrub
|
||||||
|
seekBar.handleMouseMove({ pageX: 200 });
|
||||||
|
|
||||||
|
assert.ok(userSeekSpy.notCalled, 'Seek not initiated while scrubbing');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Seek should occur when scrubbing completes on mobile when disableSeekWhileScrubbingOnMobile is true', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: true });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const userSeekSpy = sinon.spy(seekBar, 'userSeek_');
|
||||||
|
const targetSeekTime = 5;
|
||||||
|
|
||||||
|
// Simulate a source loaded
|
||||||
|
player.duration(10);
|
||||||
|
|
||||||
|
seekBar.pendingSeekTime_ = targetSeekTime;
|
||||||
|
|
||||||
|
// Simulate scrubbing completion
|
||||||
|
seekBar.handleMouseUp();
|
||||||
|
|
||||||
|
assert.ok(userSeekSpy.calledWith(targetSeekTime), 'Seeks to correct location when scrubbing completes');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Player should pause while scrubbing on mobile when disableSeekWhileScrubbingOnMobile is false', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: false });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const pauseSpy = sinon.spy(player, 'pause');
|
||||||
|
|
||||||
|
// Simulate start playing
|
||||||
|
player.play();
|
||||||
|
|
||||||
|
const mockMouseDownEvent = {
|
||||||
|
pageX: 200,
|
||||||
|
stopPropagation: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Simulate scrubbing start
|
||||||
|
seekBar.handleMouseDown(mockMouseDownEvent);
|
||||||
|
|
||||||
|
assert.ok(pauseSpy.calledOnce, 'Player paused');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('Player should not pause while scrubbing on mobile when disableSeekWhileScrubbingOnMobile is true', function(assert) {
|
||||||
|
const originalIsIos = browser.IS_IOS;
|
||||||
|
|
||||||
|
browser.stub_IS_IOS(true);
|
||||||
|
|
||||||
|
const player = TestHelpers.makePlayer({ disableSeekWhileScrubbingOnMobile: true });
|
||||||
|
const seekBar = player.controlBar.progressControl.seekBar;
|
||||||
|
const pauseSpy = sinon.spy(player, 'pause');
|
||||||
|
|
||||||
|
// Simulate start playing
|
||||||
|
player.play();
|
||||||
|
|
||||||
|
const mockMouseDownEvent = {
|
||||||
|
pageX: 200,
|
||||||
|
stopPropagation: () => { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Simulate scrubbing start
|
||||||
|
seekBar.handleMouseDown(mockMouseDownEvent);
|
||||||
|
|
||||||
|
assert.ok(pauseSpy.notCalled, 'Player not paused');
|
||||||
|
|
||||||
|
player.dispose();
|
||||||
|
browser.stub_IS_IOS(originalIsIos);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('addSourceElement calls tech method with correct args', function(assert) {
|
QUnit.test('addSourceElement calls tech method with correct args', function(assert) {
|
||||||
const player = TestHelpers.makePlayer();
|
const player = TestHelpers.makePlayer();
|
||||||
const addSourceElementSpy = sinon.spy(player.tech_, 'addSourceElement');
|
const addSourceElementSpy = sinon.spy(player.tech_, 'addSourceElement');
|
||||||
|
Loading…
Reference in New Issue
Block a user