matrix-react-sdk
Version:
SDK for matrix.org using React
104 lines (100 loc) • 17.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _callFeed = require("matrix-js-sdk/src/webrtc/callFeed");
var _logger = require("matrix-js-sdk/src/logger");
var _MediaDeviceHandler = _interopRequireWildcard(require("../../../MediaDeviceHandler"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright 2024 New Vector Ltd.
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
class AudioFeed extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "element", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "onAudioOutputChanged", audioOutput => {
const element = this.element.current;
if (audioOutput) {
try {
// This seems quite unreliable in Chrome, although I haven't yet managed to make a jsfiddle where
// it fails.
// It seems reliable if you set the sink ID after setting the srcObject and then set the sink ID
// back to the default after the call is over - Dave
element.setSinkId(audioOutput);
} catch (e) {
_logger.logger.error("Couldn't set requested audio output device: using default", e);
_logger.logger.warn("Couldn't set requested audio output device: using default", e);
}
}
});
(0, _defineProperty2.default)(this, "onNewStream", () => {
this.setState({
audioMuted: this.props.feed.isAudioMuted()
});
this.playMedia();
});
this.state = {
audioMuted: this.props.feed.isAudioMuted()
};
}
componentDidMount() {
_MediaDeviceHandler.default.instance.addListener(_MediaDeviceHandler.MediaDeviceHandlerEvent.AudioOutputChanged, this.onAudioOutputChanged);
this.props.feed.addListener(_callFeed.CallFeedEvent.NewStream, this.onNewStream);
this.playMedia();
}
componentWillUnmount() {
_MediaDeviceHandler.default.instance.removeListener(_MediaDeviceHandler.MediaDeviceHandlerEvent.AudioOutputChanged, this.onAudioOutputChanged);
this.props.feed.removeListener(_callFeed.CallFeedEvent.NewStream, this.onNewStream);
this.stopMedia();
}
async playMedia() {
const element = this.element.current;
if (!element) return;
this.onAudioOutputChanged(_MediaDeviceHandler.default.getAudioOutput());
element.muted = false;
element.srcObject = this.props.feed.stream;
element.autoplay = true;
try {
// A note on calling methods on media elements:
// We used to have queues per media element to serialise all calls on those elements.
// The reason given for this was that load() and play() were racing. However, we now
// never call load() explicitly so this seems unnecessary. However, serialising every
// operation was causing bugs where video would not resume because some play command
// had got stuck and all media operations were queued up behind it. If necessary, we
// should serialise the ones that need to be serialised but then be able to interrupt
// them with another load() which will cancel the pending one, but since we don't call
// load() explicitly, it shouldn't be a problem. - Dave
await element.load();
} catch (e) {
_logger.logger.info(`Failed to play media element with feed for userId ` + `${this.props.feed.userId} with purpose ${this.props.feed.purpose}`, e);
}
}
stopMedia() {
const element = this.element.current;
if (!element) return;
element.pause();
element.removeAttribute("src");
// As per comment in componentDidMount, setting the sink ID back to the
// default once the call is over makes setSinkId work reliably. - Dave
// Since we are not using the same element anymore, the above doesn't
// seem to be necessary - Šimon
}
render() {
// Do not render the audio element if there is no audio track
if (this.state.audioMuted) return null;
return /*#__PURE__*/_react.default.createElement("audio", {
ref: this.element
});
}
}
exports.default = AudioFeed;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2FsbEZlZWQiLCJfbG9nZ2VyIiwiX01lZGlhRGV2aWNlSGFuZGxlciIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIkF1ZGlvRmVlZCIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJjcmVhdGVSZWYiLCJhdWRpb091dHB1dCIsImVsZW1lbnQiLCJjdXJyZW50Iiwic2V0U2lua0lkIiwibG9nZ2VyIiwiZXJyb3IiLCJ3YXJuIiwic2V0U3RhdGUiLCJhdWRpb011dGVkIiwiZmVlZCIsImlzQXVkaW9NdXRlZCIsInBsYXlNZWRpYSIsInN0YXRlIiwiY29tcG9uZW50RGlkTW91bnQiLCJNZWRpYURldmljZUhhbmRsZXIiLCJpbnN0YW5jZSIsImFkZExpc3RlbmVyIiwiTWVkaWFEZXZpY2VIYW5kbGVyRXZlbnQiLCJBdWRpb091dHB1dENoYW5nZWQiLCJvbkF1ZGlvT3V0cHV0Q2hhbmdlZCIsIkNhbGxGZWVkRXZlbnQiLCJOZXdTdHJlYW0iLCJvbk5ld1N0cmVhbSIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwicmVtb3ZlTGlzdGVuZXIiLCJzdG9wTWVkaWEiLCJnZXRBdWRpb091dHB1dCIsIm11dGVkIiwic3JjT2JqZWN0Iiwic3RyZWFtIiwiYXV0b3BsYXkiLCJsb2FkIiwiaW5mbyIsInVzZXJJZCIsInB1cnBvc2UiLCJwYXVzZSIsInJlbW92ZUF0dHJpYnV0ZSIsInJlbmRlciIsImNyZWF0ZUVsZW1lbnQiLCJyZWYiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3Mvdm9pcC9BdWRpb0ZlZWQudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIxIMWgaW1vbiBCcmFuZG5lciA8c2ltb24uYnJhLmFnQGdtYWlsLmNvbT5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZVJlZiB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgQ2FsbEZlZWQsIENhbGxGZWVkRXZlbnQgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvd2VicnRjL2NhbGxGZWVkXCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5cbmltcG9ydCBNZWRpYURldmljZUhhbmRsZXIsIHsgTWVkaWFEZXZpY2VIYW5kbGVyRXZlbnQgfSBmcm9tIFwiLi4vLi4vLi4vTWVkaWFEZXZpY2VIYW5kbGVyXCI7XG5cbmludGVyZmFjZSBJUHJvcHMge1xuICAgIGZlZWQ6IENhbGxGZWVkO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBhdWRpb011dGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBdWRpb0ZlZWQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwcml2YXRlIGVsZW1lbnQgPSBjcmVhdGVSZWY8SFRNTEF1ZGlvRWxlbWVudD4oKTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogSVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgYXVkaW9NdXRlZDogdGhpcy5wcm9wcy5mZWVkLmlzQXVkaW9NdXRlZCgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnREaWRNb3VudCgpOiB2b2lkIHtcbiAgICAgICAgTWVkaWFEZXZpY2VIYW5kbGVyLmluc3RhbmNlLmFkZExpc3RlbmVyKE1lZGlhRGV2aWNlSGFuZGxlckV2ZW50LkF1ZGlvT3V0cHV0Q2hhbmdlZCwgdGhpcy5vbkF1ZGlvT3V0cHV0Q2hhbmdlZCk7XG4gICAgICAgIHRoaXMucHJvcHMuZmVlZC5hZGRMaXN0ZW5lcihDYWxsRmVlZEV2ZW50Lk5ld1N0cmVhbSwgdGhpcy5vbk5ld1N0cmVhbSk7XG4gICAgICAgIHRoaXMucGxheU1lZGlhKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCk6IHZvaWQge1xuICAgICAgICBNZWRpYURldmljZUhhbmRsZXIuaW5zdGFuY2UucmVtb3ZlTGlzdGVuZXIoXG4gICAgICAgICAgICBNZWRpYURldmljZUhhbmRsZXJFdmVudC5BdWRpb091dHB1dENoYW5nZWQsXG4gICAgICAgICAgICB0aGlzLm9uQXVkaW9PdXRwdXRDaGFuZ2VkLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnByb3BzLmZlZWQucmVtb3ZlTGlzdGVuZXIoQ2FsbEZlZWRFdmVudC5OZXdTdHJlYW0sIHRoaXMub25OZXdTdHJlYW0pO1xuICAgICAgICB0aGlzLnN0b3BNZWRpYSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25BdWRpb091dHB1dENoYW5nZWQgPSAoYXVkaW9PdXRwdXQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50LmN1cnJlbnQ7XG4gICAgICAgIGlmIChhdWRpb091dHB1dCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIHNlZW1zIHF1aXRlIHVucmVsaWFibGUgaW4gQ2hyb21lLCBhbHRob3VnaCBJIGhhdmVuJ3QgeWV0IG1hbmFnZWQgdG8gbWFrZSBhIGpzZmlkZGxlIHdoZXJlXG4gICAgICAgICAgICAgICAgLy8gaXQgZmFpbHMuXG4gICAgICAgICAgICAgICAgLy8gSXQgc2VlbXMgcmVsaWFibGUgaWYgeW91IHNldCB0aGUgc2luayBJRCBhZnRlciBzZXR0aW5nIHRoZSBzcmNPYmplY3QgYW5kIHRoZW4gc2V0IHRoZSBzaW5rIElEXG4gICAgICAgICAgICAgICAgLy8gYmFjayB0byB0aGUgZGVmYXVsdCBhZnRlciB0aGUgY2FsbCBpcyBvdmVyIC0gRGF2ZVxuICAgICAgICAgICAgICAgIGVsZW1lbnQhLnNldFNpbmtJZChhdWRpb091dHB1dCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiQ291bGRuJ3Qgc2V0IHJlcXVlc3RlZCBhdWRpbyBvdXRwdXQgZGV2aWNlOiB1c2luZyBkZWZhdWx0XCIsIGUpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiQ291bGRuJ3Qgc2V0IHJlcXVlc3RlZCBhdWRpbyBvdXRwdXQgZGV2aWNlOiB1c2luZyBkZWZhdWx0XCIsIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByaXZhdGUgYXN5bmMgcGxheU1lZGlhKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50LmN1cnJlbnQ7XG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xuICAgICAgICB0aGlzLm9uQXVkaW9PdXRwdXRDaGFuZ2VkKE1lZGlhRGV2aWNlSGFuZGxlci5nZXRBdWRpb091dHB1dCgpKTtcbiAgICAgICAgZWxlbWVudC5tdXRlZCA9IGZhbHNlO1xuICAgICAgICBlbGVtZW50LnNyY09iamVjdCA9IHRoaXMucHJvcHMuZmVlZC5zdHJlYW07XG4gICAgICAgIGVsZW1lbnQuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBBIG5vdGUgb24gY2FsbGluZyBtZXRob2RzIG9uIG1lZGlhIGVsZW1lbnRzOlxuICAgICAgICAgICAgLy8gV2UgdXNlZCB0byBoYXZlIHF1ZXVlcyBwZXIgbWVkaWEgZWxlbWVudCB0byBzZXJpYWxpc2UgYWxsIGNhbGxzIG9uIHRob3NlIGVsZW1lbnRzLlxuICAgICAgICAgICAgLy8gVGhlIHJlYXNvbiBnaXZlbiBmb3IgdGhpcyB3YXMgdGhhdCBsb2FkKCkgYW5kIHBsYXkoKSB3ZXJlIHJhY2luZy4gSG93ZXZlciwgd2Ugbm93XG4gICAgICAgICAgICAvLyBuZXZlciBjYWxsIGxvYWQoKSBleHBsaWNpdGx5IHNvIHRoaXMgc2VlbXMgdW5uZWNlc3NhcnkuIEhvd2V2ZXIsIHNlcmlhbGlzaW5nIGV2ZXJ5XG4gICAgICAgICAgICAvLyBvcGVyYXRpb24gd2FzIGNhdXNpbmcgYnVncyB3aGVyZSB2aWRlbyB3b3VsZCBub3QgcmVzdW1lIGJlY2F1c2Ugc29tZSBwbGF5IGNvbW1hbmRcbiAgICAgICAgICAgIC8vIGhhZCBnb3Qgc3R1Y2sgYW5kIGFsbCBtZWRpYSBvcGVyYXRpb25zIHdlcmUgcXVldWVkIHVwIGJlaGluZCBpdC4gSWYgbmVjZXNzYXJ5LCB3ZVxuICAgICAgICAgICAgLy8gc2hvdWxkIHNlcmlhbGlzZSB0aGUgb25lcyB0aGF0IG5lZWQgdG8gYmUgc2VyaWFsaXNlZCBidXQgdGhlbiBiZSBhYmxlIHRvIGludGVycnVwdFxuICAgICAgICAgICAgLy8gdGhlbSB3aXRoIGFub3RoZXIgbG9hZCgpIHdoaWNoIHdpbGwgY2FuY2VsIHRoZSBwZW5kaW5nIG9uZSwgYnV0IHNpbmNlIHdlIGRvbid0IGNhbGxcbiAgICAgICAgICAgIC8vIGxvYWQoKSBleHBsaWNpdGx5LCBpdCBzaG91bGRuJ3QgYmUgYSBwcm9ibGVtLiAtIERhdmVcbiAgICAgICAgICAgIGF3YWl0IGVsZW1lbnQubG9hZCgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHRvIHBsYXkgbWVkaWEgZWxlbWVudCB3aXRoIGZlZWQgZm9yIHVzZXJJZCBgICtcbiAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy5wcm9wcy5mZWVkLnVzZXJJZH0gd2l0aCBwdXJwb3NlICR7dGhpcy5wcm9wcy5mZWVkLnB1cnBvc2V9YCxcbiAgICAgICAgICAgICAgICBlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcE1lZGlhKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50LmN1cnJlbnQ7XG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuO1xuXG4gICAgICAgIGVsZW1lbnQucGF1c2UoKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJzcmNcIik7XG5cbiAgICAgICAgLy8gQXMgcGVyIGNvbW1lbnQgaW4gY29tcG9uZW50RGlkTW91bnQsIHNldHRpbmcgdGhlIHNpbmsgSUQgYmFjayB0byB0aGVcbiAgICAgICAgLy8gZGVmYXVsdCBvbmNlIHRoZSBjYWxsIGlzIG92ZXIgbWFrZXMgc2V0U2lua0lkIHdvcmsgcmVsaWFibHkuIC0gRGF2ZVxuICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgbm90IHVzaW5nIHRoZSBzYW1lIGVsZW1lbnQgYW55bW9yZSwgdGhlIGFib3ZlIGRvZXNuJ3RcbiAgICAgICAgLy8gc2VlbSB0byBiZSBuZWNlc3NhcnkgLSDFoGltb25cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uTmV3U3RyZWFtID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGF1ZGlvTXV0ZWQ6IHRoaXMucHJvcHMuZmVlZC5pc0F1ZGlvTXV0ZWQoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGxheU1lZGlhKCk7XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgLy8gRG8gbm90IHJlbmRlciB0aGUgYXVkaW8gZWxlbWVudCBpZiB0aGVyZSBpcyBubyBhdWRpbyB0cmFja1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5hdWRpb011dGVkKSByZXR1cm4gbnVsbDtcblxuICAgICAgICByZXR1cm4gPGF1ZGlvIHJlZj17dGhpcy5lbGVtZW50fSAvPjtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBUUEsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsU0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsT0FBQSxHQUFBRixPQUFBO0FBRUEsSUFBQUcsbUJBQUEsR0FBQUosdUJBQUEsQ0FBQUMsT0FBQTtBQUEwRixTQUFBSSx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBTix3QkFBQU0sQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUwsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3QkFBQSxXQUFBQyxDQUFBLElBQUFkLENBQUEsb0JBQUFjLENBQUEs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