UNPKG

@skyway-sdk/sfu-bot

Version:

The official Next Generation JavaScript SDK for SkyWay

216 lines 9.47 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SFUConnection = void 0; const common_1 = require("@skyway-sdk/common"); const core_1 = require("@skyway-sdk/core"); const errors_1 = require("../errors"); const util_1 = require("../util"); const receiver_1 = require("./receiver"); const sender_1 = require("./sender"); const log = new common_1.Logger('packages/sfu-bot/src/connection/index.ts'); /**@internal */ class SFUConnection { /**@internal */ constructor(_api, channel, localPerson, remoteMember, _transportRepository, _context) { this._api = _api; this.channel = channel; this.localPerson = localPerson; this.remoteMember = remoteMember; this._transportRepository = _transportRepository; this._context = _context; this.type = 'sfu'; this.onDisconnect = new common_1.Event(); this.onClose = new common_1.Event(); this.closed = false; /**@private */ this._receivers = {}; /**@private */ this._senders = {}; } /**@internal */ addSender(publication) { const sender = new sender_1.Sender(publication, this.channel, this._api, this._transportRepository, this.localPerson, this.remoteMember, this.localPerson.iceManager, this._context); this._senders[publication.id] = sender; return sender; } /**@internal */ removeSender(originPublicationId) { log.debug('removeSender', originPublicationId); const sender = this._senders[originPublicationId]; if (!sender) { return; } sender.unproduce(); } startSubscribing(subscription) { var _a; return __awaiter(this, void 0, void 0, function* () { const receiver = new receiver_1.Receiver(subscription, this._api, this._transportRepository, this.localPerson, this.remoteMember, this.localPerson.iceManager, this._context); this._receivers[subscription.id] = receiver; const ts = log.debug('[start] _startSubscribing consume'); const { stream, codec } = yield receiver.consume().catch((e) => { log.error('[failed] _startSubscribing consume', (0, core_1.createError)({ operationName: 'SFUConnection.startSubscribing', context: this._context, channel: this.channel, info: Object.assign(Object.assign({}, errors_1.errors.internal), { detail: 'failed to receiver.consume' }), error: e, path: log.prefix, payload: { subscription: subscription.toJSON() }, })); throw e; }); log.elapsed(ts, '[end] _startSubscribing consume'); stream.setIsEnabled(subscription.publication.state === 'enabled'); subscription.codec = codec; subscription._setStream(stream); if (this.localPerson._analytics && !this.localPerson._analytics.isClosed()) { const preferredEncoding = subscription.preferredEncoding; const encodings = (_a = subscription.publication.origin) === null || _a === void 0 ? void 0 : _a.encodings; if (!preferredEncoding || !encodings || encodings.length === 0) { return; } const layer = (0, util_1.getLayerFromEncodings)(preferredEncoding, encodings); // 再送時に他の処理をブロックしないためにawaitしない void this.localPerson._analytics.client.sendSubscriptionUpdatePreferredEncodingReport({ subscriptionId: subscription.id, preferredEncodingIndex: layer, updatedAt: Date.now(), }); } }); } /**@internal */ stopSubscribing(subscription) { return __awaiter(this, void 0, void 0, function* () { const connection = this._receivers[subscription.id]; if (!connection) { return; } connection.unconsume(); }); } /**@internal */ stopPublishing(publication) { return __awaiter(this, void 0, void 0, function* () { this.removeSender(publication.id); }); } /**@internal */ close({ reason } = {}) { if (this.closed) { return; } log.debug('close sfu connection', { remote: this.remoteMember, local: this.localPerson, reason, }); this.closed = true; Object.values(this._senders).forEach((sender) => { sender.close(); }); Object.values(this._receivers).forEach((receiver) => { receiver.close(); }); this._senders = {}; this._receivers = {}; this.onClose.emit(); } _getReceiver(subscriptionId) { return this._receivers[subscriptionId]; } changePreferredEncoding(subscription) { var _a; return __awaiter(this, void 0, void 0, function* () { const preferredEncoding = subscription.preferredEncoding; const encodings = (_a = subscription.publication.origin) === null || _a === void 0 ? void 0 : _a.encodings; log.debug('changePreferredEncoding', { preferredEncoding, encodings, subscription, }); if (!preferredEncoding) { throw (0, core_1.createError)({ operationName: 'SFUConnection.changePreferredEncoding', context: this._context, channel: this.channel, info: errors_1.errors.invalidPreferredEncoding, path: log.prefix, payload: { subscription }, }); } if (!encodings || encodings.length === 0) { throw (0, core_1.createError)({ operationName: 'SFUConnection.changePreferredEncoding', context: this._context, channel: this.channel, info: errors_1.errors.invalidEncodings, path: log.prefix, payload: { subscription }, }); } const layer = (0, util_1.getLayerFromEncodings)(preferredEncoding, encodings); const receiver = this._getReceiver(subscription.id); if (!receiver) { throw (0, core_1.createError)({ operationName: 'SFUConnection.changePreferredEncoding', context: this._context, channel: this.channel, info: errors_1.errors.receiverNotFound, path: log.prefix, payload: { subscription }, }); } const transport = receiver.transport; if (!transport) { throw (0, core_1.createError)({ operationName: 'SFUConnection.changePreferredEncoding', context: this._context, channel: this.channel, info: Object.assign(Object.assign({}, errors_1.errors.internal), { detail: 'transport not found' }), path: log.prefix, payload: { subscription }, }); } const consumer = receiver.consumer; if (!consumer) { throw (0, core_1.createError)({ operationName: 'SFUConnection.changePreferredEncoding', context: this._context, channel: this.channel, info: errors_1.errors.consumerNotFound, path: log.prefix, payload: { subscription }, }); } yield this._api.changeConsumerLayer({ transportId: transport.id, consumerId: consumer.id, publicationId: subscription.publication.id, spatialLayer: layer, }); if (this.localPerson._analytics && !this.localPerson._analytics.isClosed()) { // 再送時に他の処理をブロックしないためにawaitしない void this.localPerson._analytics.client.sendSubscriptionUpdatePreferredEncodingReport({ subscriptionId: subscription.id, preferredEncodingIndex: layer, updatedAt: Date.now(), }); } }); } } exports.SFUConnection = SFUConnection; //# sourceMappingURL=index.js.map