UNPKG

matrix-react-sdk

Version:
135 lines (131 loc) 16.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.createVoiceMessageRecording = exports.VoiceMessageRecording = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _ContentMessages = require("../ContentMessages"); var _arrays = require("../utils/arrays"); var _Singleflight = require("../utils/Singleflight"); var _Playback = require("./Playback"); var _VoiceRecording = require("./VoiceRecording"); /* Copyright 2024 New Vector Ltd. Copyright 2022 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * This class can be used to record a single voice message. */ class VoiceMessageRecording { constructor(matrixClient, voiceRecording) { (0, _defineProperty2.default)(this, "lastUpload", void 0); (0, _defineProperty2.default)(this, "buffer", new Uint8Array(0)); // use this.audioBuffer to access (0, _defineProperty2.default)(this, "playback", void 0); (0, _defineProperty2.default)(this, "onDataAvailable", data => { const buf = new Uint8Array(data); this.buffer = (0, _arrays.concat)(this.buffer, buf); }); this.matrixClient = matrixClient; this.voiceRecording = voiceRecording; this.voiceRecording.onDataAvailable = this.onDataAvailable; } async start() { if (this.lastUpload || this.hasRecording) { throw new Error("Recording already prepared"); } return this.voiceRecording.start(); } async stop() { await this.voiceRecording.stop(); return this.audioBuffer; } on(event, listener) { this.voiceRecording.on(event, listener); return this; } off(event, listener) { this.voiceRecording.off(event, listener); return this; } emit(event, ...args) { return this.voiceRecording.emit(event, ...args); } get hasRecording() { return this.buffer.length > 0; } get isRecording() { return this.voiceRecording.isRecording; } /** * Gets a playback instance for this voice recording. Note that the playback will not * have been prepared fully, meaning the `prepare()` function needs to be called on it. * * The same playback instance is returned each time. * * @returns {Playback} The playback instance. */ getPlayback() { this.playback = _Singleflight.Singleflight.for(this, "playback").do(() => { return new _Playback.Playback(this.audioBuffer.buffer, this.voiceRecording.amplitudes); // cast to ArrayBuffer proper; }); return this.playback; } async upload(inRoomId) { if (!this.hasRecording) { throw new Error("No recording available to upload"); } if (this.lastUpload) return this.lastUpload; try { this.emit(_VoiceRecording.RecordingState.Uploading); const { url: mxc, file: encrypted } = await (0, _ContentMessages.uploadFile)(this.matrixClient, inRoomId, new Blob([this.audioBuffer], { type: this.contentType })); this.lastUpload = { mxc, encrypted }; this.emit(_VoiceRecording.RecordingState.Uploaded); } catch (e) { this.emit(_VoiceRecording.RecordingState.Ended); throw e; } return this.lastUpload; } get durationSeconds() { return this.voiceRecording.durationSeconds; } get contentType() { return this.voiceRecording.contentType; } get contentLength() { return this.buffer.length; } get liveData() { return this.voiceRecording.liveData; } get isSupported() { return this.voiceRecording.isSupported; } destroy() { this.playback?.destroy(); this.voiceRecording.destroy(); } get audioBuffer() { // We need a clone of the buffer to avoid accidentally changing the position // on the real thing. return this.buffer.slice(0); } } exports.VoiceMessageRecording = VoiceMessageRecording; const createVoiceMessageRecording = matrixClient => { return new VoiceMessageRecording(matrixClient, new _VoiceRecording.VoiceRecording()); }; exports.createVoiceMessageRecording = createVoiceMessageRecording; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQ29udGVudE1lc3NhZ2VzIiwicmVxdWlyZSIsIl9hcnJheXMiLCJfU2luZ2xlZmxpZ2h0IiwiX1BsYXliYWNrIiwiX1ZvaWNlUmVjb3JkaW5nIiwiVm9pY2VNZXNzYWdlUmVjb3JkaW5nIiwiY29uc3RydWN0b3IiLCJtYXRyaXhDbGllbnQiLCJ2b2ljZVJlY29yZGluZyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiVWludDhBcnJheSIsImRhdGEiLCJidWYiLCJidWZmZXIiLCJjb25jYXQiLCJvbkRhdGFBdmFpbGFibGUiLCJzdGFydCIsImxhc3RVcGxvYWQiLCJoYXNSZWNvcmRpbmciLCJFcnJvciIsInN0b3AiLCJhdWRpb0J1ZmZlciIsIm9uIiwiZXZlbnQiLCJsaXN0ZW5lciIsIm9mZiIsImVtaXQiLCJhcmdzIiwibGVuZ3RoIiwiaXNSZWNvcmRpbmciLCJnZXRQbGF5YmFjayIsInBsYXliYWNrIiwiU2luZ2xlZmxpZ2h0IiwiZm9yIiwiZG8iLCJQbGF5YmFjayIsImFtcGxpdHVkZXMiLCJ1cGxvYWQiLCJpblJvb21JZCIsIlJlY29yZGluZ1N0YXRlIiwiVXBsb2FkaW5nIiwidXJsIiwibXhjIiwiZmlsZSIsImVuY3J5cHRlZCIsInVwbG9hZEZpbGUiLCJCbG9iIiwidHlwZSIsImNvbnRlbnRUeXBlIiwiVXBsb2FkZWQiLCJlIiwiRW5kZWQiLCJkdXJhdGlvblNlY29uZHMiLCJjb250ZW50TGVuZ3RoIiwibGl2ZURhdGEiLCJpc1N1cHBvcnRlZCIsImRlc3Ryb3kiLCJzbGljZSIsImV4cG9ydHMiLCJjcmVhdGVWb2ljZU1lc3NhZ2VSZWNvcmRpbmciLCJWb2ljZVJlY29yZGluZyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdWRpby9Wb2ljZU1lc3NhZ2VSZWNvcmRpbmcudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjIgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgTWF0cml4Q2xpZW50IH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgRW5jcnlwdGVkRmlsZSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuaW1wb3J0IHsgU2ltcGxlT2JzZXJ2YWJsZSB9IGZyb20gXCJtYXRyaXgtd2lkZ2V0LWFwaVwiO1xuXG5pbXBvcnQgeyB1cGxvYWRGaWxlIH0gZnJvbSBcIi4uL0NvbnRlbnRNZXNzYWdlc1wiO1xuaW1wb3J0IHsgY29uY2F0IH0gZnJvbSBcIi4uL3V0aWxzL2FycmF5c1wiO1xuaW1wb3J0IHsgSURlc3Ryb3lhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL0lEZXN0cm95YWJsZVwiO1xuaW1wb3J0IHsgU2luZ2xlZmxpZ2h0IH0gZnJvbSBcIi4uL3V0aWxzL1NpbmdsZWZsaWdodFwiO1xuaW1wb3J0IHsgUGxheWJhY2sgfSBmcm9tIFwiLi9QbGF5YmFja1wiO1xuaW1wb3J0IHsgSVJlY29yZGluZ1VwZGF0ZSwgUmVjb3JkaW5nU3RhdGUsIFZvaWNlUmVjb3JkaW5nIH0gZnJvbSBcIi4vVm9pY2VSZWNvcmRpbmdcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJVXBsb2FkIHtcbiAgICBteGM/OiBzdHJpbmc7IC8vIGZvciB1bmVuY3J5cHRlZCB1cGxvYWRzXG4gICAgZW5jcnlwdGVkPzogRW5jcnlwdGVkRmlsZTtcbn1cblxuLyoqXG4gKiBUaGlzIGNsYXNzIGNhbiBiZSB1c2VkIHRvIHJlY29yZCBhIHNpbmdsZSB2b2ljZSBtZXNzYWdlLlxuICovXG5leHBvcnQgY2xhc3MgVm9pY2VNZXNzYWdlUmVjb3JkaW5nIGltcGxlbWVudHMgSURlc3Ryb3lhYmxlIHtcbiAgICBwcml2YXRlIGxhc3RVcGxvYWQ/OiBJVXBsb2FkO1xuICAgIHByaXZhdGUgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMCk7IC8vIHVzZSB0aGlzLmF1ZGlvQnVmZmVyIHRvIGFjY2Vzc1xuICAgIHByaXZhdGUgcGxheWJhY2s/OiBQbGF5YmFjaztcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBtYXRyaXhDbGllbnQ6IE1hdHJpeENsaWVudCxcbiAgICAgICAgcHJpdmF0ZSB2b2ljZVJlY29yZGluZzogVm9pY2VSZWNvcmRpbmcsXG4gICAgKSB7XG4gICAgICAgIHRoaXMudm9pY2VSZWNvcmRpbmcub25EYXRhQXZhaWxhYmxlID0gdGhpcy5vbkRhdGFBdmFpbGFibGU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5sYXN0VXBsb2FkIHx8IHRoaXMuaGFzUmVjb3JkaW5nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWNvcmRpbmcgYWxyZWFkeSBwcmVwYXJlZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnZvaWNlUmVjb3JkaW5nLnN0YXJ0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHN0b3AoKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgICAgIGF3YWl0IHRoaXMudm9pY2VSZWNvcmRpbmcuc3RvcCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5hdWRpb0J1ZmZlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgb24oZXZlbnQ6IHN0cmluZyB8IHN5bWJvbCwgbGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICB0aGlzLnZvaWNlUmVjb3JkaW5nLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyBvZmYoZXZlbnQ6IHN0cmluZyB8IHN5bWJvbCwgbGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICB0aGlzLnZvaWNlUmVjb3JkaW5nLm9mZihldmVudCwgbGlzdGVuZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwdWJsaWMgZW1pdChldmVudDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy52b2ljZVJlY29yZGluZy5lbWl0KGV2ZW50LCAuLi5hcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhhc1JlY29yZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLmxlbmd0aCA+IDA7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpc1JlY29yZGluZygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2VSZWNvcmRpbmcuaXNSZWNvcmRpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIHBsYXliYWNrIGluc3RhbmNlIGZvciB0aGlzIHZvaWNlIHJlY29yZGluZy4gTm90ZSB0aGF0IHRoZSBwbGF5YmFjayB3aWxsIG5vdFxuICAgICAqIGhhdmUgYmVlbiBwcmVwYXJlZCBmdWxseSwgbWVhbmluZyB0aGUgYHByZXBhcmUoKWAgZnVuY3Rpb24gbmVlZHMgdG8gYmUgY2FsbGVkIG9uIGl0LlxuICAgICAqXG4gICAgICogVGhlIHNhbWUgcGxheWJhY2sgaW5zdGFuY2UgaXMgcmV0dXJuZWQgZWFjaCB0aW1lLlxuICAgICAqXG4gICAgICogQHJldHVybnMge1BsYXliYWNrfSBUaGUgcGxheWJhY2sgaW5zdGFuY2UuXG4gICAgICovXG4gICAgcHVibGljIGdldFBsYXliYWNrKCk6IFBsYXliYWNrIHtcbiAgICAgICAgdGhpcy5wbGF5YmFjayA9IFNpbmdsZWZsaWdodC5mb3IodGhpcywgXCJwbGF5YmFja1wiKS5kbygoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFBsYXliYWNrKHRoaXMuYXVkaW9CdWZmZXIuYnVmZmVyLCB0aGlzLnZvaWNlUmVjb3JkaW5nLmFtcGxpdHVkZXMpOyAvLyBjYXN0IHRvIEFycmF5QnVmZmVyIHByb3BlcjtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLnBsYXliYWNrO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyB1cGxvYWQoaW5Sb29tSWQ6IHN0cmluZyk6IFByb21pc2U8SVVwbG9hZD4ge1xuICAgICAgICBpZiAoIXRoaXMuaGFzUmVjb3JkaW5nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyByZWNvcmRpbmcgYXZhaWxhYmxlIHRvIHVwbG9hZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmxhc3RVcGxvYWQpIHJldHVybiB0aGlzLmxhc3RVcGxvYWQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChSZWNvcmRpbmdTdGF0ZS5VcGxvYWRpbmcpO1xuICAgICAgICAgICAgY29uc3QgeyB1cmw6IG14YywgZmlsZTogZW5jcnlwdGVkIH0gPSBhd2FpdCB1cGxvYWRGaWxlKFxuICAgICAgICAgICAgICAgIHRoaXMubWF0cml4Q2xpZW50LFxuICAgICAgICAgICAgICAgIGluUm9vbUlkLFxuICAgICAgICAgICAgICAgIG5ldyBCbG9iKFt0aGlzLmF1ZGlvQnVmZmVyXSwge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnRUeXBlLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMubGFzdFVwbG9hZCA9IHsgbXhjLCBlbmNyeXB0ZWQgfTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChSZWNvcmRpbmdTdGF0ZS5VcGxvYWRlZCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChSZWNvcmRpbmdTdGF0ZS5FbmRlZCk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmxhc3RVcGxvYWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkdXJhdGlvblNlY29uZHMoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2VSZWNvcmRpbmcuZHVyYXRpb25TZWNvbmRzO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgY29udGVudFR5cGUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2VSZWNvcmRpbmcuY29udGVudFR5cGU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjb250ZW50TGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5sZW5ndGg7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBsaXZlRGF0YSgpOiBTaW1wbGVPYnNlcnZhYmxlPElSZWNvcmRpbmdVcGRhdGU+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2VSZWNvcmRpbmcubGl2ZURhdGE7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpc1N1cHBvcnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2VSZWNvcmRpbmcuaXNTdXBwb3J0ZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMucGxheWJhY2s/LmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy52b2ljZVJlY29yZGluZy5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRhdGFBdmFpbGFibGUgPSAoZGF0YTogQXJyYXlCdWZmZXIpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgYnVmID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gY29uY2F0KHRoaXMuYnVmZmVyLCBidWYpO1xuICAgIH07XG5cbiAgICBwcml2YXRlIGdldCBhdWRpb0J1ZmZlcigpOiBVaW50OEFycmF5IHtcbiAgICAgICAgLy8gV2UgbmVlZCBhIGNsb25lIG9mIHRoZSBidWZmZXIgdG8gYXZvaWQgYWNjaWRlbnRhbGx5IGNoYW5naW5nIHRoZSBwb3NpdGlvblxuICAgICAgICAvLyBvbiB0aGUgcmVhbCB0aGluZy5cbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnNsaWNlKDApO1xuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVZvaWNlTWVzc2FnZVJlY29yZGluZyA9IChtYXRyaXhDbGllbnQ6IE1hdHJpeENsaWVudCk6IFZvaWNlTWVzc2FnZVJlY29yZGluZyA9PiB7XG4gICAgcmV0dXJuIG5ldyBWb2ljZU1lc3NhZ2VSZWNvcmRpbmcobWF0cml4Q2xpZW50LCBuZXcgVm9pY2VSZWNvcmRpbmcoKSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVlBLElBQUFBLGdCQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxhQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxTQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxlQUFBLEdBQUFKLE9BQUE7QUFqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBa0JBO0FBQ0E7QUFDQTtBQUNPLE1BQU1LLHFCQUFxQixDQUF5QjtFQUtoREMsV0FBV0EsQ0FDTkMsWUFBMEIsRUFDMUJDLGNBQThCLEVBQ3hDO0lBQUEsSUFBQUMsZ0JBQUEsQ0FBQUMsT0FBQTtJQUFBLElBQUFELGdCQUFBLENBQUFDLE9BQUEsa0JBTmUsSUFBSUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUFFO0lBQUEsSUFBQUYsZ0JBQUEsQ0FBQUMsT0FBQTtJQUFBLElBQUFELGdCQUFBLENBQUFDLE9BQUEsMkJBOEdURSxJQUFpQixJQUFXO01BQ25ELE1BQU1DLEdBQUcsR0FBRyxJQUFJRixVQUFVLENBQUNDLElBQUksQ0FBQztNQUNoQyxJQUFJLENBQUNFLE1BQU0sR0FBRyxJQUFBQyxjQUFN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