@campoint/vxwebrtc 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/MungeSdp.d.ts +2 -0
  2. package/dist/Types/CodecsOptions.d.ts +8 -0
  3. package/dist/Types/CommonConnectionTypes.d.ts +48 -0
  4. package/dist/Types/EnumCodecContentType.d.ts +13 -0
  5. package/dist/Types/EnumMediaStreamTrackKind.d.ts +4 -0
  6. package/dist/Types/WebRTCStreamConfig.d.ts +26 -0
  7. package/dist/WebRtcInputConnection.d.ts +19 -0
  8. package/dist/WebRtcOutputConnection.d.ts +21 -0
  9. package/dist/WebRtcPeerConnection.d.ts +23 -0
  10. package/dist/browserSupportedAudioCodec.d.ts +13 -0
  11. package/dist/browserSupportedVideoCodec.d.ts +7 -0
  12. package/dist/stats.json +10371 -0
  13. package/dist/utils.d.ts +6 -0
  14. package/dist/version.d.ts +1 -0
  15. package/{src/vxwebrtc.ts → dist/vxwebrtc.d.ts} +1 -8
  16. package/dist/vxwebrtc.js +3 -0
  17. package/dist/vxwebrtc.js.LICENSE.txt +8 -0
  18. package/dist/vxwebrtc.js.map +1 -0
  19. package/package.json +4 -1
  20. package/.eslintignore +0 -1
  21. package/.eslintrc.js +0 -22
  22. package/.gitlab-ci.yml +0 -51
  23. package/.husky/pre-commit +0 -4
  24. package/.prettierignore +0 -1
  25. package/src/MungeSdp.ts +0 -323
  26. package/src/Types/CodecsOptions.ts +0 -9
  27. package/src/Types/CommonConnectionTypes.ts +0 -57
  28. package/src/Types/EnumCodecContentType.ts +0 -13
  29. package/src/Types/EnumMediaStreamTrackKind.ts +0 -4
  30. package/src/Types/WebRTCStreamConfig.ts +0 -59
  31. package/src/WebRtcInputConnection.ts +0 -152
  32. package/src/WebRtcOutputConnection.ts +0 -153
  33. package/src/WebRtcPeerConnection.ts +0 -91
  34. package/src/browserSupportedAudioCodec.ts +0 -49
  35. package/src/browserSupportedVideoCodec.ts +0 -39
  36. package/src/utils.ts +0 -18
  37. package/src/version.ts +0 -1
  38. package/tsconfig.json +0 -15
  39. package/tslint.json +0 -18
  40. package/webpack.common.js +0 -44
  41. package/webpack.dev.js +0 -7
  42. package/webpack.prod.js +0 -7
