Revert "feat(streams): add phase-2 SFU transport handshake and produce/consume APIs"
This reverts commit 498a7f838b7747470b220701505c4bfbd3ea8cff.
This commit is contained in:
@@ -3,12 +3,6 @@ import { randomUUID } from 'crypto';
|
||||
import { mediaConfig } from '../config';
|
||||
import { SfuSessionRegistry } from './registry';
|
||||
import type {
|
||||
SfuConnectTransportInput,
|
||||
SfuConsumeInput,
|
||||
SfuConsumerDescriptor,
|
||||
SfuIceServer,
|
||||
SfuProduceInput,
|
||||
SfuProducerDescriptor,
|
||||
SfuPublishTransportRequest,
|
||||
SfuPublishTransportResult,
|
||||
SfuService,
|
||||
@@ -16,10 +10,9 @@ import type {
|
||||
SfuSessionStartInput,
|
||||
SfuSubscribeTransportRequest,
|
||||
SfuSubscribeTransportResult,
|
||||
SfuTransportDescriptor,
|
||||
} from './types';
|
||||
|
||||
const toIceServers = (): SfuIceServer[] => {
|
||||
const toIceServers = (): Array<{ urls: string; username?: string; credential?: string }> => {
|
||||
if (mediaConfig.turn.urls.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -64,138 +57,21 @@ export class NoopSfuService implements SfuService {
|
||||
return this.registry.get(streamSessionId);
|
||||
}
|
||||
|
||||
async getRouterRtpCapabilities(_streamSessionId: string): Promise<Record<string, unknown> | null> {
|
||||
return {
|
||||
codecs: [{ mimeType: 'video/VP8', clockRate: 90000, kind: 'video' }],
|
||||
headerExtensions: [],
|
||||
};
|
||||
}
|
||||
|
||||
async listSessions(): Promise<SfuSessionDescriptor[]> {
|
||||
return this.registry.list();
|
||||
}
|
||||
|
||||
async listTransports(streamSessionId: string): Promise<SfuTransportDescriptor[]> {
|
||||
return this.registry.listTransports(streamSessionId);
|
||||
}
|
||||
|
||||
async listProducers(streamSessionId: string): Promise<SfuProducerDescriptor[]> {
|
||||
return this.registry.listProducers(streamSessionId);
|
||||
}
|
||||
|
||||
async listConsumers(streamSessionId: string): Promise<SfuConsumerDescriptor[]> {
|
||||
return this.registry.listConsumers(streamSessionId);
|
||||
}
|
||||
|
||||
async createPublishTransport(input: SfuPublishTransportRequest): Promise<SfuPublishTransportResult> {
|
||||
const transportId = `pub_${randomUUID()}`;
|
||||
this.registry.addTransport({
|
||||
transportId,
|
||||
streamSessionId: input.streamSessionId,
|
||||
ownerDeviceId: input.cameraDeviceId,
|
||||
direction: 'publish',
|
||||
});
|
||||
async createPublishTransport(_input: SfuPublishTransportRequest): Promise<SfuPublishTransportResult> {
|
||||
return {
|
||||
transportId,
|
||||
transportId: `pub_${randomUUID()}`,
|
||||
iceServers: toIceServers(),
|
||||
transportOptions: {
|
||||
id: transportId,
|
||||
iceParameters: {},
|
||||
iceCandidates: [],
|
||||
dtlsParameters: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async createSubscribeTransport(input: SfuSubscribeTransportRequest): Promise<SfuSubscribeTransportResult> {
|
||||
const transportId = `sub_${randomUUID()}`;
|
||||
this.registry.addTransport({
|
||||
transportId,
|
||||
streamSessionId: input.streamSessionId,
|
||||
ownerDeviceId: input.viewerDeviceId,
|
||||
direction: 'subscribe',
|
||||
});
|
||||
async createSubscribeTransport(_input: SfuSubscribeTransportRequest): Promise<SfuSubscribeTransportResult> {
|
||||
return {
|
||||
transportId,
|
||||
transportId: `sub_${randomUUID()}`,
|
||||
iceServers: toIceServers(),
|
||||
transportOptions: {
|
||||
id: transportId,
|
||||
iceParameters: {},
|
||||
iceCandidates: [],
|
||||
dtlsParameters: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async connectPublishTransport(input: SfuConnectTransportInput): Promise<SfuTransportDescriptor> {
|
||||
const transport = this.registry.getTransport(input.transportId);
|
||||
if (!transport) throw new Error('Publish transport not found');
|
||||
if (transport.streamSessionId !== input.streamSessionId) throw new Error('Transport does not belong to stream');
|
||||
if (transport.direction !== 'publish') throw new Error('Transport is not a publish transport');
|
||||
if (transport.ownerDeviceId !== input.deviceId) throw new Error('Device does not own this publish transport');
|
||||
|
||||
const connected = this.registry.connectTransport(input.transportId);
|
||||
if (!connected) throw new Error('Publish transport connect failed');
|
||||
return connected;
|
||||
}
|
||||
|
||||
async connectSubscribeTransport(input: SfuConnectTransportInput): Promise<SfuTransportDescriptor> {
|
||||
const transport = this.registry.getTransport(input.transportId);
|
||||
if (!transport) throw new Error('Subscribe transport not found');
|
||||
if (transport.streamSessionId !== input.streamSessionId) throw new Error('Transport does not belong to stream');
|
||||
if (transport.direction !== 'subscribe') throw new Error('Transport is not a subscribe transport');
|
||||
if (transport.ownerDeviceId !== input.deviceId) throw new Error('Device does not own this subscribe transport');
|
||||
|
||||
const connected = this.registry.connectTransport(input.transportId);
|
||||
if (!connected) throw new Error('Subscribe transport connect failed');
|
||||
return connected;
|
||||
}
|
||||
|
||||
async produce(input: SfuProduceInput): Promise<SfuProducerDescriptor> {
|
||||
const transport = this.registry.getTransport(input.transportId);
|
||||
if (!transport) throw new Error('Publish transport not found');
|
||||
if (transport.streamSessionId !== input.streamSessionId) throw new Error('Transport does not belong to stream');
|
||||
if (transport.direction !== 'publish') throw new Error('Transport is not a publish transport');
|
||||
if (transport.ownerDeviceId !== input.cameraDeviceId) throw new Error('Device does not own this publish transport');
|
||||
if (transport.state !== 'connected') throw new Error('Publish transport must be connected before producing');
|
||||
|
||||
return this.registry.addProducer({
|
||||
producerId: `prod_${randomUUID()}`,
|
||||
streamSessionId: input.streamSessionId,
|
||||
transportId: input.transportId,
|
||||
cameraDeviceId: input.cameraDeviceId,
|
||||
kind: input.kind,
|
||||
rtpParameters: input.rtpParameters,
|
||||
});
|
||||
}
|
||||
|
||||
async consume(input: SfuConsumeInput): Promise<SfuConsumerDescriptor> {
|
||||
const transport = this.registry.getTransport(input.transportId);
|
||||
if (!transport) throw new Error('Subscribe transport not found');
|
||||
if (transport.streamSessionId !== input.streamSessionId) throw new Error('Transport does not belong to stream');
|
||||
if (transport.direction !== 'subscribe') throw new Error('Transport is not a subscribe transport');
|
||||
if (transport.ownerDeviceId !== input.viewerDeviceId) throw new Error('Device does not own this subscribe transport');
|
||||
if (transport.state !== 'connected') throw new Error('Subscribe transport must be connected before consuming');
|
||||
|
||||
const selectedProducer =
|
||||
(input.producerId ? this.registry.getProducer(input.producerId) : null) ??
|
||||
this.registry
|
||||
.listProducers(input.streamSessionId)
|
||||
.slice()
|
||||
.reverse()
|
||||
.find((producer) => producer.kind === 'video');
|
||||
|
||||
if (!selectedProducer) throw new Error('No producer available for consume');
|
||||
if (selectedProducer.streamSessionId !== input.streamSessionId) throw new Error('Producer does not belong to stream');
|
||||
|
||||
return this.registry.addConsumer({
|
||||
consumerId: `cons_${randomUUID()}`,
|
||||
streamSessionId: input.streamSessionId,
|
||||
transportId: input.transportId,
|
||||
viewerDeviceId: input.viewerDeviceId,
|
||||
producerId: selectedProducer.producerId,
|
||||
kind: selectedProducer.kind,
|
||||
rtpParameters: selectedProducer.rtpParameters,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user