@livekit/react-native 0.2.2
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/LICENSE +202 -0
- package/README.md +141 -0
- package/android/build.gradle +133 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradle.properties +3 -0
- package/android/gradlew +185 -0
- package/android/gradlew.bat +89 -0
- package/android/local.properties +8 -0
- package/android/src/main/AndroidManifest.xml +13 -0
- package/android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt +50 -0
- package/android/src/main/java/com/livekit/reactnative/LivekitReactNativePackage.kt +17 -0
- package/android/src/main/java/com/livekit/reactnative/audio/AudioDeviceKind.java +40 -0
- package/android/src/main/java/com/livekit/reactnative/audio/AudioSwitchManager.java +140 -0
- package/ios/LivekitReactNative-Bridging-Header.h +2 -0
- package/ios/LivekitReactNative.h +11 -0
- package/ios/LivekitReactNative.m +111 -0
- package/ios/LivekitReactNative.xcodeproj/project.pbxproj +274 -0
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/LivekitReactNative.xcodeproj/project.xcworkspace/xcuserdata/davidliu.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/LivekitReactNative.xcodeproj/xcuserdata/davidliu.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/lib/commonjs/audio/AudioSession.js +80 -0
- package/lib/commonjs/audio/AudioSession.js.map +1 -0
- package/lib/commonjs/components/VideoView.js +165 -0
- package/lib/commonjs/components/VideoView.js.map +1 -0
- package/lib/commonjs/components/ViewPortDetector.js +109 -0
- package/lib/commonjs/components/ViewPortDetector.js.map +1 -0
- package/lib/commonjs/index.js +103 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/useParticipant.js +100 -0
- package/lib/commonjs/useParticipant.js.map +1 -0
- package/lib/commonjs/useRoom.js +137 -0
- package/lib/commonjs/useRoom.js.map +1 -0
- package/lib/module/audio/AudioSession.js +70 -0
- package/lib/module/audio/AudioSession.js.map +1 -0
- package/lib/module/components/VideoView.js +144 -0
- package/lib/module/components/VideoView.js.map +1 -0
- package/lib/module/components/ViewPortDetector.js +97 -0
- package/lib/module/components/ViewPortDetector.js.map +1 -0
- package/lib/module/index.js +45 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/useParticipant.js +91 -0
- package/lib/module/useParticipant.js.map +1 -0
- package/lib/module/useRoom.js +126 -0
- package/lib/module/useRoom.js.map +1 -0
- package/lib/typescript/audio/AudioSession.d.ts +88 -0
- package/lib/typescript/components/VideoView.d.ts +10 -0
- package/lib/typescript/components/ViewPortDetector.d.ts +26 -0
- package/lib/typescript/index.d.ts +12 -0
- package/lib/typescript/useParticipant.d.ts +13 -0
- package/lib/typescript/useRoom.d.ts +20 -0
- package/livekit-react-native.podspec +22 -0
- package/package.json +157 -0
- package/src/audio/AudioSession.ts +132 -0
- package/src/components/VideoView.tsx +143 -0
- package/src/components/ViewPortDetector.tsx +93 -0
- package/src/index.tsx +37 -0
- package/src/useParticipant.ts +144 -0
- package/src/useRoom.ts +163 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
|
|
12
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
13
|
+
|
|
14
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
+
|
|
16
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
17
|
+
|
|
18
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Detects when this is in the viewport and visible.
|
|
22
|
+
*
|
|
23
|
+
* Will not fire visibility changes for zero width/height components.
|
|
24
|
+
*/
|
|
25
|
+
class ViewPortDetector extends _react.Component {
|
|
26
|
+
constructor(props) {
|
|
27
|
+
super(props);
|
|
28
|
+
|
|
29
|
+
_defineProperty(this, "lastValue", null);
|
|
30
|
+
|
|
31
|
+
_defineProperty(this, "interval", null);
|
|
32
|
+
|
|
33
|
+
_defineProperty(this, "view", null);
|
|
34
|
+
|
|
35
|
+
this.state = {
|
|
36
|
+
rectTop: 0,
|
|
37
|
+
rectBottom: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
componentDidMount() {
|
|
42
|
+
if (!this.props.disabled) {
|
|
43
|
+
this.startWatching();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
componentWillUnmount() {
|
|
48
|
+
this.stopWatching();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
52
|
+
if (nextProps.disabled) {
|
|
53
|
+
this.stopWatching();
|
|
54
|
+
} else {
|
|
55
|
+
this.lastValue = null;
|
|
56
|
+
this.startWatching();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
startWatching() {
|
|
61
|
+
if (this.interval) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.interval = setInterval(() => {
|
|
66
|
+
if (!this.view) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.view.measure((_x, _y, width, height, _pageX, _pageY) => {
|
|
71
|
+
this.checkInViewPort(width, height);
|
|
72
|
+
});
|
|
73
|
+
}, this.props.delay || 100);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
stopWatching() {
|
|
77
|
+
this.interval = clearInterval(this.interval);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
checkInViewPort(width, height) {
|
|
81
|
+
let isVisible; // Not visible if any of these are missing.
|
|
82
|
+
|
|
83
|
+
if (!width || !height) {
|
|
84
|
+
isVisible = false;
|
|
85
|
+
} else {
|
|
86
|
+
isVisible = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (this.lastValue !== isVisible) {
|
|
90
|
+
var _this$props$onChange, _this$props;
|
|
91
|
+
|
|
92
|
+
this.lastValue = isVisible;
|
|
93
|
+
(_this$props$onChange = (_this$props = this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props, isVisible);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
render() {
|
|
98
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, _extends({
|
|
99
|
+
collapsable: false,
|
|
100
|
+
ref: component => {
|
|
101
|
+
this.view = component;
|
|
102
|
+
}
|
|
103
|
+
}, this.props), this.props.children);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
exports.default = ViewPortDetector;
|
|
109
|
+
//# sourceMappingURL=ViewPortDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["ViewPortDetector.tsx"],"names":["ViewPortDetector","Component","constructor","props","state","rectTop","rectBottom","componentDidMount","disabled","startWatching","componentWillUnmount","stopWatching","UNSAFE_componentWillReceiveProps","nextProps","lastValue","interval","setInterval","view","measure","_x","_y","width","height","_pageX","_pageY","checkInViewPort","delay","clearInterval","isVisible","onChange","render","component","children"],"mappings":"AAAA;;;;;;;AAEA;;AACA;;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACe,MAAMA,gBAAN,SAA+BC,gBAA/B,CAAgD;AAK7DC,EAAAA,WAAW,CAACC,KAAD,EAAe;AACxB,UAAMA,KAAN;;AADwB,uCAJU,IAIV;;AAAA,sCAHK,IAGL;;AAAA,kCAFE,IAEF;;AAExB,SAAKC,KAAL,GAAa;AAAEC,MAAAA,OAAO,EAAE,CAAX;AAAcC,MAAAA,UAAU,EAAE;AAA1B,KAAb;AACD;;AAEDC,EAAAA,iBAAiB,GAAG;AAClB,QAAI,CAAC,KAAKJ,KAAL,CAAWK,QAAhB,EAA0B;AACxB,WAAKC,aAAL;AACD;AACF;;AAEDC,EAAAA,oBAAoB,GAAG;AACrB,SAAKC,YAAL;AACD;;AAEDC,EAAAA,gCAAgC,CAACC,SAAD,EAAmB;AACjD,QAAIA,SAAS,CAACL,QAAd,EAAwB;AACtB,WAAKG,YAAL;AACD,KAFD,MAEO;AACL,WAAKG,SAAL,GAAiB,IAAjB;AACA,WAAKL,aAAL;AACD;AACF;;AAEOA,EAAAA,aAAa,GAAG;AACtB,QAAI,KAAKM,QAAT,EAAmB;AACjB;AACD;;AACD,SAAKA,QAAL,GAAgBC,WAAW,CAAC,MAAM;AAChC,UAAI,CAAC,KAAKC,IAAV,EAAgB;AACd;AACD;;AACD,WAAKA,IAAL,CAAUC,OAAV,CAAkB,CAACC,EAAD,EAAKC,EAAL,EAASC,KAAT,EAAgBC,MAAhB,EAAwBC,MAAxB,EAAgCC,MAAhC,KAA2C;AAC3D,aAAKC,eAAL,CAAqBJ,KAArB,EAA4BC,MAA5B;AACD,OAFD;AAGD,KAP0B,EAOxB,KAAKnB,KAAL,CAAWuB,KAAX,IAAoB,GAPI,CAA3B;AAQD;;AAEOf,EAAAA,YAAY,GAAG;AACrB,SAAKI,QAAL,GAAgBY,aAAa,CAAC,KAAKZ,QAAN,CAA7B;AACD;;AAEOU,EAAAA,eAAe,CAACJ,KAAD,EAAiBC,MAAjB,EAAkC;AACvD,QAAIM,SAAJ,CADuD,CAEvD;;AACA,QAAI,CAACP,KAAD,IAAU,CAACC,MAAf,EAAuB;AACrBM,MAAAA,SAAS,GAAG,KAAZ;AACD,KAFD,MAEO;AACLA,MAAAA,SAAS,GAAG,IAAZ;AACD;;AAED,QAAI,KAAKd,SAAL,KAAmBc,SAAvB,EAAkC;AAAA;;AAChC,WAAKd,SAAL,GAAiBc,SAAjB;AACA,kDAAKzB,KAAL,EAAW0B,QAAX,gGAAsBD,SAAtB;AACD;AACF;;AAEDE,EAAAA,MAAM,GAAG;AACP,wBACE,6BAAC,iBAAD;AACE,MAAA,WAAW,EAAE,KADf;AAEE,MAAA,GAAG,EAAGC,SAAD,IAAe;AAClB,aAAKd,IAAL,GAAYc,SAAZ;AACD;AAJH,OAKM,KAAK5B,KALX,GAOG,KAAKA,KAAL,CAAW6B,QAPd,CADF;AAWD;;AA1E4D","sourcesContent":["'use strict';\n\nimport React, { Component } from 'react';\nimport { View, ViewStyle } from 'react-native';\n\nexport type Props = {\n disabled?: boolean;\n style?: ViewStyle;\n onChange?: (isVisible: boolean) => void;\n delay?: number;\n};\n\n/**\n * Detects when this is in the viewport and visible.\n *\n * Will not fire visibility changes for zero width/height components.\n */\nexport default class ViewPortDetector extends Component<Props> {\n private lastValue: boolean | null = null;\n private interval: any | null = null;\n private view: View | null = null;\n\n constructor(props: Props) {\n super(props);\n this.state = { rectTop: 0, rectBottom: 0 };\n }\n\n componentDidMount() {\n if (!this.props.disabled) {\n this.startWatching();\n }\n }\n\n componentWillUnmount() {\n this.stopWatching();\n }\n\n UNSAFE_componentWillReceiveProps(nextProps: Props) {\n if (nextProps.disabled) {\n this.stopWatching();\n } else {\n this.lastValue = null;\n this.startWatching();\n }\n }\n\n private startWatching() {\n if (this.interval) {\n return;\n }\n this.interval = setInterval(() => {\n if (!this.view) {\n return;\n }\n this.view.measure((_x, _y, width, height, _pageX, _pageY) => {\n this.checkInViewPort(width, height);\n });\n }, this.props.delay || 100);\n }\n\n private stopWatching() {\n this.interval = clearInterval(this.interval);\n }\n\n private checkInViewPort(width?: number, height?: number) {\n let isVisible: boolean;\n // Not visible if any of these are missing.\n if (!width || !height) {\n isVisible = false;\n } else {\n isVisible = true;\n }\n\n if (this.lastValue !== isVisible) {\n this.lastValue = isVisible;\n this.props.onChange?.(isVisible);\n }\n }\n\n render() {\n return (\n <View\n collapsable={false}\n ref={(component) => {\n this.view = component;\n }}\n {...this.props}\n >\n {this.props.children}\n </View>\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
registerGlobals: true,
|
|
8
|
+
AudioSession: true
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "AudioSession", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _AudioSession.default;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
exports.registerGlobals = registerGlobals;
|
|
17
|
+
|
|
18
|
+
var _reactNativeWebrtc = require("react-native-webrtc");
|
|
19
|
+
|
|
20
|
+
var _reactNativeUrlPolyfill = require("react-native-url-polyfill");
|
|
21
|
+
|
|
22
|
+
var _AudioSession = _interopRequireDefault(require("./audio/AudioSession"));
|
|
23
|
+
|
|
24
|
+
var _VideoView = require("./components/VideoView");
|
|
25
|
+
|
|
26
|
+
Object.keys(_VideoView).forEach(function (key) {
|
|
27
|
+
if (key === "default" || key === "__esModule") return;
|
|
28
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
29
|
+
if (key in exports && exports[key] === _VideoView[key]) return;
|
|
30
|
+
Object.defineProperty(exports, key, {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _VideoView[key];
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
var _useParticipant = require("./useParticipant");
|
|
39
|
+
|
|
40
|
+
Object.keys(_useParticipant).forEach(function (key) {
|
|
41
|
+
if (key === "default" || key === "__esModule") return;
|
|
42
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
43
|
+
if (key in exports && exports[key] === _useParticipant[key]) return;
|
|
44
|
+
Object.defineProperty(exports, key, {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function () {
|
|
47
|
+
return _useParticipant[key];
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
var _useRoom = require("./useRoom");
|
|
53
|
+
|
|
54
|
+
Object.keys(_useRoom).forEach(function (key) {
|
|
55
|
+
if (key === "default" || key === "__esModule") return;
|
|
56
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
57
|
+
if (key in exports && exports[key] === _useRoom[key]) return;
|
|
58
|
+
Object.defineProperty(exports, key, {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: function () {
|
|
61
|
+
return _useRoom[key];
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Registers the required globals needed for LiveKit to work.
|
|
70
|
+
*
|
|
71
|
+
* Must be called before using LiveKit.
|
|
72
|
+
*/
|
|
73
|
+
function registerGlobals() {
|
|
74
|
+
(0, _reactNativeWebrtc.registerGlobals)();
|
|
75
|
+
(0, _reactNativeUrlPolyfill.setupURLPolyfill)();
|
|
76
|
+
fixWebrtcAdapter();
|
|
77
|
+
shimPromiseAllSettled();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function fixWebrtcAdapter() {
|
|
81
|
+
var _window;
|
|
82
|
+
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
if (((_window = window) === null || _window === void 0 ? void 0 : _window.navigator) !== undefined) {
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
const {
|
|
87
|
+
navigator
|
|
88
|
+
} = window;
|
|
89
|
+
|
|
90
|
+
if (navigator.userAgent === undefined) {
|
|
91
|
+
var _navigator$product;
|
|
92
|
+
|
|
93
|
+
navigator.userAgent = (_navigator$product = navigator.product) !== null && _navigator$product !== void 0 ? _navigator$product : 'Unknown';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function shimPromiseAllSettled() {
|
|
99
|
+
var allSettled = require('promise.allsettled');
|
|
100
|
+
|
|
101
|
+
allSettled.shim();
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["index.tsx"],"names":["registerGlobals","fixWebrtcAdapter","shimPromiseAllSettled","window","navigator","undefined","userAgent","product","allSettled","require","shim"],"mappings":";;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AA+BA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AA9BA;AACA;AACA;AACA;AACA;AACO,SAASA,eAAT,GAA2B;AAChC;AACA;AACAC,EAAAA,gBAAgB;AAChBC,EAAAA,qBAAqB;AACtB;;AAED,SAASD,gBAAT,GAA4B;AAAA;;AAC1B;AACA,MAAI,YAAAE,MAAM,UAAN,0CAAQC,SAAR,MAAsBC,SAA1B,EAAqC;AACnC;AACA,UAAM;AAAED,MAAAA;AAAF,QAAgBD,MAAtB;;AACA,QAAIC,SAAS,CAACE,SAAV,KAAwBD,SAA5B,EAAuC;AAAA;;AACrCD,MAAAA,SAAS,CAACE,SAAV,yBAAsBF,SAAS,CAACG,OAAhC,mEAA2C,SAA3C;AACD;AACF;AACF;;AAED,SAASL,qBAAT,GAAiC;AAC/B,MAAIM,UAAU,GAAGC,OAAO,CAAC,oBAAD,CAAxB;;AACAD,EAAAA,UAAU,CAACE,IAAX;AACD","sourcesContent":["import { registerGlobals as webrtcRegisterGlobals } from 'react-native-webrtc';\nimport { setupURLPolyfill } from 'react-native-url-polyfill';\nimport AudioSession from './audio/AudioSession';\nimport type { AudioConfiguration } from './audio/AudioSession';\n\n/**\n * Registers the required globals needed for LiveKit to work.\n *\n * Must be called before using LiveKit.\n */\nexport function registerGlobals() {\n webrtcRegisterGlobals();\n setupURLPolyfill();\n fixWebrtcAdapter();\n shimPromiseAllSettled();\n}\n\nfunction fixWebrtcAdapter() {\n // @ts-ignore\n if (window?.navigator !== undefined) {\n // @ts-ignore\n const { navigator } = window;\n if (navigator.userAgent === undefined) {\n navigator.userAgent = navigator.product ?? 'Unknown';\n }\n }\n}\n\nfunction shimPromiseAllSettled() {\n var allSettled = require('promise.allsettled');\n allSettled.shim();\n}\n\nexport * from './components/VideoView';\nexport * from './useParticipant';\nexport * from './useRoom';\nexport { AudioSession, AudioConfiguration };\n"]}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useParticipant = useParticipant;
|
|
7
|
+
|
|
8
|
+
var _livekitClient = require("livekit-client");
|
|
9
|
+
|
|
10
|
+
var _react = require("react");
|
|
11
|
+
|
|
12
|
+
function useParticipant(participant) {
|
|
13
|
+
const [isAudioMuted, setAudioMuted] = (0, _react.useState)(false);
|
|
14
|
+
const [, setVideoMuted] = (0, _react.useState)(false);
|
|
15
|
+
const [connectionQuality, setConnectionQuality] = (0, _react.useState)(participant.connectionQuality);
|
|
16
|
+
const [isSpeaking, setSpeaking] = (0, _react.useState)(false);
|
|
17
|
+
const [metadata, setMetadata] = (0, _react.useState)();
|
|
18
|
+
const [publications, setPublications] = (0, _react.useState)([]);
|
|
19
|
+
const [subscribedTracks, setSubscribedTracks] = (0, _react.useState)([]);
|
|
20
|
+
const [cameraPublication, setCameraPublication] = (0, _react.useState)(participant.getTrack(_livekitClient.Track.Source.Camera));
|
|
21
|
+
const [microphonePublication, setMicrophonePublication] = (0, _react.useState)(participant.getTrack(_livekitClient.Track.Source.Microphone));
|
|
22
|
+
const [screenSharePublication, setScreenSharePublication] = (0, _react.useState)(participant.getTrack(_livekitClient.Track.Source.ScreenShare));
|
|
23
|
+
(0, _react.useEffect)(() => {
|
|
24
|
+
const onPublicationsChanged = () => {
|
|
25
|
+
setPublications(Array.from(participant.tracks.values()));
|
|
26
|
+
setCameraPublication(participant.getTrack(_livekitClient.Track.Source.Camera));
|
|
27
|
+
setMicrophonePublication(participant.getTrack(_livekitClient.Track.Source.Microphone));
|
|
28
|
+
setScreenSharePublication(participant.getTrack(_livekitClient.Track.Source.ScreenShare));
|
|
29
|
+
setSubscribedTracks(Array.from(participant.tracks.values()).filter(pub => {
|
|
30
|
+
return pub.isSubscribed && pub.track !== undefined;
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const onMuted = pub => {
|
|
35
|
+
if (pub.kind === _livekitClient.Track.Kind.Audio) {
|
|
36
|
+
setAudioMuted(true);
|
|
37
|
+
} else if (pub.kind === _livekitClient.Track.Kind.Video) {
|
|
38
|
+
setVideoMuted(true);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const onUnmuted = pub => {
|
|
43
|
+
if (pub.kind === _livekitClient.Track.Kind.Audio) {
|
|
44
|
+
setAudioMuted(false);
|
|
45
|
+
} else if (pub.kind === _livekitClient.Track.Kind.Video) {
|
|
46
|
+
setVideoMuted(false);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const onMetadataChanged = () => {
|
|
51
|
+
if (participant.metadata) {
|
|
52
|
+
setMetadata(participant.metadata);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const onIsSpeakingChanged = () => {
|
|
57
|
+
setSpeaking(participant.isSpeaking);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const onConnectionQualityUpdate = () => {
|
|
61
|
+
setConnectionQuality(participant.connectionQuality);
|
|
62
|
+
}; // register listeners
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
participant.on(_livekitClient.ParticipantEvent.TrackMuted, onMuted).on(_livekitClient.ParticipantEvent.TrackUnmuted, onUnmuted).on(_livekitClient.ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged).on(_livekitClient.ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged).on(_livekitClient.ParticipantEvent.TrackPublished, onPublicationsChanged).on(_livekitClient.ParticipantEvent.TrackUnpublished, onPublicationsChanged).on(_livekitClient.ParticipantEvent.TrackSubscribed, onPublicationsChanged).on(_livekitClient.ParticipantEvent.TrackUnsubscribed, onPublicationsChanged).on(_livekitClient.ParticipantEvent.LocalTrackPublished, onPublicationsChanged).on(_livekitClient.ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged).on(_livekitClient.ParticipantEvent.ConnectionQualityChanged, onConnectionQualityUpdate); // set initial state
|
|
66
|
+
|
|
67
|
+
onMetadataChanged();
|
|
68
|
+
onIsSpeakingChanged();
|
|
69
|
+
onPublicationsChanged();
|
|
70
|
+
return () => {
|
|
71
|
+
// cleanup
|
|
72
|
+
participant.off(_livekitClient.ParticipantEvent.TrackMuted, onMuted).off(_livekitClient.ParticipantEvent.TrackUnmuted, onUnmuted).off(_livekitClient.ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged).off(_livekitClient.ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged).off(_livekitClient.ParticipantEvent.TrackPublished, onPublicationsChanged).off(_livekitClient.ParticipantEvent.TrackUnpublished, onPublicationsChanged).off(_livekitClient.ParticipantEvent.TrackSubscribed, onPublicationsChanged).off(_livekitClient.ParticipantEvent.TrackUnsubscribed, onPublicationsChanged).off(_livekitClient.ParticipantEvent.LocalTrackPublished, onPublicationsChanged).off(_livekitClient.ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged).off(_livekitClient.ParticipantEvent.ConnectionQualityChanged, onConnectionQualityUpdate);
|
|
73
|
+
};
|
|
74
|
+
}, [participant]);
|
|
75
|
+
let muted;
|
|
76
|
+
participant.audioTracks.forEach(pub => {
|
|
77
|
+
muted = pub.isMuted;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (muted === undefined) {
|
|
81
|
+
muted = true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (isAudioMuted !== muted) {
|
|
85
|
+
setAudioMuted(muted);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
isLocal: participant instanceof _livekitClient.LocalParticipant,
|
|
90
|
+
isSpeaking,
|
|
91
|
+
connectionQuality,
|
|
92
|
+
publications,
|
|
93
|
+
subscribedTracks,
|
|
94
|
+
cameraPublication,
|
|
95
|
+
microphonePublication,
|
|
96
|
+
screenSharePublication,
|
|
97
|
+
metadata
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=useParticipant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["useParticipant.ts"],"names":["useParticipant","participant","isAudioMuted","setAudioMuted","setVideoMuted","connectionQuality","setConnectionQuality","isSpeaking","setSpeaking","metadata","setMetadata","publications","setPublications","subscribedTracks","setSubscribedTracks","cameraPublication","setCameraPublication","getTrack","Track","Source","Camera","microphonePublication","setMicrophonePublication","Microphone","screenSharePublication","setScreenSharePublication","ScreenShare","onPublicationsChanged","Array","from","tracks","values","filter","pub","isSubscribed","track","undefined","onMuted","kind","Kind","Audio","Video","onUnmuted","onMetadataChanged","onIsSpeakingChanged","onConnectionQualityUpdate","on","ParticipantEvent","TrackMuted","TrackUnmuted","ParticipantMetadataChanged","IsSpeakingChanged","TrackPublished","TrackUnpublished","TrackSubscribed","TrackUnsubscribed","LocalTrackPublished","LocalTrackUnpublished","ConnectionQualityChanged","off","muted","audioTracks","forEach","isMuted","isLocal","LocalParticipant"],"mappings":"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","sourcesContent":["import {\n ConnectionQuality,\n LocalParticipant,\n Participant,\n ParticipantEvent,\n Track,\n TrackPublication,\n} from 'livekit-client';\nimport { useEffect, useState } from 'react';\n\nexport interface ParticipantState {\n isSpeaking: boolean;\n connectionQuality: ConnectionQuality;\n isLocal: boolean;\n metadata?: string;\n publications: TrackPublication[];\n subscribedTracks: TrackPublication[];\n cameraPublication?: TrackPublication;\n microphonePublication?: TrackPublication;\n screenSharePublication?: TrackPublication;\n}\n\nexport function useParticipant(participant: Participant): ParticipantState {\n const [isAudioMuted, setAudioMuted] = useState(false);\n const [, setVideoMuted] = useState(false);\n const [connectionQuality, setConnectionQuality] = useState<ConnectionQuality>(\n participant.connectionQuality\n );\n const [isSpeaking, setSpeaking] = useState(false);\n const [metadata, setMetadata] = useState<string>();\n const [publications, setPublications] = useState<TrackPublication[]>([]);\n const [subscribedTracks, setSubscribedTracks] = useState<TrackPublication[]>(\n []\n );\n\n const [cameraPublication, setCameraPublication] = useState(\n participant.getTrack(Track.Source.Camera)\n );\n const [microphonePublication, setMicrophonePublication] = useState(\n participant.getTrack(Track.Source.Microphone)\n );\n const [screenSharePublication, setScreenSharePublication] = useState(\n participant.getTrack(Track.Source.ScreenShare)\n );\n useEffect(() => {\n const onPublicationsChanged = () => {\n setPublications(Array.from(participant.tracks.values()));\n setCameraPublication(participant.getTrack(Track.Source.Camera));\n setMicrophonePublication(participant.getTrack(Track.Source.Microphone));\n setScreenSharePublication(participant.getTrack(Track.Source.ScreenShare));\n setSubscribedTracks(\n Array.from(participant.tracks.values()).filter((pub) => {\n return pub.isSubscribed && pub.track !== undefined;\n })\n );\n };\n const onMuted = (pub: TrackPublication) => {\n if (pub.kind === Track.Kind.Audio) {\n setAudioMuted(true);\n } else if (pub.kind === Track.Kind.Video) {\n setVideoMuted(true);\n }\n };\n const onUnmuted = (pub: TrackPublication) => {\n if (pub.kind === Track.Kind.Audio) {\n setAudioMuted(false);\n } else if (pub.kind === Track.Kind.Video) {\n setVideoMuted(false);\n }\n };\n const onMetadataChanged = () => {\n if (participant.metadata) {\n setMetadata(participant.metadata);\n }\n };\n const onIsSpeakingChanged = () => {\n setSpeaking(participant.isSpeaking);\n };\n const onConnectionQualityUpdate = () => {\n setConnectionQuality(participant.connectionQuality);\n };\n\n // register listeners\n participant\n .on(ParticipantEvent.TrackMuted, onMuted)\n .on(ParticipantEvent.TrackUnmuted, onUnmuted)\n .on(ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged)\n .on(ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged)\n .on(ParticipantEvent.TrackPublished, onPublicationsChanged)\n .on(ParticipantEvent.TrackUnpublished, onPublicationsChanged)\n .on(ParticipantEvent.TrackSubscribed, onPublicationsChanged)\n .on(ParticipantEvent.TrackUnsubscribed, onPublicationsChanged)\n .on(ParticipantEvent.LocalTrackPublished, onPublicationsChanged)\n .on(ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged)\n .on(ParticipantEvent.ConnectionQualityChanged, onConnectionQualityUpdate);\n\n // set initial state\n onMetadataChanged();\n onIsSpeakingChanged();\n onPublicationsChanged();\n\n return () => {\n // cleanup\n participant\n .off(ParticipantEvent.TrackMuted, onMuted)\n .off(ParticipantEvent.TrackUnmuted, onUnmuted)\n .off(ParticipantEvent.ParticipantMetadataChanged, onMetadataChanged)\n .off(ParticipantEvent.IsSpeakingChanged, onIsSpeakingChanged)\n .off(ParticipantEvent.TrackPublished, onPublicationsChanged)\n .off(ParticipantEvent.TrackUnpublished, onPublicationsChanged)\n .off(ParticipantEvent.TrackSubscribed, onPublicationsChanged)\n .off(ParticipantEvent.TrackUnsubscribed, onPublicationsChanged)\n .off(ParticipantEvent.LocalTrackPublished, onPublicationsChanged)\n .off(ParticipantEvent.LocalTrackUnpublished, onPublicationsChanged)\n .off(\n ParticipantEvent.ConnectionQualityChanged,\n onConnectionQualityUpdate\n );\n };\n }, [participant]);\n\n let muted: boolean | undefined;\n participant.audioTracks.forEach((pub) => {\n muted = pub.isMuted;\n });\n if (muted === undefined) {\n muted = true;\n }\n if (isAudioMuted !== muted) {\n setAudioMuted(muted);\n }\n\n return {\n isLocal: participant instanceof LocalParticipant,\n isSpeaking,\n connectionQuality,\n publications,\n subscribedTracks,\n cameraPublication,\n microphonePublication,\n screenSharePublication,\n metadata,\n };\n}\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sortParticipants = sortParticipants;
|
|
7
|
+
exports.useRoom = useRoom;
|
|
8
|
+
|
|
9
|
+
var _livekitClient = require("livekit-client");
|
|
10
|
+
|
|
11
|
+
var _react = require("react");
|
|
12
|
+
|
|
13
|
+
function useRoom(room, options) {
|
|
14
|
+
var _options$sortParticip;
|
|
15
|
+
|
|
16
|
+
const [error] = (0, _react.useState)();
|
|
17
|
+
const [participants, setParticipants] = (0, _react.useState)([]);
|
|
18
|
+
const [audioTracks, setAudioTracks] = (0, _react.useState)([]);
|
|
19
|
+
const sortFunc = (_options$sortParticip = options === null || options === void 0 ? void 0 : options.sortParticipants) !== null && _options$sortParticip !== void 0 ? _options$sortParticip : sortParticipants;
|
|
20
|
+
(0, _react.useEffect)(() => {
|
|
21
|
+
const onParticipantsChanged = () => {
|
|
22
|
+
const remotes = Array.from(room.participants.values());
|
|
23
|
+
const newParticipants = [room.localParticipant];
|
|
24
|
+
newParticipants.push(...remotes);
|
|
25
|
+
sortFunc(newParticipants, room.localParticipant);
|
|
26
|
+
setParticipants(newParticipants);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const onSubscribedTrackChanged = track => {
|
|
30
|
+
// ordering may have changed, re-sort
|
|
31
|
+
onParticipantsChanged();
|
|
32
|
+
|
|
33
|
+
if (track && track.kind !== _livekitClient.Track.Kind.Audio) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const tracks = [];
|
|
38
|
+
room.participants.forEach(p => {
|
|
39
|
+
p.audioTracks.forEach(pub => {
|
|
40
|
+
if (pub.audioTrack) {
|
|
41
|
+
tracks.push(pub.audioTrack);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
setAudioTracks(tracks);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const onConnectionStateChanged = state => {
|
|
49
|
+
if (state === _livekitClient.ConnectionState.Connected) {
|
|
50
|
+
onParticipantsChanged();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
room.once(_livekitClient.RoomEvent.Disconnected, () => {
|
|
55
|
+
room.off(_livekitClient.RoomEvent.ParticipantConnected, onParticipantsChanged).off(_livekitClient.RoomEvent.ParticipantDisconnected, onParticipantsChanged).off(_livekitClient.RoomEvent.ActiveSpeakersChanged, onParticipantsChanged).off(_livekitClient.RoomEvent.TrackSubscribed, onSubscribedTrackChanged).off(_livekitClient.RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged).off(_livekitClient.RoomEvent.LocalTrackPublished, onParticipantsChanged).off(_livekitClient.RoomEvent.LocalTrackUnpublished, onParticipantsChanged).off(_livekitClient.RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged).off(_livekitClient.RoomEvent.ConnectionStateChanged, onConnectionStateChanged);
|
|
56
|
+
});
|
|
57
|
+
room.on(_livekitClient.RoomEvent.ConnectionStateChanged, onConnectionStateChanged).on(_livekitClient.RoomEvent.Reconnected, onParticipantsChanged).on(_livekitClient.RoomEvent.ParticipantConnected, onParticipantsChanged).on(_livekitClient.RoomEvent.ParticipantDisconnected, onParticipantsChanged).on(_livekitClient.RoomEvent.ActiveSpeakersChanged, onParticipantsChanged).on(_livekitClient.RoomEvent.TrackSubscribed, onSubscribedTrackChanged).on(_livekitClient.RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged).on(_livekitClient.RoomEvent.LocalTrackPublished, onParticipantsChanged).on(_livekitClient.RoomEvent.LocalTrackUnpublished, onParticipantsChanged) // trigger a state change by re-sorting participants
|
|
58
|
+
.on(_livekitClient.RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged);
|
|
59
|
+
onSubscribedTrackChanged();
|
|
60
|
+
return () => {
|
|
61
|
+
room.disconnect();
|
|
62
|
+
};
|
|
63
|
+
}, [room, sortFunc]);
|
|
64
|
+
return {
|
|
65
|
+
error,
|
|
66
|
+
participants,
|
|
67
|
+
audioTracks
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Default sort for participants, it'll order participants by:
|
|
72
|
+
* 1. dominant speaker (speaker with the loudest audio level)
|
|
73
|
+
* 2. local participant
|
|
74
|
+
* 3. other speakers that are recently active
|
|
75
|
+
* 4. participants with video on
|
|
76
|
+
* 5. by joinedAt
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
function sortParticipants(participants, localParticipant) {
|
|
81
|
+
participants.sort((a, b) => {
|
|
82
|
+
var _a$joinedAt$getTime, _a$joinedAt, _b$joinedAt$getTime, _b$joinedAt;
|
|
83
|
+
|
|
84
|
+
// loudest speaker first
|
|
85
|
+
if (a.isSpeaking && b.isSpeaking) {
|
|
86
|
+
return b.audioLevel - a.audioLevel;
|
|
87
|
+
} // speaker goes first
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if (a.isSpeaking !== b.isSpeaking) {
|
|
91
|
+
if (a.isSpeaking) {
|
|
92
|
+
return -1;
|
|
93
|
+
} else {
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
} // last active speaker first
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if (a.lastSpokeAt !== b.lastSpokeAt) {
|
|
100
|
+
var _a$lastSpokeAt$getTim, _a$lastSpokeAt, _b$lastSpokeAt$getTim, _b$lastSpokeAt;
|
|
101
|
+
|
|
102
|
+
const aLast = (_a$lastSpokeAt$getTim = (_a$lastSpokeAt = a.lastSpokeAt) === null || _a$lastSpokeAt === void 0 ? void 0 : _a$lastSpokeAt.getTime()) !== null && _a$lastSpokeAt$getTim !== void 0 ? _a$lastSpokeAt$getTim : 0;
|
|
103
|
+
const bLast = (_b$lastSpokeAt$getTim = (_b$lastSpokeAt = b.lastSpokeAt) === null || _b$lastSpokeAt === void 0 ? void 0 : _b$lastSpokeAt.getTime()) !== null && _b$lastSpokeAt$getTim !== void 0 ? _b$lastSpokeAt$getTim : 0;
|
|
104
|
+
return bLast - aLast;
|
|
105
|
+
} // video on
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
const aVideo = a.videoTracks.size > 0;
|
|
109
|
+
const bVideo = b.videoTracks.size > 0;
|
|
110
|
+
|
|
111
|
+
if (aVideo !== bVideo) {
|
|
112
|
+
if (aVideo) {
|
|
113
|
+
return -1;
|
|
114
|
+
} else {
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
} // joinedAt
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
return ((_a$joinedAt$getTime = (_a$joinedAt = a.joinedAt) === null || _a$joinedAt === void 0 ? void 0 : _a$joinedAt.getTime()) !== null && _a$joinedAt$getTime !== void 0 ? _a$joinedAt$getTime : 0) - ((_b$joinedAt$getTime = (_b$joinedAt = b.joinedAt) === null || _b$joinedAt === void 0 ? void 0 : _b$joinedAt.getTime()) !== null && _b$joinedAt$getTime !== void 0 ? _b$joinedAt$getTime : 0);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (localParticipant) {
|
|
124
|
+
const localIdx = participants.indexOf(localParticipant);
|
|
125
|
+
|
|
126
|
+
if (localIdx >= 0) {
|
|
127
|
+
participants.splice(localIdx, 1);
|
|
128
|
+
|
|
129
|
+
if (participants.length > 0) {
|
|
130
|
+
participants.splice(1, 0, localParticipant);
|
|
131
|
+
} else {
|
|
132
|
+
participants.push(localParticipant);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=useRoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["useRoom.ts"],"names":["useRoom","room","options","error","participants","setParticipants","audioTracks","setAudioTracks","sortFunc","sortParticipants","onParticipantsChanged","remotes","Array","from","values","newParticipants","localParticipant","push","onSubscribedTrackChanged","track","kind","Track","Kind","Audio","tracks","forEach","p","pub","audioTrack","onConnectionStateChanged","state","ConnectionState","Connected","once","RoomEvent","Disconnected","off","ParticipantConnected","ParticipantDisconnected","ActiveSpeakersChanged","TrackSubscribed","TrackUnsubscribed","LocalTrackPublished","LocalTrackUnpublished","AudioPlaybackStatusChanged","ConnectionStateChanged","on","Reconnected","disconnect","sort","a","b","isSpeaking","audioLevel","lastSpokeAt","aLast","getTime","bLast","aVideo","videoTracks","size","bVideo","joinedAt","localIdx","indexOf","splice","length"],"mappings":"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","sourcesContent":["import {\n AudioTrack,\n ConnectionState,\n LocalParticipant,\n Participant,\n RemoteTrack,\n Room,\n RoomEvent,\n Track,\n} from 'livekit-client';\nimport { useEffect, useState } from 'react';\n\nexport interface RoomState {\n room?: Room;\n /* all participants in the room, including the local participant. */\n participants: Participant[];\n /* all subscribed audio tracks in the room, not including local participant. */\n audioTracks: AudioTrack[];\n error?: Error;\n}\n\nexport interface RoomOptions {\n sortParticipants?: (participants: Participant[]) => void;\n}\n\nexport function useRoom(room: Room, options?: RoomOptions): RoomState {\n const [error] = useState<Error>();\n const [participants, setParticipants] = useState<Participant[]>([]);\n const [audioTracks, setAudioTracks] = useState<AudioTrack[]>([]);\n\n const sortFunc = options?.sortParticipants ?? sortParticipants;\n\n useEffect(() => {\n const onParticipantsChanged = () => {\n const remotes = Array.from(room.participants.values());\n const newParticipants: Participant[] = [room.localParticipant];\n newParticipants.push(...remotes);\n sortFunc(newParticipants, room.localParticipant);\n setParticipants(newParticipants);\n };\n const onSubscribedTrackChanged = (track?: RemoteTrack) => {\n // ordering may have changed, re-sort\n onParticipantsChanged();\n if (track && track.kind !== Track.Kind.Audio) {\n return;\n }\n const tracks: AudioTrack[] = [];\n room.participants.forEach((p) => {\n p.audioTracks.forEach((pub) => {\n if (pub.audioTrack) {\n tracks.push(pub.audioTrack);\n }\n });\n });\n setAudioTracks(tracks);\n };\n\n const onConnectionStateChanged = (state: ConnectionState) => {\n if (state === ConnectionState.Connected) {\n onParticipantsChanged();\n }\n };\n\n room.once(RoomEvent.Disconnected, () => {\n room\n .off(RoomEvent.ParticipantConnected, onParticipantsChanged)\n .off(RoomEvent.ParticipantDisconnected, onParticipantsChanged)\n .off(RoomEvent.ActiveSpeakersChanged, onParticipantsChanged)\n .off(RoomEvent.TrackSubscribed, onSubscribedTrackChanged)\n .off(RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged)\n .off(RoomEvent.LocalTrackPublished, onParticipantsChanged)\n .off(RoomEvent.LocalTrackUnpublished, onParticipantsChanged)\n .off(RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged)\n .off(RoomEvent.ConnectionStateChanged, onConnectionStateChanged);\n });\n room\n .on(RoomEvent.ConnectionStateChanged, onConnectionStateChanged)\n .on(RoomEvent.Reconnected, onParticipantsChanged)\n .on(RoomEvent.ParticipantConnected, onParticipantsChanged)\n .on(RoomEvent.ParticipantDisconnected, onParticipantsChanged)\n .on(RoomEvent.ActiveSpeakersChanged, onParticipantsChanged)\n .on(RoomEvent.TrackSubscribed, onSubscribedTrackChanged)\n .on(RoomEvent.TrackUnsubscribed, onSubscribedTrackChanged)\n .on(RoomEvent.LocalTrackPublished, onParticipantsChanged)\n .on(RoomEvent.LocalTrackUnpublished, onParticipantsChanged)\n // trigger a state change by re-sorting participants\n .on(RoomEvent.AudioPlaybackStatusChanged, onParticipantsChanged);\n\n onSubscribedTrackChanged();\n\n return () => {\n room.disconnect();\n };\n }, [room, sortFunc]);\n\n return {\n error,\n participants,\n audioTracks,\n };\n}\n\n/**\n * Default sort for participants, it'll order participants by:\n * 1. dominant speaker (speaker with the loudest audio level)\n * 2. local participant\n * 3. other speakers that are recently active\n * 4. participants with video on\n * 5. by joinedAt\n */\nexport function sortParticipants(\n participants: Participant[],\n localParticipant?: LocalParticipant\n) {\n participants.sort((a, b) => {\n // loudest speaker first\n if (a.isSpeaking && b.isSpeaking) {\n return b.audioLevel - a.audioLevel;\n }\n\n // speaker goes first\n if (a.isSpeaking !== b.isSpeaking) {\n if (a.isSpeaking) {\n return -1;\n } else {\n return 1;\n }\n }\n\n // last active speaker first\n if (a.lastSpokeAt !== b.lastSpokeAt) {\n const aLast = a.lastSpokeAt?.getTime() ?? 0;\n const bLast = b.lastSpokeAt?.getTime() ?? 0;\n return bLast - aLast;\n }\n\n // video on\n const aVideo = a.videoTracks.size > 0;\n const bVideo = b.videoTracks.size > 0;\n if (aVideo !== bVideo) {\n if (aVideo) {\n return -1;\n } else {\n return 1;\n }\n }\n\n // joinedAt\n return (a.joinedAt?.getTime() ?? 0) - (b.joinedAt?.getTime() ?? 0);\n });\n\n if (localParticipant) {\n const localIdx = participants.indexOf(localParticipant);\n if (localIdx >= 0) {\n participants.splice(localIdx, 1);\n if (participants.length > 0) {\n participants.splice(1, 0, localParticipant);\n } else {\n participants.push(localParticipant);\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
+
|
|
3
|
+
import { NativeModules, Platform } from 'react-native';
|
|
4
|
+
const LINKING_ERROR = `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
|
|
5
|
+
ios: "- You have run 'pod install'\n",
|
|
6
|
+
default: ''
|
|
7
|
+
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo managed workflow\n';
|
|
8
|
+
const LivekitReactNative = NativeModules.LivekitReactNative ? NativeModules.LivekitReactNative : new Proxy({}, {
|
|
9
|
+
get() {
|
|
10
|
+
throw new Error(LINKING_ERROR);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for the underlying AudioSession.
|
|
16
|
+
*
|
|
17
|
+
* ----
|
|
18
|
+
* Android specific options:
|
|
19
|
+
*
|
|
20
|
+
* * preferredOutputList - The preferred order in which to automatically select an audio output.
|
|
21
|
+
* This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.
|
|
22
|
+
*
|
|
23
|
+
* By default, the order is set to:
|
|
24
|
+
* 1. `"speaker"`
|
|
25
|
+
* 2. `"earpiece"`
|
|
26
|
+
* 3. `"headset"`
|
|
27
|
+
* 4. `"bluetooth"`
|
|
28
|
+
*
|
|
29
|
+
* ----
|
|
30
|
+
* iOS
|
|
31
|
+
*
|
|
32
|
+
* * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.
|
|
33
|
+
*
|
|
34
|
+
* By default, this is set to `"speaker"`
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export default class AudioSession {}
|
|
38
|
+
|
|
39
|
+
_defineProperty(AudioSession, "configureAudio", async config => {
|
|
40
|
+
await LivekitReactNative.configureAudio(config);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
_defineProperty(AudioSession, "startAudioSession", async () => {
|
|
44
|
+
await LivekitReactNative.startAudioSession();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
_defineProperty(AudioSession, "stopAudioSession", async () => {
|
|
48
|
+
await LivekitReactNative.stopAudioSession();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
_defineProperty(AudioSession, "getAudioOutputs", async () => {
|
|
52
|
+
if (Platform.OS === 'ios') {
|
|
53
|
+
return ['default', 'force_speaker'];
|
|
54
|
+
} else if (Platform.OS === 'android') {
|
|
55
|
+
return await LivekitReactNative.getAudioOutputs();
|
|
56
|
+
} else {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
_defineProperty(AudioSession, "selectAudioOutput", async deviceId => {
|
|
62
|
+
await LivekitReactNative.selectAudioOutput(deviceId);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
_defineProperty(AudioSession, "showAudioRoutePicker", async () => {
|
|
66
|
+
if (Platform.OS === 'ios') {
|
|
67
|
+
await LivekitReactNative.showAudioRoutePicker();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=AudioSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["AudioSession.ts"],"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","LivekitReactNative","Proxy","get","Error","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker"],"mappings":";;AAAA,SAASA,aAAT,EAAwBC,QAAxB,QAAwC,cAAxC;AACA,MAAMC,aAAa,GAChB,+EAAD,GACAD,QAAQ,CAACE,MAAT,CAAgB;AAAEC,EAAAA,GAAG,EAAE,gCAAP;AAAyCC,EAAAA,OAAO,EAAE;AAAlD,CAAhB,CADA,GAEA,sDAFA,GAGA,6CAJF;AAMA,MAAMC,kBAAkB,GAAGN,aAAa,CAACM,kBAAd,GACvBN,aAAa,CAACM,kBADS,GAEvB,IAAIC,KAAJ,CACE,EADF,EAEE;AACEC,EAAAA,GAAG,GAAG;AACJ,UAAM,IAAIC,KAAJ,CAAUP,aAAV,CAAN;AACD;;AAHH,CAFF,CAFJ;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA,eAAe,MAAMQ,YAAN,CAAmB;;gBAAbA,Y,oBAMK,MAAOC,MAAP,IAAsC;AAC5D,QAAML,kBAAkB,CAACM,cAAnB,CAAkCD,MAAlC,CAAN;AACD,C;;gBARkBD,Y,uBAaQ,YAAY;AACrC,QAAMJ,kBAAkB,CAACO,iBAAnB,EAAN;AACD,C;;gBAfkBH,Y,sBAoBO,YAAY;AACpC,QAAMJ,kBAAkB,CAACQ,gBAAnB,EAAN;AACD,C;;gBAtBkBJ,Y,qBAmDM,YAA+B;AACtD,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO,CAAC,SAAD,EAAY,eAAZ,CAAP;AACD,GAFD,MAEO,IAAId,QAAQ,CAACc,EAAT,KAAgB,SAApB,EAA+B;AACpC,WAAQ,MAAMT,kBAAkB,CAACU,eAAnB,EAAd;AACD,GAFM,MAEA;AACL,WAAO,EAAP;AACD;AACF,C;;gBA3DkBN,Y,uBAoEQ,MAAOO,QAAP,IAA4B;AACrD,QAAMX,kBAAkB,CAACY,iBAAnB,CAAqCD,QAArC,CAAN;AACD,C;;gBAtEkBP,Y,0BA6EW,YAAY;AACxC,MAAIT,QAAQ,CAACc,EAAT,KAAgB,KAApB,EAA2B;AACzB,UAAMT,kBAAkB,CAACa,oBAAnB,EAAN;AACD;AACF,C","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package 'livekit-react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"speaker\"`\n * 2. `\"earpiece\"`\n * 3. `\"headset\"`\n * 4. `\"bluetooth\"`\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android: {\n preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n };\n ios: {\n defaultOutput: 'speaker' | 'earpiece';\n };\n};\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * Note: For applications targeting SDK versions over 30, the runtime BLUETOOTH_CONNECT\n * permission must be requested to send audio to bluetooth headsets.\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n}\n"]}
|