@techsee/techsee-media-service 0.1.3
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/README.md +1 -0
- package/lib/constants.js +20 -0
- package/lib/constants.js.map +1 -0
- package/lib/event-emitter.js +39 -0
- package/lib/event-emitter.js.map +1 -0
- package/lib/index.js +64 -0
- package/lib/index.js.map +1 -0
- package/lib/opentok/session.js +304 -0
- package/lib/opentok/session.js.map +1 -0
- package/lib/opentok/stream.js +310 -0
- package/lib/opentok/stream.js.map +1 -0
- package/lib/publisher.js +143 -0
- package/lib/publisher.js.map +1 -0
- package/lib/qos/raw-qos.js +319 -0
- package/lib/qos/raw-qos.js.map +1 -0
- package/lib/service.js +316 -0
- package/lib/service.js.map +1 -0
- package/lib/session.js +104 -0
- package/lib/session.js.map +1 -0
- package/lib/stream.js +195 -0
- package/lib/stream.js.map +1 -0
- package/lib/subscriber.js +90 -0
- package/lib/subscriber.js.map +1 -0
- package/lib/webrtc/constants.js +112 -0
- package/lib/webrtc/constants.js.map +1 -0
- package/lib/webrtc/helper.js +169 -0
- package/lib/webrtc/helper.js.map +1 -0
- package/lib/webrtc/session-kms.js +558 -0
- package/lib/webrtc/session-kms.js.map +1 -0
- package/lib/webrtc/session-loopback.js +340 -0
- package/lib/webrtc/session-loopback.js.map +1 -0
- package/lib/webrtc/session-turn.js +807 -0
- package/lib/webrtc/session-turn.js.map +1 -0
- package/lib/webrtc/session-turn.v2.js +2 -0
- package/lib/webrtc/session-turn.v2.js.map +1 -0
- package/lib/webrtc/session.js +40 -0
- package/lib/webrtc/session.js.map +1 -0
- package/lib/webrtc/stream.js +631 -0
- package/lib/webrtc/stream.js.map +1 -0
- package/lib/webrtc/temasys/adapter-loader.js +12 -0
- package/lib/webrtc/temasys/adapter-loader.js.map +1 -0
- package/lib/webrtc/temasys/adapter.js +5861 -0
- package/lib/webrtc/temasys/adapter.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.getHighestResolutionStream = exports.getVideoTrackSettings = exports.getMediaConstraints = exports.FALLBACK_RESOLUTION = exports.POSSIBLE_RESOLUTIONS = exports.CONSTRAINTS_TYPES = undefined;
|
|
5
|
+
|
|
6
|
+
var _service = require('../service');
|
|
7
|
+
|
|
8
|
+
function _resolutionToConstraints(resolution) {
|
|
9
|
+
var _resolution$split = resolution.split('x'),
|
|
10
|
+
width = _resolution$split[0],
|
|
11
|
+
height = _resolution$split[1];
|
|
12
|
+
|
|
13
|
+
return { width: width, height: height };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
var CONSTRAINTS_TYPES = exports.CONSTRAINTS_TYPES = {
|
|
17
|
+
MIN: 'min',
|
|
18
|
+
IDEAL: 'ideal'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
var POSSIBLE_RESOLUTIONS = exports.POSSIBLE_RESOLUTIONS = [
|
|
22
|
+
//'3840x2160', // 4k - disabled since it's an overkill
|
|
23
|
+
'1920x1080', // FHD
|
|
24
|
+
'1280x720' // HD
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// In case all possible resolution fails, we'll attempt to set the highest resolution as ideal
|
|
28
|
+
var FALLBACK_RESOLUTION = exports.FALLBACK_RESOLUTION = POSSIBLE_RESOLUTIONS[0];
|
|
29
|
+
|
|
30
|
+
function _constraintByType(value, type) {
|
|
31
|
+
switch (type) {
|
|
32
|
+
case CONSTRAINTS_TYPES.MIN:
|
|
33
|
+
return { min: value };
|
|
34
|
+
default:
|
|
35
|
+
return { ideal: value };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var getMediaConstraints = exports.getMediaConstraints = function getMediaConstraints(_ref) {
|
|
40
|
+
var resolution = _ref.resolution,
|
|
41
|
+
deviceOpts = _ref.deviceOpts,
|
|
42
|
+
constraintType = _ref.constraintType;
|
|
43
|
+
return _service.TsMediaService.getDevices().then(function (devices) {
|
|
44
|
+
var groupedDevices = {
|
|
45
|
+
video: _.filter(devices, function (device) {
|
|
46
|
+
return device.kind.toLowerCase() === 'videoinput';
|
|
47
|
+
}),
|
|
48
|
+
audio: _.filter(devices, function (device) {
|
|
49
|
+
return device.kind.toLowerCase() === 'audioinput';
|
|
50
|
+
})
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
var videoDevice = deviceOpts.video && _.last(groupedDevices.video);
|
|
54
|
+
var audioDevice = deviceOpts.audio && _.last(groupedDevices.audio);
|
|
55
|
+
|
|
56
|
+
var mediaConstraints = {};
|
|
57
|
+
|
|
58
|
+
if (videoDevice) {
|
|
59
|
+
var videoResolution = _resolutionToConstraints(resolution);
|
|
60
|
+
|
|
61
|
+
_.assign(mediaConstraints, {
|
|
62
|
+
video: {
|
|
63
|
+
deviceId: videoDevice.deviceId,
|
|
64
|
+
width: _constraintByType(videoResolution.width, constraintType),
|
|
65
|
+
height: _constraintByType(videoResolution.height, constraintType),
|
|
66
|
+
facingMode: 'environment',
|
|
67
|
+
frameRate: { ideal: 15, max: 30 }
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (audioDevice) {
|
|
73
|
+
_.assign(mediaConstraints, {
|
|
74
|
+
audio: { deviceId: audioDevice.deviceId }
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return mediaConstraints;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
var getVideoTrackSettings = exports.getVideoTrackSettings = function getVideoTrackSettings(stream) {
|
|
83
|
+
var videoTracks = stream.getTracks().filter(function (track) {
|
|
84
|
+
return track.kind === 'video';
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (_.isEmpty(videoTracks)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var videoTrack = videoTracks[0];
|
|
92
|
+
|
|
93
|
+
return videoTrack.getSettings && videoTrack.getSettings();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
function _constraintsByResolution(resolution, deviceOpts, constraintType) {
|
|
97
|
+
return getMediaConstraints({
|
|
98
|
+
resolution: resolution,
|
|
99
|
+
deviceOpts: deviceOpts,
|
|
100
|
+
constraintType: constraintType
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function _handleGetUserMediaError(error) {
|
|
105
|
+
var errorName = _.get(error, 'name');
|
|
106
|
+
|
|
107
|
+
if (errorName === 'NotAllowedError') {
|
|
108
|
+
return { code: 1500, name: 'NotAllowedError' };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (errorName === 'PermissionDismissedError') {
|
|
112
|
+
return { code: 8, name: 'PermissionDismissedError' };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { code: 999, name: errorName || 'UnknownError' };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Scan possible resolutions from high to low, trying to set each as minimal.
|
|
120
|
+
* Eventually, use a fallback as ideal so the browser may decide which to use.
|
|
121
|
+
*
|
|
122
|
+
* @method
|
|
123
|
+
* @param {Object} [deviceOpts] Devices to limit to in the constraints
|
|
124
|
+
* @param {Object} [constraints] Media constraints
|
|
125
|
+
*
|
|
126
|
+
* @returns { Promise }
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
var getHighestResolutionStream = exports.getHighestResolutionStream = function getHighestResolutionStream(deviceOpts, constraints) {
|
|
130
|
+
// In case we had a constraints scan before, return the best
|
|
131
|
+
if (constraints) {
|
|
132
|
+
return _service.TsMediaService.createLocalMediaStream(constraints).then(function (stream) {
|
|
133
|
+
return { stream: stream, constraints: constraints };
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
var successfulConstraintsFound = false;
|
|
138
|
+
|
|
139
|
+
return new Promise(function (resolve, reject) {
|
|
140
|
+
Promise.reduce(POSSIBLE_RESOLUTIONS, function (total, resolution) {
|
|
141
|
+
if (successfulConstraintsFound) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return _constraintsByResolution(resolution, deviceOpts, CONSTRAINTS_TYPES.MIN).then(function (potentialConstraints) {
|
|
146
|
+
return _service.TsMediaService.createLocalMediaStream(potentialConstraints).then(function (stream) {
|
|
147
|
+
successfulConstraintsFound = true;
|
|
148
|
+
|
|
149
|
+
return resolve({ stream: stream, constraints: potentialConstraints });
|
|
150
|
+
});
|
|
151
|
+
}).catch(function () {
|
|
152
|
+
return null;
|
|
153
|
+
});
|
|
154
|
+
}, 0).then(function () {
|
|
155
|
+
if (successfulConstraintsFound) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
_constraintsByResolution(FALLBACK_RESOLUTION, deviceOpts, CONSTRAINTS_TYPES.IDEAL).then(function (potentialConstraints) {
|
|
160
|
+
return _service.TsMediaService.createLocalMediaStream(potentialConstraints).then(function (stream) {
|
|
161
|
+
return resolve({ stream: stream, constraints: potentialConstraints });
|
|
162
|
+
});
|
|
163
|
+
}).catch(function (err) {
|
|
164
|
+
return reject(_handleGetUserMediaError(err));
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["webrtc/helper.js"],"names":["_resolutionToConstraints","resolution","split","width","height","CONSTRAINTS_TYPES","MIN","IDEAL","POSSIBLE_RESOLUTIONS","FALLBACK_RESOLUTION","_constraintByType","value","type","min","ideal","getMediaConstraints","deviceOpts","constraintType","TsMediaService","getDevices","then","devices","groupedDevices","video","_","filter","device","kind","toLowerCase","audio","videoDevice","last","audioDevice","mediaConstraints","videoResolution","assign","deviceId","facingMode","frameRate","max","getVideoTrackSettings","stream","videoTracks","getTracks","track","isEmpty","videoTrack","getSettings","_constraintsByResolution","_handleGetUserMediaError","error","errorName","get","code","name","getHighestResolutionStream","constraints","createLocalMediaStream","successfulConstraintsFound","Promise","resolve","reject","reduce","total","potentialConstraints","catch","err"],"mappings":"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","file":"helper.js","sourcesContent":["import {TsMediaService} from '../service';\n\nfunction _resolutionToConstraints(resolution) {\n const [width, height] = resolution.split('x');\n\n return {width, height};\n}\n\nexport const CONSTRAINTS_TYPES = {\n MIN: 'min',\n IDEAL: 'ideal'\n};\n\nexport const POSSIBLE_RESOLUTIONS = [\n //'3840x2160', // 4k - disabled since it's an overkill\n '1920x1080', // FHD\n '1280x720' // HD\n];\n\n// In case all possible resolution fails, we'll attempt to set the highest resolution as ideal\nexport const FALLBACK_RESOLUTION = POSSIBLE_RESOLUTIONS[0];\n\nfunction _constraintByType(value, type) {\n switch (type) {\n case CONSTRAINTS_TYPES.MIN:\n return {min: value};\n default:\n return {ideal: value};\n }\n}\n\nexport const getMediaConstraints = ({resolution, deviceOpts, constraintType}) =>\n TsMediaService.getDevices()\n .then((devices) => {\n const groupedDevices = {\n video: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'videoinput'),\n audio: _.filter(devices, (device) =>\n device.kind.toLowerCase() === 'audioinput')\n };\n\n const videoDevice = deviceOpts.video && _.last(groupedDevices.video);\n const audioDevice = deviceOpts.audio && _.last(groupedDevices.audio);\n\n const mediaConstraints = {};\n\n if (videoDevice) {\n const videoResolution = _resolutionToConstraints(resolution);\n\n _.assign(mediaConstraints, {\n video: {\n deviceId: videoDevice.deviceId,\n width: _constraintByType(videoResolution.width, constraintType),\n height: _constraintByType(videoResolution.height, constraintType),\n facingMode: 'environment',\n frameRate: {ideal: 15, max: 30}\n }\n });\n }\n\n if (audioDevice) {\n _.assign(mediaConstraints, {\n audio: {deviceId: audioDevice.deviceId}\n });\n }\n\n return mediaConstraints;\n });\n\nexport const getVideoTrackSettings = (stream) => {\n const videoTracks = stream.getTracks()\n .filter((track) => (track.kind === 'video'));\n\n if (_.isEmpty(videoTracks)) {\n return;\n }\n\n const videoTrack = videoTracks[0];\n\n return videoTrack.getSettings && videoTrack.getSettings();\n};\n\nfunction _constraintsByResolution(resolution, deviceOpts, constraintType) {\n return getMediaConstraints({\n resolution: resolution,\n deviceOpts: deviceOpts,\n constraintType: constraintType\n });\n}\n\nfunction _handleGetUserMediaError(error) {\n const errorName = _.get(error, 'name');\n\n if (errorName === 'NotAllowedError') {\n return {code: 1500, name: 'NotAllowedError'};\n }\n\n if (errorName === 'PermissionDismissedError') {\n return {code: 8, name: 'PermissionDismissedError'};\n }\n\n return {code: 999, name: errorName || 'UnknownError'};\n}\n\n/**\n * Scan possible resolutions from high to low, trying to set each as minimal.\n * Eventually, use a fallback as ideal so the browser may decide which to use.\n *\n * @method\n * @param {Object} [deviceOpts] Devices to limit to in the constraints\n * @param {Object} [constraints] Media constraints\n *\n * @returns { Promise }\n *\n */\nexport const getHighestResolutionStream = (deviceOpts, constraints) => {\n // In case we had a constraints scan before, return the best\n if (constraints) {\n return TsMediaService.createLocalMediaStream(constraints)\n .then((stream) => ({stream, constraints}));\n }\n\n let successfulConstraintsFound = false;\n\n return new Promise((resolve, reject) => {\n Promise.reduce(POSSIBLE_RESOLUTIONS, (total, resolution) => {\n if (successfulConstraintsFound) {\n return;\n }\n\n return _constraintsByResolution(resolution, deviceOpts, CONSTRAINTS_TYPES.MIN)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => {\n successfulConstraintsFound = true;\n\n return resolve({stream, constraints: potentialConstraints});\n }))\n .catch(() => null);\n }, 0)\n .then(() => {\n if (successfulConstraintsFound) {\n return;\n }\n\n _constraintsByResolution(FALLBACK_RESOLUTION, deviceOpts, CONSTRAINTS_TYPES.IDEAL)\n .then((potentialConstraints) => TsMediaService.createLocalMediaStream(potentialConstraints)\n .then((stream) => resolve({stream, constraints: potentialConstraints})))\n .catch((err) => reject(_handleGetUserMediaError(err)));\n });\n });\n};\n"]}
|