kasunk99-livestream-core 0.3.2 → 0.3.4
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/components/LiveStreamViewerItem.d.ts.map +1 -1
- package/dist/components/LiveStreamViewerItem.js +31 -1
- package/dist/hooks/useHostSocket.d.ts.map +1 -1
- package/dist/hooks/useHostSocket.js +14 -1
- package/dist/hooks/useViewerSocket.d.ts.map +1 -1
- package/dist/hooks/useViewerSocket.js +3 -4
- package/dist/host/hostSession.d.ts +1 -0
- package/dist/host/hostSession.d.ts.map +1 -1
- package/dist/host/hostSession.js +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAe1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,KAAK,yBAAyB,GAAG;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,oBAAoB,uDA4V/B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { Animated, Dimensions, Keyboard, Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native';
|
|
3
|
+
import { Animated, Dimensions, Keyboard, NativeModules, Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native';
|
|
4
4
|
import { useViewerSocket } from '../hooks/useViewerSocket';
|
|
5
5
|
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
|
|
6
6
|
const CHAT_NAME_COLORS = ['#f97316', '#22c55e', '#3b82f6', '#eab308', '#ec4899', '#a855f7'];
|
|
@@ -151,6 +151,36 @@ export const LiveStreamViewerItem = memo(function LiveStreamViewerItem({ stream,
|
|
|
151
151
|
// ignore scroll errors
|
|
152
152
|
}
|
|
153
153
|
}, [chatData.length]);
|
|
154
|
+
// System audio playback (Android only — receives AAC chunks from host during screen sharing)
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (!socket || !joined || !isActive || Platform.OS !== 'android')
|
|
157
|
+
return;
|
|
158
|
+
let playerStarted = false;
|
|
159
|
+
const onChunk = async (payload) => {
|
|
160
|
+
const b64 = payload?.data;
|
|
161
|
+
if (!b64)
|
|
162
|
+
return;
|
|
163
|
+
try {
|
|
164
|
+
const player = NativeModules.ScreenSystemAudioPlayer;
|
|
165
|
+
if (!player)
|
|
166
|
+
return;
|
|
167
|
+
if (!playerStarted) {
|
|
168
|
+
await player.startPlayback();
|
|
169
|
+
playerStarted = true;
|
|
170
|
+
}
|
|
171
|
+
player.feedChunk(b64);
|
|
172
|
+
}
|
|
173
|
+
catch { /* ignore */ }
|
|
174
|
+
};
|
|
175
|
+
socket.on('system-audio-chunk', onChunk);
|
|
176
|
+
return () => {
|
|
177
|
+
socket.off('system-audio-chunk', onChunk);
|
|
178
|
+
if (playerStarted) {
|
|
179
|
+
const player = NativeModules.ScreenSystemAudioPlayer;
|
|
180
|
+
player?.stopPlayback();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}, [socket, joined, isActive]);
|
|
154
184
|
const getNameColor = (name) => {
|
|
155
185
|
if (!name)
|
|
156
186
|
return CHAT_NAME_COLORS[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHostSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useHostSocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAoB3B,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAMF,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useHostSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useHostSocket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAC;AAoB3B,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAMF,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAiqBrF"}
|
|
@@ -96,6 +96,11 @@ export function useHostSocket(options = {}) {
|
|
|
96
96
|
}
|
|
97
97
|
catch { /* ignore */ }
|
|
98
98
|
hostSession.videoProducer = null;
|
|
99
|
+
try {
|
|
100
|
+
hostSession.screenAudioProducer?.close();
|
|
101
|
+
}
|
|
102
|
+
catch { /* ignore */ }
|
|
103
|
+
hostSession.screenAudioProducer = null;
|
|
99
104
|
// Snapshot stream refs and null them out so re-entrant stopScreenShare() bails.
|
|
100
105
|
const screenStreamToStop = hostSession.screenStream;
|
|
101
106
|
hostSession.screenStream = null;
|
|
@@ -388,7 +393,7 @@ export function useHostSocket(options = {}) {
|
|
|
388
393
|
}, [replaceVideoProducer]);
|
|
389
394
|
const startScreenShare = useCallback(async () => {
|
|
390
395
|
try {
|
|
391
|
-
const screenStream = await mediaDevices.getDisplayMedia({ video: true, audio:
|
|
396
|
+
const screenStream = await mediaDevices.getDisplayMedia({ video: true, audio: true });
|
|
392
397
|
const screenVideoTrack = screenStream.getVideoTracks()[0];
|
|
393
398
|
if (!screenVideoTrack) {
|
|
394
399
|
screenStream.getTracks()
|
|
@@ -399,6 +404,7 @@ export function useHostSocket(options = {}) {
|
|
|
399
404
|
return;
|
|
400
405
|
}
|
|
401
406
|
hostSession.screenStream = screenStream;
|
|
407
|
+
const screenAudioTrack = screenStream.getAudioTracks()[0] ?? null;
|
|
402
408
|
if (Platform.OS === 'android') {
|
|
403
409
|
// Android: stop camera hardware — MediaProjection captures the hardware
|
|
404
410
|
// display independently, so stopping the camera is safe and saves battery.
|
|
@@ -422,6 +428,13 @@ export function useHostSocket(options = {}) {
|
|
|
422
428
|
patchHostState({ streamURL: getStreamURL(hostSession.localStream) });
|
|
423
429
|
}
|
|
424
430
|
await replaceVideoProducer(screenVideoTrack);
|
|
431
|
+
if (screenAudioTrack && hostSession.sendTransport && !hostSession.sendTransport.closed) {
|
|
432
|
+
try {
|
|
433
|
+
const screenAudioProducer = await hostSession.sendTransport.produce({ track: screenAudioTrack });
|
|
434
|
+
hostSession.screenAudioProducer = screenAudioProducer;
|
|
435
|
+
}
|
|
436
|
+
catch { /* ignore — system audio not available on this device/OS version */ }
|
|
437
|
+
}
|
|
425
438
|
// Auto-revert when user dismisses screen share
|
|
426
439
|
// (Android: from the notification bar; iOS: from the status-bar recording dot)
|
|
427
440
|
screenVideoTrack.addEventListener?.('ended', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useViewerSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewerSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"useViewerSocket.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewerSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAM,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CA0dpG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect,
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { io } from 'socket.io-client';
|
|
3
3
|
import { getApiKey, getDisplayName } from '../config';
|
|
4
4
|
import { ensureMediasoupGlobals } from '../services/mediasoup-init';
|
|
@@ -31,7 +31,6 @@ export function useViewerSocket(roomId) {
|
|
|
31
31
|
const consumeInProgressRef = useRef(false);
|
|
32
32
|
const iceServersRef = useRef([]);
|
|
33
33
|
const consumeRetryCountRef = useRef(0);
|
|
34
|
-
const displayName = useMemo(() => getDisplayName(), []);
|
|
35
34
|
const disconnect = useCallback(() => {
|
|
36
35
|
consumedProducerIdsRef.current.clear();
|
|
37
36
|
try {
|
|
@@ -140,7 +139,7 @@ export function useViewerSocket(roomId) {
|
|
|
140
139
|
socket?.emit('join-room', {
|
|
141
140
|
roomId,
|
|
142
141
|
role: 'viewer',
|
|
143
|
-
displayName,
|
|
142
|
+
displayName: getDisplayName(),
|
|
144
143
|
}, (res) => {
|
|
145
144
|
clearTimeout(joinTimeout);
|
|
146
145
|
if (roomIdRef.current !== roomId)
|
|
@@ -213,7 +212,7 @@ export function useViewerSocket(roomId) {
|
|
|
213
212
|
}
|
|
214
213
|
disconnect();
|
|
215
214
|
};
|
|
216
|
-
}, [roomId,
|
|
215
|
+
}, [roomId, disconnect]);
|
|
217
216
|
// Consume flow: create device, recv transport, connect, consume each producer → remoteStream
|
|
218
217
|
useEffect(() => {
|
|
219
218
|
const socket = socketRef.current;
|
|
@@ -13,6 +13,7 @@ export declare const hostSession: {
|
|
|
13
13
|
screenStream: MediaStream | null;
|
|
14
14
|
audioProducer: mediasoupClient.types.Producer<mediasoupClient.types.AppData> | null;
|
|
15
15
|
videoProducer: mediasoupClient.types.Producer<mediasoupClient.types.AppData> | null;
|
|
16
|
+
screenAudioProducer: mediasoupClient.types.Producer<mediasoupClient.types.AppData> | null;
|
|
16
17
|
iceServers: RTCIceServer[];
|
|
17
18
|
};
|
|
18
19
|
//# sourceMappingURL=hostSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hostSession.d.ts","sourceRoot":"","sources":["../../src/host/hostSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,KAAK,eAAe,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"hostSession.d.ts","sourceRoot":"","sources":["../../src/host/hostSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,KAAK,eAAe,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,WAAW;;;;;;;;;;CAUvB,CAAC"}
|
package/dist/host/hostSession.js
CHANGED
package/package.json
CHANGED