streamlit-webrtc 0.62.1__tar.gz → 0.62.2__tar.gz

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.
Files changed (26) hide show
  1. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/PKG-INFO +1 -1
  2. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/component.py +32 -18
  3. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/.gitignore +0 -0
  4. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/LICENSE +0 -0
  5. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/README.md +0 -0
  6. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/pyproject.toml +0 -0
  7. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/__init__.py +0 -0
  8. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/_compat.py +0 -0
  9. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/components_callbacks.py +0 -0
  10. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/config.py +0 -0
  11. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/credentials.py +0 -0
  12. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/eventloop.py +0 -0
  13. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/factory.py +0 -0
  14. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/frontend/dist/assets/index-Cz1nSw2-.js +0 -0
  15. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/frontend/dist/index.html +0 -0
  16. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/mix.py +0 -0
  17. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/models.py +0 -0
  18. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/process.py +0 -0
  19. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/py.typed +0 -0
  20. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/receive.py +0 -0
  21. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/relay.py +0 -0
  22. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/server.py +0 -0
  23. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/session_info.py +0 -0
  24. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/shutdown.py +0 -0
  25. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/source.py +0 -0
  26. {streamlit_webrtc-0.62.1 → streamlit_webrtc-0.62.2}/streamlit_webrtc/webrtc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit-webrtc
3
- Version: 0.62.1
3
+ Version: 0.62.2
4
4
  Summary: Real-time video and audio processing on Streamlit
5
5
  Project-URL: Repository, https://github.com/whitphx/streamlit-webrtc
6
6
  Author-email: "Yuichiro Tachibana (Tsuchiya)" <t.yic.yt@gmail.com>
@@ -95,6 +95,8 @@ class WebRtcStreamerContext(Generic[VideoProcessorT, AudioProcessorT]):
95
95
  _component_value_snapshot: Union[ComponentValueSnapshot, None]
96
96
  _worker_creation_lock: threading.Lock
97
97
  _frontend_rtc_configuration: Optional[Union[Dict[str, Any], RTCConfiguration]]
98
+ _sdp_answer_json: Optional[str]
99
+ _is_sdp_answer_sent: bool
98
100
 
99
101
  def __init__(
100
102
  self,
@@ -106,6 +108,8 @@ class WebRtcStreamerContext(Generic[VideoProcessorT, AudioProcessorT]):
106
108
  self._component_value_snapshot = None
107
109
  self._worker_creation_lock = threading.Lock()
108
110
  self._frontend_rtc_configuration = None
111
+ self._sdp_answer_json = None
112
+ self._is_sdp_answer_sent = False
109
113
 
110
114
  def _set_worker(
111
115
  self, worker: Optional[WebRtcWorker[VideoProcessorT, AudioProcessorT]]
@@ -481,16 +485,9 @@ def webrtc_streamer(
481
485
  )
482
486
  context._frontend_rtc_configuration["iceServers"] = get_available_ice_servers()
483
487
 
484
- webrtc_worker = context._get_worker()
485
-
486
- sdp_answer_json = None
487
- if webrtc_worker and webrtc_worker.pc.localDescription:
488
- sdp_answer_json = json.dumps(
489
- {
490
- "sdp": webrtc_worker.pc.localDescription.sdp,
491
- "type": webrtc_worker.pc.localDescription.type,
492
- }
493
- )
488
+ if context._sdp_answer_json:
489
+ # Set the flag not to trigger rerun() any more as `context._sdp_answer_json` is already set and will have been sent to the frontend in this run.
490
+ context._is_sdp_answer_sent = True
494
491
 
495
492
  frontend_key = generate_frontend_component_key(key)
496
493
 
@@ -515,7 +512,7 @@ def webrtc_streamer(
515
512
  }
516
513
  component_value_raw: Union[Dict, str, None] = _component_func(
517
514
  key=frontend_key,
518
- sdp_answer_json=sdp_answer_json,
515
+ sdp_answer_json=context._sdp_answer_json,
519
516
  mode=mode.name,
520
517
  rtc_configuration=context._frontend_rtc_configuration,
521
518
  media_stream_constraints=media_stream_constraints,
@@ -566,6 +563,8 @@ def webrtc_streamer(
566
563
  sdp_offer = component_value.get("sdpOffer")
567
564
  ice_candidates = component_value.get("iceCandidates")
568
565
 
566
+ webrtc_worker = context._get_worker()
567
+
569
568
  if not context.state.playing and not context.state.signalling:
570
569
  LOGGER.debug(
571
570
  "Unset the worker and the internal states because the frontend state is "
@@ -578,8 +577,9 @@ def webrtc_streamer(
578
577
  if webrtc_worker:
579
578
  webrtc_worker.stop()
580
579
  context._set_worker(None)
580
+ context._is_sdp_answer_sent = False
581
+ context._sdp_answer_json = None
581
582
  webrtc_worker = None
582
-
583
583
  # Rerun to unset the SDP answer from the frontend args
584
584
  rerun()
585
585
 
@@ -650,13 +650,27 @@ def webrtc_streamer(
650
650
  # Set the worker here within the lock.
651
651
  context._set_worker(worker_created_in_this_run)
652
652
 
653
- # It's important to lock the entire block including creating the worker, waiting for process_offer(), and calling rerun().
654
- # Otherwise, `rerun()` may fail because another script run completes during this run is pending to wait for these operations
655
- # and it sets the `ScriptRequests._state` to `ScriptRequestType.STOP` which denies the rerun request.
656
- LOGGER.debug("Rerun to send the SDP answer to frontend")
657
- rerun()
658
-
659
653
  webrtc_worker = context._get_worker()
654
+
655
+ if (
656
+ webrtc_worker
657
+ and webrtc_worker.pc.localDescription
658
+ and not context._is_sdp_answer_sent
659
+ ):
660
+ context._sdp_answer_json = json.dumps(
661
+ {
662
+ "sdp": webrtc_worker.pc.localDescription.sdp,
663
+ "type": webrtc_worker.pc.localDescription.type,
664
+ }
665
+ )
666
+
667
+ LOGGER.debug("Rerun to send the SDP answer to frontend")
668
+ # NOTE: rerun() may not work if it's called in the lock when the `runner.fastReruns` config is enabled
669
+ # because the `ScriptRequests._state` is set to `ScriptRequestType.STOP` by the rerun request from the frontend sent during awaiting the lock,
670
+ # which makes the rerun request refused.
671
+ # So we call rerun() here. It can be called even in a different thread(run) from the one where the worker is created as long as the condition is met.
672
+ rerun()
673
+
660
674
  if webrtc_worker and ice_candidates:
661
675
  webrtc_worker.set_ice_candidates_from_offerer(ice_candidates)
662
676