mirror of
https://github.com/videojs/video.js.git
synced 2025-01-02 06:32:07 +02:00
Merge branch 'main' into type-updates
This commit is contained in:
commit
651dc44513
30
CHANGELOG.md
30
CHANGELOG.md
@ -1,3 +1,33 @@
|
||||
<a name="8.19.1"></a>
|
||||
## [8.19.1](https://github.com/videojs/video.js/compare/v8.19.0...v8.19.1) (2024-10-10)
|
||||
|
||||
### Chores
|
||||
|
||||
* **package:** update http-streaming to v3.15.0 ([#8889](https://github.com/videojs/video.js/issues/8889)) ([84f4905](https://github.com/videojs/video.js/commit/84f4905))
|
||||
* update mpd-parser to v1.3.1 ([#8888](https://github.com/videojs/video.js/issues/8888)) ([7c17d75](https://github.com/videojs/video.js/commit/7c17d75))
|
||||
|
||||
<a name="8.19.0"></a>
|
||||
# [8.19.0](https://github.com/videojs/video.js/compare/v8.18.0...v8.19.0) (2024-10-09)
|
||||
|
||||
### Features
|
||||
|
||||
* Add methods to add and remove <source> elements ([#8886](https://github.com/videojs/video.js/issues/8886)) ([eddda97](https://github.com/videojs/video.js/commit/eddda97)), closes [1000#0](https://github.com/1000/issues/0)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Don't request fullscreen from document PIP window ([#8881](https://github.com/videojs/video.js/issues/8881)) ([077077b](https://github.com/videojs/video.js/commit/077077b)), closes [#8877](https://github.com/videojs/video.js/issues/8877)
|
||||
|
||||
### Chores
|
||||
|
||||
* **package:** Update to VHS v3.14.2 ([#8869](https://github.com/videojs/video.js/issues/8869)) ([89eb454](https://github.com/videojs/video.js/commit/89eb454))
|
||||
|
||||
<a name="8.18.1"></a>
|
||||
## [8.18.1](https://github.com/videojs/video.js/compare/v8.18.0...v8.18.1) (2024-09-17)
|
||||
|
||||
### Chores
|
||||
|
||||
* **package:** Update to VHS v3.14.2 ([#8869](https://github.com/videojs/video.js/issues/8869)) ([89eb454](https://github.com/videojs/video.js/commit/89eb454))
|
||||
|
||||
<a name="8.18.0"></a>
|
||||
# [8.18.0](https://github.com/videojs/video.js/compare/v8.17.4...v8.18.0) (2024-09-10)
|
||||
|
||||
|
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>`:
|
||||
|
||||
```html
|
||||
<link href="//vjs.zencdn.net/8.18.0/video-js.min.css" rel="stylesheet">
|
||||
<script src="//vjs.zencdn.net/8.18.0/video.min.js"></script>
|
||||
<link href="//vjs.zencdn.net/8.19.1/video-js.min.css" rel="stylesheet">
|
||||
<script src="//vjs.zencdn.net/8.19.1/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.
|
||||
@ -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>
|
||||
|
||||
<!-- unpkg : use a specific version of Video.js (change the version numbers as necessary) -->
|
||||
<link href="https://unpkg.com/video.js@8.18.0/dist/video-js.min.css" rel="stylesheet">
|
||||
<script src="https://unpkg.com/video.js@8.18.0/dist/video.min.js"></script>
|
||||
<link href="https://unpkg.com/video.js@8.19.1/dist/video-js.min.css" rel="stylesheet">
|
||||
<script src="https://unpkg.com/video.js@8.19.1/dist/video.min.js"></script>
|
||||
|
||||
<!-- 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.18.0/video-js.min.css" rel="stylesheet">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.18.0/video.min.js"></script>
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.19.1/video-js.min.css" rel="stylesheet">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.19.1/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!
|
||||
|
109
package-lock.json
generated
109
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"version": "8.18.0",
|
||||
"version": "8.19.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -1791,16 +1791,16 @@
|
||||
}
|
||||
},
|
||||
"@videojs/http-streaming": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.14.1.tgz",
|
||||
"integrity": "sha512-VQ0msr+xTkA8BsDBMG9fqXMIvkPYXguVrOOPcrw+sk8y6xgrJjdfzie2h25uUMg/JUbEQqp1CbsK6IuIMqRFoA==",
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.15.0.tgz",
|
||||
"integrity": "sha512-6rjaqEa87gVFqDFsHaLKXGrDqL3NhNZRNi6wkMw+uyt1lrLD2OFY0SfRQRNl7Vmmx0pt5FRJoRJYlnKsowyElA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/vhs-utils": "^4.1.1",
|
||||
"aes-decrypter": "^4.0.2",
|
||||
"global": "^4.4.0",
|
||||
"m3u8-parser": "^7.2.0",
|
||||
"mpd-parser": "^1.3.0",
|
||||
"mpd-parser": "^1.3.1",
|
||||
"mux.js": "7.0.3",
|
||||
"video.js": "^7 || ^8"
|
||||
}
|
||||
@ -7282,11 +7282,6 @@
|
||||
"integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==",
|
||||
"dev": true
|
||||
},
|
||||
"individual": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz",
|
||||
"integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g=="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@ -9744,9 +9739,9 @@
|
||||
}
|
||||
},
|
||||
"mpd-parser": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.0.tgz",
|
||||
"integrity": "sha512-WgeIwxAqkmb9uTn4ClicXpEQYCEduDqRKfmUdp4X8vmghKfBNXZLYpREn9eqrDx/Tf5LhzRcJLSpi4ohfV742Q==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.1.tgz",
|
||||
"integrity": "sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/vhs-utils": "^4.0.0",
|
||||
@ -12486,14 +12481,6 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"rust-result": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz",
|
||||
"integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==",
|
||||
"requires": {
|
||||
"individual": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
@ -12529,14 +12516,6 @@
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"safe-json-parse": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
|
||||
"integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==",
|
||||
"requires": {
|
||||
"rust-result": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
@ -14846,11 +14825,6 @@
|
||||
"prepend-http": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"url-toolkit": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.5.tgz",
|
||||
"integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg=="
|
||||
},
|
||||
"urljoin": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/urljoin/-/urljoin-0.1.5.tgz",
|
||||
@ -15076,75 +15050,22 @@
|
||||
"dev": true
|
||||
},
|
||||
"video.js": {
|
||||
"version": "8.17.3",
|
||||
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.17.3.tgz",
|
||||
"integrity": "sha512-zhhmE0LNxJRA603/48oYzF7GYdT+rQRscvcsouYxFE71aKhalHLBP6S9/XjixnyjcrYgwIx8OQo6eSjcbbAW0Q==",
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.18.1.tgz",
|
||||
"integrity": "sha512-oQ4M/HD2fFgEPHfmVMWxGykRFIpOmVhK0XZ4PSsPTgN2jH6E6+92f/RI2mDXDb0yu+Fxv9fxMUm0M7Z2K3Zo9w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/http-streaming": "3.13.2",
|
||||
"@videojs/vhs-utils": "^4.0.0",
|
||||
"@videojs/http-streaming": "^3.14.2",
|
||||
"@videojs/vhs-utils": "^4.1.1",
|
||||
"@videojs/xhr": "2.7.0",
|
||||
"aes-decrypter": "^4.0.1",
|
||||
"aes-decrypter": "^4.0.2",
|
||||
"global": "4.4.0",
|
||||
"m3u8-parser": "^7.1.0",
|
||||
"m3u8-parser": "^7.2.0",
|
||||
"mpd-parser": "^1.2.2",
|
||||
"mux.js": "^7.0.1",
|
||||
"safe-json-parse": "4.0.0",
|
||||
"videojs-contrib-quality-levels": "4.1.0",
|
||||
"videojs-font": "4.2.0",
|
||||
"videojs-vtt.js": "0.15.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@videojs/http-streaming": {
|
||||
"version": "3.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.13.2.tgz",
|
||||
"integrity": "sha512-eCfQp61w00hg7Y9npmLnsJ6UvDF+SsFYzu7mQJgVXxWpVm9AthYWA3KQEKA7F7Sy6yzlm/Sps8BHs5ItelNZgQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/vhs-utils": "4.0.0",
|
||||
"aes-decrypter": "4.0.1",
|
||||
"global": "^4.4.0",
|
||||
"m3u8-parser": "^7.1.0",
|
||||
"mpd-parser": "^1.3.0",
|
||||
"mux.js": "7.0.3",
|
||||
"video.js": "^7 || ^8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@videojs/vhs-utils": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz",
|
||||
"integrity": "sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"global": "^4.4.0",
|
||||
"url-toolkit": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"aes-decrypter": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz",
|
||||
"integrity": "sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/vhs-utils": "^3.0.5",
|
||||
"global": "^4.4.0",
|
||||
"pkcs7": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@videojs/vhs-utils": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
|
||||
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"global": "^4.4.0",
|
||||
"url-toolkit": "^2.2.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"videojs-contrib-quality-levels": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 video player that supports HLS and DASH with a common API and skin.",
|
||||
"version": "8.18.0",
|
||||
"version": "8.19.1",
|
||||
"main": "./dist/video.cjs.js",
|
||||
"module": "./dist/video.es.js",
|
||||
"style": "./dist/video-js.css",
|
||||
@ -86,13 +86,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/http-streaming": "^3.14.1",
|
||||
"@videojs/http-streaming": "^3.15.0",
|
||||
"@videojs/vhs-utils": "^4.1.1",
|
||||
"@videojs/xhr": "2.7.0",
|
||||
"aes-decrypter": "^4.0.2",
|
||||
"global": "4.4.0",
|
||||
"m3u8-parser": "^7.2.0",
|
||||
"mpd-parser": "^1.2.2",
|
||||
"mpd-parser": "^1.3.1",
|
||||
"mux.js": "^7.0.1",
|
||||
"videojs-contrib-quality-levels": "4.1.0",
|
||||
"videojs-font": "4.2.0",
|
||||
|
@ -2003,7 +2003,8 @@ class Player extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a double-click on the media element to enter/exit fullscreen
|
||||
* Handle a double-click on the media element to enter/exit fullscreen,
|
||||
* or exit documentPictureInPicture mode
|
||||
*
|
||||
* @param {Event} event
|
||||
* the event that caused this function to trigger
|
||||
@ -2045,7 +2046,12 @@ class Player extends Component {
|
||||
) {
|
||||
|
||||
this.options_.userActions.doubleClick.call(this, event);
|
||||
|
||||
} else if (this.isInPictureInPicture() && !document.pictureInPictureElement) {
|
||||
// Checking the presence of `window.documentPictureInPicture.window` complicates
|
||||
// tests, checking `document.pictureInPictureElement` also works. It wouldn't
|
||||
// be null in regular picture in picture.
|
||||
// Exit picture in picture mode. This gesture can't trigger pip on the main window.
|
||||
this.exitPictureInPicture();
|
||||
} else if (this.isFullscreen()) {
|
||||
this.exitFullscreen();
|
||||
} else {
|
||||
@ -3704,6 +3710,43 @@ class Player extends Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <source> element to the <video> element.
|
||||
*
|
||||
* @param {string} srcUrl
|
||||
* The URL of the video source.
|
||||
*
|
||||
* @param {string} [mimeType]
|
||||
* The MIME type of the video source. Optional but recommended.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true if the source element was successfully added, false otherwise.
|
||||
*/
|
||||
addSourceElement(srcUrl, mimeType) {
|
||||
if (!this.tech_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.tech_.addSourceElement(srcUrl, mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a <source> element from the <video> element by its URL.
|
||||
*
|
||||
* @param {string} srcUrl
|
||||
* The URL of the source to remove.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true if the source element was successfully removed, false otherwise.
|
||||
*/
|
||||
removeSourceElement(srcUrl) {
|
||||
if (!this.tech_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.tech_.removeSourceElement(srcUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin loading the src data.
|
||||
*/
|
||||
|
@ -783,6 +783,67 @@ class Html5 extends Tech {
|
||||
this.setSrc(src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <source> element to the <video> element.
|
||||
*
|
||||
* @param {string} srcUrl
|
||||
* The URL of the video source.
|
||||
*
|
||||
* @param {string} [mimeType]
|
||||
* The MIME type of the video source. Optional but recommended.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true if the source element was successfully added, false otherwise.
|
||||
*/
|
||||
addSourceElement(srcUrl, mimeType) {
|
||||
if (!srcUrl) {
|
||||
log.error('Invalid source URL.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceAttributes = { src: srcUrl };
|
||||
|
||||
if (mimeType) {
|
||||
sourceAttributes.type = mimeType;
|
||||
}
|
||||
|
||||
const sourceElement = Dom.createEl('source', {}, sourceAttributes);
|
||||
|
||||
this.el_.appendChild(sourceElement);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a <source> element from the <video> element by its URL.
|
||||
*
|
||||
* @param {string} srcUrl
|
||||
* The URL of the source to remove.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns true if the source element was successfully removed, false otherwise.
|
||||
*/
|
||||
removeSourceElement(srcUrl) {
|
||||
if (!srcUrl) {
|
||||
log.error('Source URL is required to remove the source element.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceElements = this.el_.querySelectorAll('source');
|
||||
|
||||
for (const sourceElement of sourceElements) {
|
||||
if (sourceElement.src === srcUrl) {
|
||||
this.el_.removeChild(sourceElement);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
log.warn(`No matching source element found with src: ${srcUrl}`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the tech by removing all sources and then calling
|
||||
* {@link Html5.resetMediaElement}.
|
||||
|
@ -151,6 +151,19 @@ QUnit.test('by default, double-click opens fullscreen', function(assert) {
|
||||
assert.strictEqual(this.player.exitFullscreen.callCount, 1, 'has exited fullscreen');
|
||||
});
|
||||
|
||||
QUnit.test('in document picture in picture mode, double-click exits pip', function(assert) {
|
||||
this.player.isInPictureInPicture = () => true;
|
||||
this.player.exitPictureInPicture = sinon.spy();
|
||||
this.player.requestFullscreen = sinon.spy();
|
||||
this.player.exitFullscreen = sinon.spy();
|
||||
|
||||
this.player.handleTechDoubleClick_({target: this.player.tech_.el_});
|
||||
|
||||
assert.strictEqual(this.player.exitPictureInPicture.callCount, 1, 'has exited pip once');
|
||||
assert.strictEqual(this.player.requestFullscreen.callCount, 0, 'has not entered fullscreen');
|
||||
assert.strictEqual(this.player.exitFullscreen.callCount, 0, 'has not exited fullscreen');
|
||||
});
|
||||
|
||||
QUnit.test('when controls are disabled, double-click does nothing', function(assert) {
|
||||
let fullscreen = false;
|
||||
|
||||
|
@ -3611,3 +3611,57 @@ QUnit.test('smooth seeking set to true should update the display time components
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
QUnit.test('addSourceElement calls tech method with correct args', function(assert) {
|
||||
const player = TestHelpers.makePlayer();
|
||||
const addSourceElementSpy = sinon.spy(player.tech_, 'addSourceElement');
|
||||
const srcUrl = 'http://example.com/video.mp4';
|
||||
const mimeType = 'video/mp4';
|
||||
|
||||
player.addSourceElement(srcUrl, mimeType);
|
||||
|
||||
assert.ok(addSourceElementSpy.calledOnce, 'addSourceElement method called');
|
||||
assert.ok(addSourceElementSpy.calledWith(srcUrl, mimeType), 'addSourceElement called with correct arguments');
|
||||
|
||||
addSourceElementSpy.restore();
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
QUnit.test('addSourceElement returns false if no tech', function(assert) {
|
||||
const player = TestHelpers.makePlayer();
|
||||
const srcUrl = 'http://example.com/video.mp4';
|
||||
const mimeType = 'video/mp4';
|
||||
|
||||
player.tech_ = undefined;
|
||||
|
||||
const added = player.addSourceElement(srcUrl, mimeType);
|
||||
|
||||
assert.notOk(added, 'Returned false');
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
QUnit.test('removeSourceElement calls tech method with correct args', function(assert) {
|
||||
const player = TestHelpers.makePlayer();
|
||||
const removeSourceElementSpy = sinon.spy(player.tech_, 'removeSourceElement');
|
||||
const srcUrl = 'http://example.com/video.mp4';
|
||||
|
||||
player.removeSourceElement(srcUrl);
|
||||
|
||||
assert.ok(removeSourceElementSpy.calledOnce, 'removeSourceElement method called');
|
||||
assert.ok(removeSourceElementSpy.calledWith(srcUrl), 'removeSourceElement called with correct arguments');
|
||||
|
||||
removeSourceElementSpy.restore();
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
QUnit.test('removeSourceElement returns false if no tech', function(assert) {
|
||||
const player = TestHelpers.makePlayer();
|
||||
const srcUrl = 'http://example.com/video.mp4';
|
||||
const mimeType = 'video/mp4';
|
||||
|
||||
player.tech_ = undefined;
|
||||
|
||||
const removed = player.removeSourceElement(srcUrl, mimeType);
|
||||
|
||||
assert.notOk(removed, 'Returned false');
|
||||
player.dispose();
|
||||
});
|
||||
|
@ -905,3 +905,79 @@ QUnit.test('supportsFullScreen is always with `webkitEnterFullScreen`', function
|
||||
|
||||
tech.el_ = oldEl;
|
||||
});
|
||||
|
||||
QUnit.test('addSourceElement adds a valid source element with srcUrl and mimeType', function(assert) {
|
||||
const videoEl = document.createElement('video');
|
||||
|
||||
tech.el_ = videoEl;
|
||||
|
||||
const srcUrl = 'http://example.com/video.mp4';
|
||||
const mimeType = 'video/mp4';
|
||||
|
||||
const added = tech.addSourceElement(srcUrl, mimeType);
|
||||
const sourceElement = videoEl.querySelector('source');
|
||||
|
||||
assert.ok(added, 'Returned true');
|
||||
assert.ok(sourceElement, 'A source element was added');
|
||||
assert.equal(sourceElement.src, srcUrl, 'Source element has correct src');
|
||||
assert.equal(sourceElement.type, mimeType, 'Source element has correct type');
|
||||
});
|
||||
|
||||
QUnit.test('addSourceElement adds a valid source element without a mimeType', function(assert) {
|
||||
const videoEl = document.createElement('video');
|
||||
|
||||
tech.el_ = videoEl;
|
||||
|
||||
const srcUrl = 'http://example.com/video2.mp4';
|
||||
|
||||
const added = tech.addSourceElement(srcUrl);
|
||||
const sourceElement = videoEl.querySelector('source');
|
||||
|
||||
assert.ok(added, 'Returned true');
|
||||
assert.ok(sourceElement, 'A source element was added even without a type');
|
||||
assert.equal(sourceElement.src, srcUrl, 'Source element has correct src');
|
||||
assert.notOk(sourceElement.type, 'Source element does not have a type attribute');
|
||||
});
|
||||
|
||||
QUnit.test('addSourceElement does not add a source element for invalid source URL', function(assert) {
|
||||
const videoEl = document.createElement('video');
|
||||
|
||||
tech.el_ = videoEl;
|
||||
|
||||
const added = tech.addSourceElement('');
|
||||
const sourceElement = videoEl.querySelector('source');
|
||||
|
||||
assert.notOk(added, 'Returned false');
|
||||
assert.notOk(sourceElement, 'No source element was added for missing src');
|
||||
});
|
||||
|
||||
QUnit.test('removeSourceElement removes a source element by its URL', function(assert) {
|
||||
const videoEl = document.createElement('video');
|
||||
|
||||
tech.el_ = videoEl;
|
||||
|
||||
tech.addSourceElement('http://example.com/video1.mp4');
|
||||
tech.addSourceElement('http://example.com/video2.mp4');
|
||||
|
||||
let sourceElement = videoEl.querySelector('source[src="http://example.com/video1.mp4"]');
|
||||
|
||||
assert.ok(sourceElement, 'Source element for video1.mp4 was added');
|
||||
|
||||
const removed = tech.removeSourceElement('http://example.com/video1.mp4');
|
||||
|
||||
assert.ok(removed, 'Source element was successfully removed');
|
||||
sourceElement = videoEl.querySelector('source[src="http://example.com/video1.mp4"]');
|
||||
assert.notOk(sourceElement, 'Source element for video1.mp4 was removed');
|
||||
});
|
||||
|
||||
QUnit.test('removeSourceElement does not remove a source element if URL does not match', function(assert) {
|
||||
const videoEl = document.createElement('video');
|
||||
|
||||
tech.el_ = videoEl;
|
||||
|
||||
tech.addSourceElement('http://example.com/video.mp4');
|
||||
|
||||
const removed = tech.removeSourceElement('http://example.com/invalid.mp4');
|
||||
|
||||
assert.notOk(removed, 'No source element was removed for non-matching URL');
|
||||
});
|
||||
|
@ -111,6 +111,8 @@ class TechFaker extends Tech {
|
||||
}
|
||||
return 'movie.mp4';
|
||||
}
|
||||
addSourceElement() {}
|
||||
removeSourceElement() {}
|
||||
load() {
|
||||
}
|
||||
currentSrc() {
|
||||
|
Loading…
Reference in New Issue
Block a user