@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.
- package/dist/MungeSdp.d.ts +2 -0
- package/dist/Types/CodecsOptions.d.ts +8 -0
- package/dist/Types/CommonConnectionTypes.d.ts +48 -0
- package/dist/Types/EnumCodecContentType.d.ts +13 -0
- package/dist/Types/EnumMediaStreamTrackKind.d.ts +4 -0
- package/dist/Types/WebRTCStreamConfig.d.ts +26 -0
- package/dist/WebRtcInputConnection.d.ts +19 -0
- package/dist/WebRtcOutputConnection.d.ts +21 -0
- package/dist/WebRtcPeerConnection.d.ts +23 -0
- package/dist/browserSupportedAudioCodec.d.ts +13 -0
- package/dist/browserSupportedVideoCodec.d.ts +7 -0
- package/dist/stats.json +10371 -0
- package/dist/utils.d.ts +6 -0
- package/dist/version.d.ts +1 -0
- package/{src/vxwebrtc.ts → dist/vxwebrtc.d.ts} +1 -8
- package/dist/vxwebrtc.js +3 -0
- package/dist/vxwebrtc.js.LICENSE.txt +8 -0
- package/dist/vxwebrtc.js.map +1 -0
- package/package.json +4 -1
- package/.eslintignore +0 -1
- package/.eslintrc.js +0 -22
- package/.gitlab-ci.yml +0 -51
- package/.husky/pre-commit +0 -4
- package/.prettierignore +0 -1
- package/src/MungeSdp.ts +0 -323
- package/src/Types/CodecsOptions.ts +0 -9
- package/src/Types/CommonConnectionTypes.ts +0 -57
- package/src/Types/EnumCodecContentType.ts +0 -13
- package/src/Types/EnumMediaStreamTrackKind.ts +0 -4
- package/src/Types/WebRTCStreamConfig.ts +0 -59
- package/src/WebRtcInputConnection.ts +0 -152
- package/src/WebRtcOutputConnection.ts +0 -153
- package/src/WebRtcPeerConnection.ts +0 -91
- package/src/browserSupportedAudioCodec.ts +0 -49
- package/src/browserSupportedVideoCodec.ts +0 -39
- package/src/utils.ts +0 -18
- package/src/version.ts +0 -1
- package/tsconfig.json +0 -15
- package/tslint.json +0 -18
- package/webpack.common.js +0 -44
- package/webpack.dev.js +0 -7
- 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