streamlit-webrtc 0.62.0__py3-none-any.whl → 0.62.2__py3-none-any.whl

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.
@@ -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
 
@@ -597,11 +597,8 @@ def webrtc_streamer(
597
597
  on_ended=on_audio_ended,
598
598
  )
599
599
 
600
- worker_created_in_this_run = None
601
600
  with context._worker_creation_lock: # This point can be reached in parallel so we need to use a lock to make the worker creation process atomic.
602
- should_create_worker_in_this_run = not context._get_worker() and sdp_offer
603
-
604
- if should_create_worker_in_this_run:
601
+ if not context._get_worker() and sdp_offer:
605
602
  LOGGER.debug(
606
603
  "No worker exists though the offer SDP is set. "
607
604
  'Create a new worker (key="%s").',
@@ -621,7 +618,7 @@ def webrtc_streamer(
621
618
  ice_servers = get_available_ice_servers() # NOTE: This may include a yield point where Streamlit's script runner interrupts the execution and may stop the current run.
622
619
  aiortc_rtc_configuration.iceServers = compile_ice_servers(ice_servers)
623
620
 
624
- worker_created_in_this_run = WebRtcWorker(
621
+ worker_created_in_this_run: WebRtcWorker = WebRtcWorker(
625
622
  mode=mode,
626
623
  rtc_configuration=aiortc_rtc_configuration,
627
624
  player_factory=player_factory,
@@ -644,19 +641,37 @@ def webrtc_streamer(
644
641
  sendback_audio=sendback_audio,
645
642
  )
646
643
 
644
+ worker_created_in_this_run.process_offer(
645
+ sdp_offer["sdp"],
646
+ sdp_offer["type"],
647
+ timeout=10, # The timeout of aioice's method that is used in the internal of this method is 5: https://github.com/aiortc/aioice/blob/aaada959aa8de31b880822db36f1c0c0cef75c0e/src/aioice/ice.py#L973. We set a bit longer timeout here.
648
+ )
649
+
647
650
  # Set the worker here within the lock.
648
651
  context._set_worker(worker_created_in_this_run)
649
652
 
650
653
  webrtc_worker = context._get_worker()
651
- if webrtc_worker and ice_candidates:
652
- webrtc_worker.set_ice_candidates_from_offerer(ice_candidates)
653
654
 
654
- if worker_created_in_this_run:
655
- worker_created_in_this_run.process_offer(
656
- sdp_offer["sdp"], sdp_offer["type"], timeout=None
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
+ }
657
665
  )
658
666
 
659
- # Rerun to send the SDP answer to frontend
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.
660
672
  rerun()
661
673
 
674
+ if webrtc_worker and ice_candidates:
675
+ webrtc_worker.set_ice_candidates_from_offerer(ice_candidates)
676
+
662
677
  return context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit-webrtc
3
- Version: 0.62.0
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>
@@ -1,6 +1,6 @@
1
1
  streamlit_webrtc/__init__.py,sha256=jMWwXoQ9hVyYXPD4Vrps7MyiR9goyC-n7LtkZNFBOxU,2273
2
2
  streamlit_webrtc/_compat.py,sha256=AVRcUGdgWDQcCE7-ufhGr6Hb5P6EHLgejUAA72ArJmg,4384
3
- streamlit_webrtc/component.py,sha256=Imoz2xuLRvgjy2Lxi9VVXgCMdvf-nUriTim2AjdFfC0,27155
3
+ streamlit_webrtc/component.py,sha256=GYkD-UPZgLrxSUce81o9AakKYk2NOjDsna7mN9Pul7k,28291
4
4
  streamlit_webrtc/components_callbacks.py,sha256=tdrj2TlV8qcexFEdjm4PVkz8JwHffo4A8imoXOtjNHA,2401
5
5
  streamlit_webrtc/config.py,sha256=yKFIVjIoX2F62_G2qcDrNYm2Qe_qx1E9E0YqAnAibMo,5544
6
6
  streamlit_webrtc/credentials.py,sha256=fTs-DhUhScK8m7OEfkgTMw7pKXnS9QNpjtJAvR9oIzs,4619
@@ -19,7 +19,7 @@ streamlit_webrtc/source.py,sha256=haPqMZ50Xh8tg7Z1yN8Frfk8v7D3oOuKteaD59asbzs,22
19
19
  streamlit_webrtc/webrtc.py,sha256=WzgydYm3Xhoi5c1QHNLc_GiF_E0aGC5ynzmxeAbtJCw,29900
20
20
  streamlit_webrtc/frontend/dist/index.html,sha256=ZY_Iflaf7wRUHHNpw7JMlSMraE3ewM9T_tZA94NIPRs,527
21
21
  streamlit_webrtc/frontend/dist/assets/index-Cz1nSw2-.js,sha256=j126AA3NGo8BLgQSjjMyQR6QwpDRq_jILP9woihrncI,589799
22
- streamlit_webrtc-0.62.0.dist-info/METADATA,sha256=4ZRD7tidnmUHRkPHOGorF-MZrzDSnaAs7ZXPCPAmuvw,18288
23
- streamlit_webrtc-0.62.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
- streamlit_webrtc-0.62.0.dist-info/licenses/LICENSE,sha256=pwccNHVA7r4rYofGlMU10aKEU90GLUlQr8uY80PR0NQ,1081
25
- streamlit_webrtc-0.62.0.dist-info/RECORD,,
22
+ streamlit_webrtc-0.62.2.dist-info/METADATA,sha256=8RUIipCW6q8IVFviv2UVCakHZ2NG5CyoBL6Ru4uWbL4,18288
23
+ streamlit_webrtc-0.62.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
+ streamlit_webrtc-0.62.2.dist-info/licenses/LICENSE,sha256=pwccNHVA7r4rYofGlMU10aKEU90GLUlQr8uY80PR0NQ,1081
25
+ streamlit_webrtc-0.62.2.dist-info/RECORD,,