UNPKG

@skyway-sdk/core

Version:

The official Next Generation JavaScript SDK for SkyWay

485 lines 18.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; 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.sortEncodingParameters = exports.normalizeEncodings = exports.PublicationImpl = void 0; const common_1 = require("@skyway-sdk/common"); const common_2 = require("@skyway-sdk/common"); const errors_1 = require("../errors"); const data_1 = require("../media/stream/local/data"); const util_1 = require("../util"); __exportStar(require("./factory"), exports); const log = new common_1.Logger('packages/core/src/publication/index.ts'); /**@internal */ class PublicationImpl { constructor(args) { var _a, _b, _c; this._codecCapabilities = []; this._encodings = []; this._state = 'enabled'; this._events = new common_1.Events(); this.onCanceled = this._events.make(); this.onSubscribed = this._events.make(); this.onUnsubscribed = this._events.make(); this.onSubscriptionListChanged = this._events.make(); this.onMetadataUpdated = this._events.make(); this.onEnabled = this._events.make(); this.onDisabled = this._events.make(); this.onStateChanged = this._events.make(); this.onConnectionStateChanged = new common_2.Event(); /**@private */ this._onEncodingsChanged = this._events.make(); /**@private */ this._onReplaceStream = this._events.make(); this._onEnabled = this._events.make(); this.streamEventDisposer = new common_1.EventDisposer(); /** * @deprecated * @use {@link LocalPerson.unpublish} */ this.cancel = () => new Promise((r, f) => { let failed = false; this._channel._unpublish(this.id).catch((e) => { failed = true; f(e); }); this._setStream(undefined); this.onCanceled .asPromise(this._context.config.rtcApi.timeout) .then(() => r()) .catch((e) => { if (!failed) { f(e); } }); }); this.updateMetadata = (metadata) => new Promise((r, f) => __awaiter(this, void 0, void 0, function* () { const timestamp = log.info('[start] updateMetadata', yield (0, util_1.createLogPayload)({ operationName: 'Publication.updateMetadata', channel: this._channel, }), this); let failed = false; this._channel._updatePublicationMetadata(this.id, metadata).catch((e) => { failed = true; f(e); }); this.onMetadataUpdated .watch((e) => e.metadata === metadata, this._context.config.rtcApi.timeout) .then(() => __awaiter(this, void 0, void 0, function* () { r(); log.elapsed(timestamp, '[end] updateMetadata', yield (0, util_1.createLogPayload)({ operationName: 'Publication.updateMetadata', channel: this._channel, }), this); })) .catch((error) => { if (!failed) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.updateMetadata', info: Object.assign(Object.assign({}, errors_1.errors.timeout), { detail: 'publication onMetadataUpdated' }), path: log.prefix, context: this._context, channel: this._channel, error, }); } }); })); this.disable = () => new Promise((r, f) => __awaiter(this, void 0, void 0, function* () { // すでに disabled の場合は何もしない if (this.state === 'disabled') { r(); return; } const timestamp = log.info('[start] disable', yield (0, util_1.createLogPayload)({ operationName: 'Publication.disable', channel: this._channel, }), this); yield this._disableStream(); let failed = false; this._channel._disablePublication(this.id).catch((e) => { failed = true; f(e); }); this.onDisabled .asPromise(this._context.config.rtcApi.timeout) .then(() => __awaiter(this, void 0, void 0, function* () { r(); log.elapsed(timestamp, '[end] disable', yield (0, util_1.createLogPayload)({ operationName: 'Publication.disable', channel: this._channel, }), this); })) .catch((e) => { if (!failed) { f(e); } }); })); this.enable = () => new Promise((r, f) => __awaiter(this, void 0, void 0, function* () { if (this.stream == undefined) { f((0, util_1.createError)({ operationName: 'Publication.enable', context: this._context, info: errors_1.errors.canNotEnableRemotePublication, path: log.prefix, })); return; } // すでに enabled の場合は何もしない if (this.state === 'enabled') { r(); return; } const timestamp = log.info('[start] enable', yield (0, util_1.createLogPayload)({ operationName: 'Publication.enable', channel: this._channel, }), this); let failed = false; this._channel._enablePublication(this.id).catch((e) => { failed = true; f(e); }); this._onEnabled .asPromise(this._context.config.rtcApi.timeout) .then(() => __awaiter(this, void 0, void 0, function* () { yield this._enableStream(); this.onEnabled.emit(); this.onStateChanged.emit(); log.elapsed(timestamp, '[end] enable', yield (0, util_1.createLogPayload)({ operationName: 'Publication.enable', channel: this._channel, }), this); r(); })) .catch((e) => { if (!failed) { f(e); } }); })); this.id = args.id; this._channel = args.channel; this._context = this._channel._context; this.publisher = args.publisher; this.contentType = args.contentType; this._metadata = args.metadata; this.origin = args.origin; this.setCodecCapabilities((_a = args.codecCapabilities) !== null && _a !== void 0 ? _a : []); this.setEncodings((0, exports.normalizeEncodings)((_b = args.encodings) !== null && _b !== void 0 ? _b : [])); this._state = args.isEnabled ? 'enabled' : 'disabled'; if (args.stream) { this._setStream(args.stream); } this._analytics = (_c = this._channel.localPerson) === null || _c === void 0 ? void 0 : _c._analytics; log.debug('publication spawned', this.toJSON()); } get codecCapabilities() { return this._codecCapabilities; } setCodecCapabilities(_codecCapabilities) { this._codecCapabilities = _codecCapabilities; } get encodings() { return this._encodings; } setEncodings(_encodings) { this._encodings = _encodings; } get stream() { return this._stream; } /**@internal */ _setStream(stream) { this._stream = stream; if (stream) { stream._onConnectionStateChanged .add((e) => { log.debug('onConnectionStateChanged', this.id, e); this.onConnectionStateChanged.emit(e); }) .disposer(this.streamEventDisposer); } else { this.streamEventDisposer.dispose(); } } get metadata() { return this._metadata; } get state() { return this._state; } get deviceName() { if (this.stream instanceof data_1.LocalDataStream) { return undefined; } else { const withDeviceStream = this.stream; return withDeviceStream.track.label; } } get subscriptions() { return this._channel.subscriptions.filter((s) => s.publication.id === this.id); } /**@private */ _updateMetadata(metadata) { this._metadata = metadata; this.onMetadataUpdated.emit({ metadata }); } /**@private */ _disable() { return __awaiter(this, void 0, void 0, function* () { yield this._disableStream(); this.onDisabled.emit(); this.onStateChanged.emit(); }); } /**@private */ _enable() { if (this.stream) { this._onEnabled.emit(); } else { this._state = 'enabled'; this.onEnabled.emit(); this.onStateChanged.emit(); } } /**@private */ _unpublished() { this._state = 'canceled'; if (this.stream) { this.stream._unpublished(); } this.onCanceled.emit(); this.onStateChanged.emit(); this._dispose(); } /**@private */ _subscribed(subscription) { this.onSubscribed.emit({ subscription }); this.onSubscriptionListChanged.emit(); } /**@private */ _unsubscribed(subscription) { this.onUnsubscribed.emit({ subscription }); this.onSubscriptionListChanged.emit(); } updateEncodings(encodings) { log.info('updateEncodings', { encodings }, this); this.setEncodings((0, exports.normalizeEncodings)((0, exports.sortEncodingParameters)(encodings))); this._onEncodingsChanged.emit(encodings); if (this._analytics && !this._analytics.isClosed()) { // 再送時に他の処理をブロックしないためにawaitしない void this._analytics.client.sendPublicationUpdateEncodingsReport({ publicationId: this.id, encodings: this.encodings, updatedAt: Date.now(), }); } } _disableStream() { return __awaiter(this, void 0, void 0, function* () { if (this.state === 'disabled') { return; } this._state = 'disabled'; if (!this.stream) { return; } if (this.stream.contentType === 'data') { this.stream.setIsEnabled(false); } else { yield this.stream.setEnabled(false).catch((e) => { log.warn((0, util_1.createWarnPayload)({ channel: this._channel, operationName: 'Publication._disableStream', payload: e, detail: 'setEnabled failed', })); }); } (0, util_1.createLogPayload)({ operationName: 'Publication._disableStream', channel: this._channel, }) .then((p) => log.info('publication _disableStream', p, { publication: this })) .catch(() => { }); }); } _enableStream() { return __awaiter(this, void 0, void 0, function* () { if (this.state === 'enabled') { return; } this._state = 'enabled'; if (!this.stream) { return; } (0, util_1.createLogPayload)({ operationName: 'Publication._enableStream', channel: this._channel, }) .then((p) => log.info('publication _enableStream', p, { publication: this })) .catch(() => { }); if (this.stream.contentType === 'data') { this.stream.setIsEnabled(true); } else { yield this.stream.setEnabled(true).catch((e) => { log.warn((0, util_1.createWarnPayload)({ channel: this._channel, operationName: 'Publication._disableStream', payload: e, detail: 'setEnabled failed', })); }); } }); } replaceStream(stream, options = {}) { var _a; log.info('replaceStream', { stream, options }, this); if (!this.stream) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.replaceStream', context: this._context, info: errors_1.errors.canNotUseReplaceStream, path: log.prefix, }); } if (stream.contentType !== this.contentType) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.replaceStream', context: this._context, info: errors_1.errors.invalidContentType, path: log.prefix, }); } if ((_a = options.releaseOldStream) !== null && _a !== void 0 ? _a : true) { const old = this.stream; old.release(); } (0, util_1.createLogPayload)({ operationName: 'PublicationImpl.replaceStream', channel: this._channel, }) .then((res) => log.debug(res, { old: this.stream, new: stream })) .catch((e) => e); stream.setEnabled(this.stream.isEnabled).catch((e) => { log.error('replaceStream stream.setEnabled', e, this.toJSON()); }); const oldStream = this._stream; this._setStream(stream); this._onReplaceStream.emit({ newStream: stream, oldStream }); if (this._analytics && !this._analytics.isClosed()) { // 再送時に他の処理をブロックしないためにawaitしない void this._analytics.client.sendMediaDeviceReport({ publicationId: this.id, mediaDeviceName: this.deviceName, mediaDeviceTrigger: 'replaceStream', updatedAt: Date.now(), }); } } getStats(selector) { if (!this.stream) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.getStats', context: this._context, info: errors_1.errors.streamNotExistInSubscription, path: log.prefix, }); } return this.stream._getStats(selector); } getRTCPeerConnection(selector) { if (!this.stream) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.getRTCPeerConnection', context: this._context, info: errors_1.errors.streamNotExistInSubscription, path: log.prefix, }); } return this.stream._getRTCPeerConnection(selector); } getConnectionState(selector) { if (!this.stream) { throw (0, util_1.createError)({ operationName: 'PublicationImpl.getConnectionState', context: this._context, info: errors_1.errors.streamNotExistInSubscription, path: log.prefix, }); } return this.stream._getConnectionState(selector); } /**@private */ toJSON() { var _a; return { id: this.id, channelId: this._channel.id, publisherId: this.publisher.id, origin: (_a = this.origin) === null || _a === void 0 ? void 0 : _a.id, contentType: this.contentType, metadata: this.metadata, codecCapabilities: this.codecCapabilities, encodings: this.encodings, state: this.state, stream: this.stream, }; } _dispose() { this._events.dispose(); } } exports.PublicationImpl = PublicationImpl; /**@internal */ const normalizeEncodings = (encodings) => encodings.map((e, i) => { var _a; return (Object.assign(Object.assign({}, e), { id: (_a = e.id) !== null && _a !== void 0 ? _a : i.toString() })); }); exports.normalizeEncodings = normalizeEncodings; const sortEncodingParameters = (encodings) => { const [encode] = encodings; if (encode.maxBitrate) { // 小から大 return encodings.sort((a, b) => a.maxBitrate - b.maxBitrate); } else if (encode.scaleResolutionDownBy) { //大から小 return encodings.sort((a, b) => b.scaleResolutionDownBy - a.scaleResolutionDownBy); } else if (encode.maxFramerate) { // 小から大 return encodings.sort((a, b) => a.maxFramerate - b.maxFramerate); } return encodings; }; exports.sortEncodingParameters = sortEncodingParameters; //# sourceMappingURL=index.js.map