kasunk99-livestream-core 0.2.0 → 0.2.1

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":"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,mBAAmB,GAAG,SAAS,GAAG;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,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,CA0kBrF"}
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,mBAAmB,GAAG,SAAS,GAAG;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,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,CA6iBrF"}
@@ -497,51 +497,20 @@ export function useHostSocket(options = {}) {
497
497
  const stopLive = useCallback(async () => {
498
498
  const { captureMode } = getHostState();
499
499
  if (captureMode === 'screen' && hostSession.screenStream) {
500
- // ── Sequential screen-share teardown ───────────────────────────────
501
- // react-native-webrtc uses a single-threaded executor for ALL WebRTC ops.
502
- // ScreenCapturerAndroid.stopCapture() blocks that executor for up to 60 s
503
- // while waiting for the render thread (captureStopped CountDownLatch).
504
- // RTCPeerConnection.dispose() (triggered async after pc.close()) frees the
505
- // SurfaceTextureHelper that the render thread writes into.
506
- // If stop() runs AFTER dispose(), the render thread is stuck → 60 s freeze.
507
- //
508
- // Fix: stop the screen tracks HERE, wait for the MediaProjection 'ended'
509
- // event (i.e. the native capture has fully drained), THEN call fullCleanup().
510
- // By the time fullCleanup() runs, the screen capturer is already gone and
511
- // peerConnectionDispose() has nothing to contend with.
512
- const screenStream = hostSession.screenStream;
513
- hostSession.screenStream = null; // guard: stopScreenShare bails on re-entry
514
500
  patchHostState({ status: 'Stopping screen share...' });
515
- await new Promise((resolve) => {
516
- const videoTrack = screenStream.getVideoTracks()[0];
517
- if (videoTrack && videoTrack.readyState !== 'ended' && videoTrack.addEventListener) {
518
- const onEnded = () => {
519
- videoTrack.removeEventListener?.('ended', onEnded);
520
- resolve();
521
- };
522
- videoTrack.addEventListener('ended', onEnded);
523
- // Stop all screen tracks — fires 'ended' when MediaProjection fully releases
524
- screenStream.getTracks()
525
- .forEach((t) => { try {
526
- t.stop?.();
527
- }
528
- catch { /* ignore */ } });
529
- // Fallback: if 'ended' never fires (some devices), unblock after 800 ms
530
- setTimeout(() => {
531
- videoTrack.removeEventListener?.('ended', onEnded);
532
- resolve();
533
- }, 800);
534
- }
535
- else {
536
- screenStream.getTracks()
537
- .forEach((t) => { try {
538
- t.stop?.();
539
- }
540
- catch { /* ignore */ } });
541
- resolve();
542
- }
543
- });
544
- // MediaProjection is fully stopped — executor is free. Safe to close transport.
501
+ const screenStream = hostSession.screenStream;
502
+ hostSession.screenStream = null; // guard: stopScreenShare() bails on re-entry
503
+ // t.stop() setEnabled(false) executor: mediaStreamTrackSetEnabled(-1, id, false)
504
+ // getUserMediaImpl.mediaStreamTrackSetEnabled → ScreenCaptureController.stopCapture()
505
+ // Our override is non-blocking: spawns "ScreenCaptureStop" thread that calls
506
+ // capturer.stopCapture() (blocks there, not on executor) and then calls
507
+ // MediaProjectionService.abort(ctx) in its finally block so the notification
508
+ // disappears after the MediaProjection fully drains.
509
+ screenStream.getTracks()
510
+ .forEach((t) => { try {
511
+ t.stop?.();
512
+ }
513
+ catch { /* ignore */ } });
545
514
  }
546
515
  fullCleanup();
547
516
  patchHostState({ status: 'Stream stopped' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasunk99-livestream-core",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
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",