Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.7 KiB
98 lines
2.7 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import safeAssign from '../../helpers/object/safeAssign'; |
|
import {logger} from '../logger'; |
|
import createDataChannel from './helpers/createDataChannel'; |
|
import createPeerConnection from './helpers/createPeerConnection'; |
|
import LocalConferenceDescription from './localConferenceDescription'; |
|
import StreamManager from './streamManager'; |
|
import {Ssrc} from './types'; |
|
|
|
export type CallConnectionInstanceOptions = { |
|
streamManager: StreamManager, |
|
connection?: RTCPeerConnection, |
|
log?: ReturnType<typeof logger> |
|
}; |
|
|
|
export default abstract class CallConnectionInstanceBase { |
|
public connection: RTCPeerConnection; |
|
public streamManager: StreamManager; |
|
public dataChannel: RTCDataChannel; |
|
public description: LocalConferenceDescription; |
|
public sources: { |
|
audio: Ssrc, |
|
video?: Ssrc, |
|
}; |
|
protected negotiating: Promise<void>; |
|
protected log: ReturnType<typeof logger>; |
|
|
|
constructor(options: CallConnectionInstanceOptions) { |
|
safeAssign(this, options); |
|
|
|
if(!this.log) { |
|
this.log = this.connection?.log || logger('CALL-CONNECTION-BASE'); |
|
} |
|
|
|
this.sources = {} as any; |
|
} |
|
|
|
public createPeerConnection(config?: RTCConfiguration) { |
|
return this.connection || (this.connection = createPeerConnection(config, this.log.bindPrefix('connection')).connection); |
|
} |
|
|
|
public createDataChannel(dict?: RTCDataChannelInit) { |
|
return this.dataChannel || (this.dataChannel = createDataChannel(this.connection, dict, this.log.bindPrefix('data'))); |
|
} |
|
|
|
public createDescription() { |
|
return this.description || (this.description = new LocalConferenceDescription(this.connection)); |
|
} |
|
|
|
public appendStreamToConference() { |
|
return this.streamManager.appendToConference(this.description); |
|
} |
|
|
|
public closeConnection() { |
|
const {connection} = this; |
|
if(!connection) { |
|
return; |
|
} |
|
|
|
try { |
|
connection.log('close'); |
|
connection.close(); |
|
} catch(e) { |
|
this.log.error(e); |
|
} |
|
} |
|
|
|
public closeConnectionAndStream(stopStream: boolean) { |
|
this.closeConnection(); |
|
stopStream && this.streamManager.stop(); |
|
} |
|
|
|
protected abstract negotiateInternal(): CallConnectionInstanceBase['negotiating']; |
|
|
|
public negotiate() { |
|
const promise = this.negotiating; |
|
if(promise) { |
|
return promise; |
|
} |
|
|
|
return this.negotiating = this.negotiateInternal().finally(() => { |
|
this.negotiating = undefined; |
|
}); |
|
} |
|
|
|
public sendDataChannelData(data: any) { |
|
if(this.dataChannel.readyState !== 'open') { |
|
return; |
|
} |
|
|
|
this.dataChannel.send(JSON.stringify(data)); |
|
} |
|
}
|
|
|