Bug 1623715 - [7.2] Extract media utility functions. r=geckoview-reviewers,owlish

Differential Revision: https://phabricator.services.mozilla.com/D86349
This commit is contained in:
Eugen Sawin 2020-08-17 20:37:47 +00:00
Родитель 1205a67885
Коммит 82db8a3949
3 изменённых файлов: 96 добавлений и 54 удалений

Просмотреть файл

@ -7,10 +7,15 @@
const { GeckoViewChildModule } = ChromeUtils.import(
"resource://gre/modules/GeckoViewChildModule.jsm"
);
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
MediaUtils: "resource://gre/modules/MediaUtils.jsm",
});
class GeckoViewMediaChild extends GeckoViewChildModule {
onInit() {
this._videoIndex = 0;
@ -49,6 +54,7 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
onEnable() {
debug`onEnable`;
addEventListener("UAWidgetSetupOrChange", this, false);
addEventListener("MozDOMFullscreen:Entered", this, false);
addEventListener("MozDOMFullscreen:Exited", this, false);
@ -135,15 +141,11 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
break;
case "MozDOMFullscreen:Entered":
const element = content && content.document.fullscreenElement;
if (this.isMedia(element)) {
this.handleFullscreenChange(element);
} else {
// document.fullscreenElement can be a div container instead of the HTMLMediaElement
// in some pages (e.g Vimeo).
const childrenMedias = element.getElementsByTagName("video");
if (childrenMedias && childrenMedias.length > 0) {
this.handleFullscreenChange(childrenMedias[0]);
}
// document.fullscreenElement can be a div container instead of the
// HTMLMediaElement in some pages (e.g Vimeo).
const mediaElement = MediaUtils.findVideoElement(element);
if (mediaElement) {
this.handleFullscreenChange(mediaElement);
}
break;
case "MozDOMFullscreen:Exited":
@ -172,7 +174,7 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
}
handleNewMedia(aElement) {
if (this.getState(aElement) || !this.isMedia(aElement)) {
if (this.getState(aElement) || !MediaUtils.isMediaElement(aElement)) {
return;
}
const state = {
@ -188,12 +190,10 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
notifyNewMedia(aElement) {
this.getState(aElement).notified = true;
const message = {
type: "GeckoView:MediaAdd",
id: this.getState(aElement).id,
};
const message = MediaUtils.getMetadata(aElement) ?? {};
message.type = "GeckoView:MediaAdd";
message.id = this.getState(aElement).id;
this.fillMetadata(aElement, message);
this.eventDispatcher.sendRequest(message);
}
@ -236,16 +236,6 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
}
}
isMedia(aElement) {
if (!aElement) {
return false;
}
const elementType = ChromeUtils.getClassName(aElement);
return (
elementType === "HTMLVideoElement" || elementType === "HTMLAudioElement"
);
}
isObserving(aElement) {
return (
aElement && this.getState(aElement) && this.getState(aElement).observing
@ -292,30 +282,6 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
return false;
}
fillMetadata(aElement, aOut) {
aOut.src = aElement.currentSrc || aElement.src;
aOut.width = aElement.videoWidth || 0;
aOut.height = aElement.videoHeight || 0;
aOut.duration = aElement.duration;
aOut.seekable = !!aElement.seekable;
if (aElement.audioTracks) {
aOut.audioTrackCount = aElement.audioTracks.length;
} else {
aOut.audioTrackCount =
aElement.mozHasAudio ||
aElement.webkitAudioDecodedByteCount ||
ChromeUtils.getClassName(aElement) === "HTMLAudioElement"
? 1
: 0;
}
if (aElement.videoTracks) {
aOut.videoTrackCount = aElement.videoTracks.length;
} else {
aOut.videoTrackCount =
ChromeUtils.getClassName(aElement) === "HTMLVideoElement" ? 1 : 0;
}
}
handleMediaEvent(aEvent) {
const element = aEvent.target;
if (!this.isObserving(element)) {
@ -388,11 +354,10 @@ class GeckoViewMediaChild extends GeckoViewChildModule {
}
notifyMetadataChange(aElement) {
const message = {
type: "GeckoView:MediaMetadataChanged",
id: this.getState(aElement).id,
};
this.fillMetadata(aElement, message);
const message = MediaUtils.getMetadata(aElement) ?? {};
message.type = "GeckoView:MediaMetadataChanged";
message.id = this.getState(aElement).id;
this.eventDispatcher.sendRequest(message);
}

Просмотреть файл

@ -0,0 +1,76 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EXPORTED_SYMBOLS = ["MediaUtils"];
const MediaUtils = {
getMetadata(aElement) {
if (!aElement) {
return null;
}
return {
src: aElement.currentSrc ?? aElement.src,
width: aElement.videoWidth ?? 0,
height: aElement.videoHeight ?? 0,
duration: aElement.duration,
seekable: !!aElement.seekable,
audioTrackCount:
aElement.audioTracks?.length ??
aElement.mozHasAudio ??
aElement.webkitAudioDecodedByteCount ??
MediaUtils.isAudioElement(aElement)
? 1
: 0,
videoTrackCount:
aElement.videoTracks?.length ?? MediaUtils.isVideoElement(aElement)
? 1
: 0,
};
},
isVideoElement(aElement) {
return (
aElement && ChromeUtils.getClassName(aElement) === "HTMLVideoElement"
);
},
isAudioElement(aElement) {
return (
aElement && ChromeUtils.getClassName(aElement) === "HTMLAudioElement"
);
},
isMediaElement(aElement) {
return (
MediaUtils.isVideoElement(aElement) || MediaUtils.isAudioElement(aElement)
);
},
findVideoElement(aElement) {
if (!aElement) {
return null;
}
if (MediaUtils.isVideoElement(aElement)) {
return aElement;
}
const childrenMedia = aElement.getElementsByTagName("video");
if (childrenMedia && childrenMedia.length > 0) {
return childrenMedia[0];
}
return null;
},
findAudioElement(aElement) {
if (!aElement || MediaUtils.isAudioElement(aElement)) {
return aElement;
}
const childrenMedia = aElement.getElementsByTagName("audio");
if (childrenMedia && childrenMedia.length > 0) {
return childrenMedia[0];
}
return null;
},
};

Просмотреть файл

@ -33,5 +33,6 @@ EXTRA_JS_MODULES += [
'GeckoViewUtils.jsm',
'GeckoViewWebExtension.jsm',
'LoadURIDelegate.jsm',
'MediaUtils.jsm',
'Messaging.jsm',
]