kasunk99-livestream-core 0.3.3 → 0.3.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"LiveStreamViewerItem.d.ts","sourceRoot":"","sources":["../../src/components/LiveStreamViewerItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAc1E,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,uDAyT/B,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":"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
+ {"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,CAmgBpG"}
@@ -104,6 +104,7 @@ export function useViewerSocket(roomId) {
104
104
  });
105
105
  }, JOIN_TIMEOUT_MS);
106
106
  let socket = null;
107
+ let sysAudioPlayerStarted = false;
107
108
  (async () => {
108
109
  // Server requires viewerToken for viewers (not merchant apiKey).
109
110
  // We mint a short-lived viewer token via HTTP using the apiKey.
@@ -200,6 +201,31 @@ export function useViewerSocket(roomId) {
200
201
  setState((prev) => ({ ...prev, viewerCount: payload.viewerCount }));
201
202
  }
202
203
  });
204
+ socket.on('system-audio-chunk', (payload) => {
205
+ const b64 = typeof payload === 'string' ? payload
206
+ : typeof payload?.data === 'string'
207
+ ? payload.data
208
+ : null;
209
+ if (!b64)
210
+ return;
211
+ try {
212
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
213
+ const { NativeModules, Platform } = require('react-native');
214
+ if (Platform.OS !== 'android')
215
+ return;
216
+ const player = NativeModules.ScreenSystemAudioPlayer;
217
+ if (!player)
218
+ return;
219
+ if (!sysAudioPlayerStarted) {
220
+ sysAudioPlayerStarted = true;
221
+ player.startPlayback().catch(() => { sysAudioPlayerStarted = false; });
222
+ }
223
+ player.feedChunk(b64);
224
+ }
225
+ catch {
226
+ // NativeModules unavailable in non-RN environments
227
+ }
228
+ });
203
229
  })();
204
230
  return () => {
205
231
  clearTimeout(joinTimeout);
@@ -210,6 +236,18 @@ export function useViewerSocket(roomId) {
210
236
  catch {
211
237
  // ignore
212
238
  }
239
+ if (sysAudioPlayerStarted) {
240
+ sysAudioPlayerStarted = false;
241
+ try {
242
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
243
+ const { NativeModules } = require('react-native');
244
+ const player = NativeModules.ScreenSystemAudioPlayer;
245
+ player?.stopPlayback?.();
246
+ }
247
+ catch {
248
+ // ignore
249
+ }
250
+ }
213
251
  disconnect();
214
252
  };
215
253
  }, [roomId, disconnect]);
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  * @livestream/core — Reusable livestream module for React Native (Expo).
3
3
  * Configure with setLivestreamConfig() before using components/hooks.
4
4
  */
5
+ //kk
5
6
  export { setLivestreamConfig, getLivestreamConfig, getBaseUrl, getApiKey, getSignalingUrl, getSignalingWsUrl, getDisplayName, } from './config';
6
7
  export { fetchActiveStreams, createStream, mintViewerToken } from './services/livestream.service';
7
8
  export { ensureMediasoupGlobals } from './services/mediasoup-init';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasunk99-livestream-core",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Reusable livestream viewer/host module for React Native (Expo) — mediasoup + Socket.IO",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",