@@ -1,152 +0,0 @@
1
- import {
2
- EnumWebSocketConnectionCommand,
3
- EnumWebSocketConnectionDirection,
4
- WebSocketReply,
5
- EnumWebSocketConnectionStatus,
6
- } from './Types/CommonConnectionTypes';
7
- import WebRtcPeerConnection, { IWebRtcPeerConnectionOptions } from './WebRtcPeerConnection';
8
-
9
- const REPEATER_RETRY_COUNTER = 10;
10
-
11
- export class WebRtcInputConnection extends WebRtcPeerConnection {
12
- protected connectionOptions: IWebRtcInputConnection;
13
- private _peerConnectionConfig?: RTCConfiguration = undefined;
14
- private _repeaterRetryCount = 0;
15
- private _stream: MediaStream | undefined;
16
-
17
- constructor(connectionOptions: IWebRtcInputConnection) {
18
- super(connectionOptions);
19
-
20
- this.connectionOptions = connectionOptions;
21
- this.onRtcDescription = this.onRtcDescription.bind(this);
22
- this.onWsOpen = this.onWsOpen.bind(this);
23
- this.onWsMessage = this.onWsMessage.bind(this);
24
- this.onError = this.onError.bind(this);
25
- this.onRemoteTrack = this.onRemoteTrack.bind(this);
26
- }
27
-
28
- protected onRtcDescription(description: RTCSessionDescriptionInit) {
29
- if (!this.peerConnection) {
30
- return this.onError(new Error('RTC got description, but no RTC'));
31
- }
32
- this.peerConnection
33
- .setLocalDescription(description)
34
- .then(() =>
35
- this.sendResponse(
36
- EnumWebSocketConnectionDirection.PLAY,
37
- EnumWebSocketConnectionCommand.SEND_RESPONSE,
38
- description
39
- )
40
- )
41
- .catch(this.onError);
42
- }
43
-
44
- protected onRemoteTrack(event: RTCTrackEvent): void {
45
- try {
46
- this._stream = event.streams[0];
47
- this.connectionOptions.onTrack!(event.track.kind);
48
- if (this.connectionOptions.videoElement) {
49
- this.connectionOptions.videoElement.srcObject = event.streams[0];
50
- }
51
- } catch (error) {
52
- this.onError(new Error(JSON.stringify(error ? error : '')));
53
- }
54
- }
55
-
56
- protected onWsOpen(): void {
57
- this.peerConnection = new RTCPeerConnection(this._peerConnectionConfig);
58
- this.peerConnection.ontrack = this.onRemoteTrack;
59
-
60
- this.sendResponse(
61
- EnumWebSocketConnectionDirection.PLAY,
62
- EnumWebSocketConnectionCommand.GET_OFFER
63
- );
64
- }
65
-
66
- protected onWsMessage(evt: MessageEvent) {
67
- const msgJson: WebSocketReply = JSON.parse(evt.data);
68
- const msgStatus = parseInt(msgJson.status, 10);
69
-
70
- if (msgStatus !== EnumWebSocketConnectionStatus.OK) {
71
- this._repeaterRetryCount++;
72
-
73
- if (this._repeaterRetryCount < REPEATER_RETRY_COUNTER) {
74
- setTimeout(
75
- () =>
76
- this.sendResponse(
77
- EnumWebSocketConnectionDirection.PLAY,
78
- EnumWebSocketConnectionCommand.GET_OFFER
79
- ),
80
- this.connectionOptions.debounceTime
81
- );
82
- } else {
83
- this.onError(
84
- new Error('Live stream repeater timeout: ' + this.connectionOptions.streamInfo.streamName)
85
- );
86
- this.stop();
87
- }
88
- } else {
89
- const sdpData = msgJson.sdp;
90
- const streamInfoResponse = msgJson.streamInfo;
91
-
92
- if (streamInfoResponse !== undefined) {
93
- this.connectionOptions.streamInfo.sessionId = streamInfoResponse.sessionId;
94
- }
95
-
96
- if (sdpData && this.peerConnection) {
97
- this.peerConnection
98
- .setRemoteDescription(new RTCSessionDescription(sdpData))
99
- .then(() => {
100
- if (this.peerConnection !== undefined) {
101
- return this.peerConnection
102
- .createAnswer()
103
- .then((description: RTCSessionDescriptionInit) =>
104
- this.onRtcDescription(description)
105
- )
106
- .catch(this.onError);
107
- }
108
- })
109
- .catch(this.onError);
110
- }
111
-
112
- const iceCandidates: RTCIceCandidateInit[] = msgJson.iceCandidates;
113
-
114
- if (iceCandidates?.length > 0 && this.peerConnection) {
115
- for (const iceCandidate of iceCandidates) {
116
- this.peerConnection
117
- .addIceCandidate(new RTCIceCandidate(iceCandidate))
118
- .catch(this.onError);
119
- }
120
- }
121
- }
122
-
123
- if (this.wsConnection && 'sendResponse'.localeCompare(msgJson.command) === 0) {
124
- if (this.wsConnection !== null) {
125
- this.wsConnection.close();
126
- }
127
-
128
- this.wsConnection = undefined;
129
- }
130
- }
131
-
132
- public getStream(): MediaStream {
133
- return this._stream;
134
- }
135
-
136
- public start(): void {
137
- super.start();
138
-
139
- this._repeaterRetryCount = 0;
140
-
141
- if (this.wsConnection) {
142
- this.wsConnection.onopen = this.onWsOpen;
143
- this.wsConnection.onmessage = this.onWsMessage;
144
- }
145
- }
146
- }
147
-
148
- export interface IWebRtcInputConnection extends IWebRtcPeerConnectionOptions {
149
- videoElement?: HTMLVideoElement;
150
- onTrack?: (string) => void;
151
- debounceTime: number;
152
- }
@@ -1,153 +0,0 @@
1
- import adapter from 'webrtc-adapter';
2
- import { mungeSdpPublish } from './MungeSdp';
3
- import {
4
- EnumMediaStreamTrackKind,
5
- EnumWebSocketConnectionCommand,
6
- EnumWebSocketConnectionDirection,
7
- EnumWebSocketConnectionStatus,
8
- MediaInfo,
9
- WebSocketReply,
10
- } from './Types/CommonConnectionTypes';
11
- import WebRtcPeerConnection, { IWebRtcPeerConnectionOptions } from './WebRtcPeerConnection';
12
-
13
- export class WebRtcOutputConnection extends WebRtcPeerConnection {
14
- protected connectionOptions: IWebRtcOutputConnection;
15
- protected wsConnection?: WebSocket = undefined;
16
- protected peerConnection?: RTCPeerConnection = undefined;
17
- private peerConnectionConfig?: RTCConfiguration = undefined;
18
- private videoSender?: RTCRtpSender = undefined;
19
- private audioSender?: RTCRtpSender = undefined;
20
-
21
- constructor(connectionOptions: IWebRtcOutputConnection) {
22
- super(connectionOptions);
23
-
24
- this.onError = this.onError.bind(this);
25
- this.onRtcDescription = this.onRtcDescription.bind(this);
26
- this.onWsOpen = this.onWsOpen.bind(this);
27
- this.onWsMessage = this.onWsMessage.bind(this);
28
- this.connectionOptions = connectionOptions;
29
- }
30
-
31
- protected onRtcDescription(description: RTCSessionDescriptionInit) {
32
- if (!this.peerConnection) {
33
- return this.onError(new Error('RTC got description, but no RTC'));
34
- }
35
-
36
- if (description.sdp && adapter.browserDetails.browser !== 'safari') {
37
- description.sdp = mungeSdpPublish(
38
- description.sdp ? description.sdp : '',
39
- this.connectionOptions.mediaInfo
40
- );
41
- }
42
-
43
- this.peerConnection
44
- .setLocalDescription(description)
45
- .then(() => {
46
- this.sendResponse(
47
- EnumWebSocketConnectionDirection.PUBLISH,
48
- EnumWebSocketConnectionCommand.SEND_OFFER,
49
- description
50
- );
51
- })
52
- .catch(this.onError);
53
- }
54
-
55
- protected onWsOpen() {
56
- this.peerConnection = new RTCPeerConnection(this.peerConnectionConfig);
57
- this.videoSender = undefined;
58
- this.audioSender = undefined;
59
-
60
- this.peerConnection.onnegotiationneeded = () => {
61
- if (this.peerConnection) {
62
- this.peerConnection.createOffer().then(this.onRtcDescription, this.onError);
63
- }
64
- };
65
-
66
- const localTracks = this.connectionOptions.localStream.getTracks();
67
-
68
- for (const localTrack of localTracks) {
69
- const sender = this.peerConnection.addTrack(localTrack, this.connectionOptions.localStream);
70
-
71
- if (localTrack.kind === EnumMediaStreamTrackKind.AUDIO) {
72
- this.audioSender = sender;
73
- } else if (localTrack.kind === EnumMediaStreamTrackKind.VIDEO) {
74
- this.videoSender = sender;
75
- }
76
- }
77
- }
78
-
79
- protected onWsMessage(evt: MessageEvent) {
80
- const msgJson: WebSocketReply = JSON.parse(evt.data);
81
- const msgStatus = parseInt(msgJson.status, 10);
82
-
83
- if (msgStatus !== EnumWebSocketConnectionStatus.OK) {
84
- return this.onError(new Error(msgJson.statusDescription));
85
- }
86
-
87
- const sdpData = msgJson.sdp;
88
-
89
- if (sdpData && this.peerConnection) {
90
- this.peerConnection
91
- .setRemoteDescription(new RTCSessionDescription(sdpData))
92
- .catch(this.onError);
93
- }
94
-
95
- const iceCandidates = msgJson.iceCandidates;
96
-
97
- if (iceCandidates !== undefined && this.peerConnection) {
98
- for (const iceCandidate of iceCandidates) {
99
- this.peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate)).catch(this.onError);
100
- }
101
- }
102
- }
103
-
104
- public changeTrack(newTrack: MediaStreamTrack): Promise<void> {
105
- if (!this.wsConnection) {
106
- throw new Error('No connection open');
107
- }
108
-
109
- switch (newTrack.kind) {
110
- case EnumMediaStreamTrackKind.VIDEO: {
111
- if (!this.videoSender) {
112
- throw new Error('No video sender available');
113
- }
114
-
115
- return this.videoSender.replaceTrack(newTrack);
116
- }
117
-
118
- case EnumMediaStreamTrackKind.AUDIO: {
119
- if (!this.videoSender) {
120
- throw new Error('No audio sender available');
121
- }
122
-
123
- return this.audioSender.replaceTrack(newTrack);
124
- }
125
-
126
- default: {
127
- const supported = [EnumMediaStreamTrackKind.VIDEO, EnumMediaStreamTrackKind.AUDIO];
128
- throw new Error(
129
- `Unknown media track kind ${newTrack.kind}. Supported: ${supported.join(',')}'`
130
- );
131
- }
132
- }
133
- }
134
-
135
- public start() {
136
- super.start();
137
- if (this.wsConnection) {
138
- this.wsConnection.onopen = this.onWsOpen;
139
- this.wsConnection.onmessage = this.onWsMessage;
140
- }
141
- }
142
-
143
- public stop() {
144
- super.stop();
145
- this.videoSender = undefined;
146
- this.audioSender = undefined;
147
- }
148
- }
149
-
150
- export interface IWebRtcOutputConnection extends IWebRtcPeerConnectionOptions {
151
- localStream: MediaStream;
152
- mediaInfo: MediaInfo;
153
- }
@@ -1,91 +0,0 @@
1
- import {
2
- OnErrorCallback,
3
- OnStopCallback,
4
- StreamInfo,
5
- EnumWebSocketConnectionCommand,
6
- EnumWebSocketConnectionDirection,
7
- } from './Types/CommonConnectionTypes';
8
-
9
- abstract class WebRtcPeerConnection {
10
- protected wsConnection?: WebSocket = undefined;
11
- protected peerConnection?: RTCPeerConnection = undefined;
12
-
13
- protected abstract onRtcDescription(description: RTCSessionDescriptionInit): void;
14
- protected abstract onWsOpen(): void;
15
- protected abstract onWsMessage(evt: MessageEvent): void;
16
-
17
- protected constructor(protected connectionOptions: IWebRtcPeerConnectionOptions) {
18
- this.connectionOptions = connectionOptions;
19
- this.connectToWebSocket = this.connectToWebSocket.bind(this);
20
- this.onError = this.onError.bind(this);
21
- }
22
-
23
- protected sendResponse(
24
- direction: EnumWebSocketConnectionDirection,
25
- command: EnumWebSocketConnectionCommand,
26
- description?: RTCSessionDescriptionInit
27
- ) {
28
- if (this.wsConnection) {
29
- let json = {
30
- direction: direction,
31
- command: command,
32
- streamInfo: this.connectionOptions.streamInfo,
33
- userData: this.connectionOptions.userData,
34
- };
35
-
36
- if (description !== undefined) {
37
- json = { ...json, ...{ sdp: description } };
38
- }
39
-
40
- this.wsConnection.send(JSON.stringify(json));
41
- }
42
- }
43
-
44
- protected connectToWebSocket() {
45
- this.wsConnection = new WebSocket(this.connectionOptions.wsUrl);
46
- this.wsConnection.binaryType = 'arraybuffer';
47
- this.wsConnection.onerror = () => this.onError(new Error('WsConnection failed'));
48
- }
49
-
50
- protected onError(error: Error) {
51
- this.stop();
52
- this.connectionOptions.onError(error);
53
- }
54
-
55
- public start() {
56
- if (!this.peerConnection) {
57
- if (this.wsConnection) {
58
- this.wsConnection.close();
59
- this.wsConnection = undefined;
60
- }
61
-
62
- this.connectToWebSocket();
63
- }
64
- }
65
-
66
- public stop() {
67
- if (this.peerConnection) {
68
- this.peerConnection.close();
69
- }
70
-
71
- this.peerConnection = undefined;
72
-
73
- if (this.wsConnection) {
74
- this.wsConnection.close();
75
- }
76
-
77
- this.wsConnection = undefined;
78
-
79
- this.connectionOptions.onStop();
80
- }
81
- }
82
-
83
- export interface IWebRtcPeerConnectionOptions {
84
- wsUrl: string;
85
- streamInfo: StreamInfo;
86
- userData?: object;
87
- onStop: OnStopCallback;
88
- onError: OnErrorCallback;
89
- }
90
-
91
- export default WebRtcPeerConnection;
@@ -1,49 +0,0 @@
1
- import adapter from 'webrtc-adapter';
2
- import { EnumCodecContentType } from './Types/EnumCodecContentType';
3
- import { supportsCodec } from './utils';
4
-
5
- export enum EnumAudioCodecs {
6
- OPUS = 'opus',
7
- VORBIS = 'vorbis',
8
- PCMU = 'pcmu',
9
- PCMA = 'pcma',
10
- }
11
-
12
- /** @see CanPlayTypeResult */
13
- export enum EnumMediaCodecSupported {
14
- UNKNOWN = '',
15
- PROBABLY = 'probably',
16
- MAYBE = 'maybe',
17
- }
18
-
19
- export const browserSupportedAudioCodec = (codecs: string[]) => {
20
- const isSafari = adapter.browserDetails.browser === 'safari';
21
-
22
- for (let i = 0; i < codecs.length; i++) {
23
- const codec = codecs[i];
24
-
25
- switch (codec) {
26
- case EnumAudioCodecs.OPUS:
27
- if (
28
- isSafari ||
29
- supportsCodec(EnumCodecContentType.OPUS) === EnumMediaCodecSupported.PROBABLY
30
- ) {
31
- return EnumAudioCodecs.OPUS;
32
- }
33
- break;
34
-
35
- case EnumAudioCodecs.VORBIS:
36
- if (supportsCodec(EnumCodecContentType.VORBIS) === EnumMediaCodecSupported.PROBABLY) {
37
- return EnumAudioCodecs.VORBIS;
38
- }
39
- break;
40
-
41
- // could not find a way to check the support of this codec in the browser
42
- case EnumAudioCodecs.PCMU:
43
- case EnumAudioCodecs.PCMA:
44
- break;
45
- }
46
- }
47
-
48
- return '';
49
- };
@@ -1,39 +0,0 @@
1
- import * as _ from 'lodash';
2
- import { EnumCodecContentType } from './Types/EnumCodecContentType';
3
- import { EnumVideoCodec } from './Types/CommonConnectionTypes';
4
- import { supportsCodec } from './utils';
5
-
6
- export enum EnumVideoCodecs {
7
- H264 = 'h264',
8
- VP9 = 'VP9',
9
- VP8 = 'VP8',
10
- }
11
-
12
- export const browserSupportedVideoCodec = (codecs: string[]) => {
13
- for (let i = 0; i < codecs.length; i++) {
14
- const codec = codecs[i];
15
-
16
- switch (codec) {
17
- case EnumVideoCodecs.H264:
18
- /** @note codec is re-named here on purpose to make Wowza server happy */
19
- if (!_.isEmpty(supportsCodec(EnumCodecContentType.H264))) {
20
- return EnumVideoCodec.H264;
21
- }
22
- break;
23
-
24
- case EnumVideoCodecs.VP9:
25
- if (!_.isEmpty(supportsCodec(EnumCodecContentType.VP9))) {
26
- return EnumVideoCodecs.VP9;
27
- }
28
- break;
29
-
30
- case EnumVideoCodecs.VP8:
31
- if (!_.isEmpty(supportsCodec(EnumCodecContentType.VP8))) {
32
- return EnumVideoCodecs.VP8;
33
- }
34
- break;
35
- }
36
- }
37
-
38
- return '';
39
- };
package/src/utils.ts DELETED
@@ -1,18 +0,0 @@
1
- import * as _ from 'lodash';
2
- import { EnumCodecContentType } from './Types/EnumCodecContentType';
3
-
4
- export enum EnumSupportedMediaType {
5
- VIDEO = 'video',
6
- AUDIO = 'audio',
7
- }
8
-
9
- export const supportsCodec = (codecType: EnumCodecContentType): CanPlayTypeResult => {
10
- const mediaType = codecType.split('/');
11
-
12
- if (!_.includes(Object.values(EnumSupportedMediaType), mediaType[0])) {
13
- return '';
14
- }
15
-
16
- const v = window.document.createElement(mediaType[0]) as HTMLMediaElement;
17
- return v.canPlayType(codecType);
18
- };
package/src/version.ts DELETED
@@ -1 +0,0 @@
1
- export const VERSION = '__VERSION__';
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "lib": ["dom", "es5", "scripthost", "ES2015", "es2016.array.include"],
4
- "target": "es5",
5
- "moduleResolution": "node",
6
- "sourceMap": true,
7
- "declaration": true,
8
- "newLine": "LF",
9
- "outDir": "./dist",
10
- "rootDirs": ["src"],
11
- "allowJs": true
12
- },
13
- "include": ["src/**/*"],
14
- "exclude": ["node_modules", "**/*.spec.ts"]
15
- }
package/tslint.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "defaultSeverity": "warning",
3
- "extends": [
4
- "tslint:recommended"
5
- ],
6
- "jsRules": {},
7
- "rules": {
8
- "interface-name": [false],
9
- "max-line-length": [false],
10
- "no-empty": [false],
11
- "object-literal-shorthand": [false],
12
- "object-literal-sort-keys": [true, "match-declaration-order"],
13
- "quotemark": [true, "single", "avoid-escape", "avoid-template"],
14
- "trailing-comma": [true, {"multiline": "never", "singleline": "never"}],
15
- "variable-name": { "options": [ "check-format", "allow-leading-underscore", "allow-pascal-case", "ban-keywords" ] }
16
- },
17
- "rulesDirectory": []
18
- }
package/webpack.common.js DELETED
@@ -1,44 +0,0 @@
1
- const path = require('path');
2
- const { CleanWebpackPlugin } = require('clean-webpack-plugin');
3
- const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin');
4
- const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
5
-
6
- module.exports = {
7
- entry: {
8
- 'vxwebrtc': './src/vxwebrtc.ts',
9
- },
10
- plugins: [
11
- new CleanWebpackPlugin(),
12
- new DuplicatePackageCheckerPlugin(),
13
- new BundleAnalyzerPlugin({
14
- analyzerMode: 'disabled',
15
- generateStatsFile: true,
16
- }),
17
- ],
18
- module: {
19
- rules: [
20
- {
21
- test: /version.ts$/,
22
- loader: 'string-replace-loader',
23
- options: {
24
- search: '__VERSION__',
25
- replace: require('./package.json').version,
26
- },
27
- },
28
- {
29
- test: /\.tsx?$/,
30
- use: 'ts-loader',
31
- exclude: /node_modules/,
32
- },
33
- ],
34
- },
35
- resolve: {
36
- extensions: ['.tsx', '.ts', '.js'],
37
- },
38
- output: {
39
- filename: '[name].js',
40
- library: 'vxWebRTC',
41
- libraryTarget: 'umd',
42
- path: path.resolve(__dirname, 'dist')
43
- }
44
- };
package/webpack.dev.js DELETED
@@ -1,7 +0,0 @@
1
- const { merge } = require('webpack-merge');
2
- const common = require('./webpack.common.js');
3
-
4
- module.exports = merge(common, {
5
- mode: 'development',
6
- devtool: 'inline-source-map'
7
- });
package/webpack.prod.js DELETED
@@ -1,7 +0,0 @@
1
- const { merge } = require('webpack-merge');
2
- const common = require('./webpack.common.js');
3
-
4
- module.exports = merge(common, {
5
- mode: 'production',
6
- devtool: 'source-map'
7
- });