Reoo88 commited on
Commit
7983ecc
·
verified ·
1 Parent(s): 30b1d21

v2.37-fill-span: bound watchdog fill exemption + pump renewal by whole fill episode (fill_until)

Browse files
Files changed (2) hide show
  1. ingest.py +1 -1
  2. relay.py +6 -4
ingest.py CHANGED
@@ -6,7 +6,7 @@ import os, threading, time
6
  from datetime import datetime
7
  from zoneinfo import ZoneInfo
8
 
9
- APP_VERSION = 'relay-v2.36-fill-renewal'
10
 
11
 
12
  def env_rtmp_destination():
 
6
  from datetime import datetime
7
  from zoneinfo import ZoneInfo
8
 
9
+ APP_VERSION = 'relay-v2.37-fill-span'
10
 
11
 
12
  def env_rtmp_destination():
relay.py CHANGED
@@ -763,7 +763,8 @@ class Sender:
763
  # خياطة ليس دليل موت خرج (مقيس: 13:06:13 و13:21:46 و10:24:57).
764
  # نجدّد بمهل قصيرة ما دام الحشو قائمًا، وسقف الحشو (90 ث) نفسه
765
  # يحدّ الصبر الكلي، فلا تعليق أبديًا ولا قتل لجلسة تُنقَذ.
766
- if sess is not None and sess.get('filling') and not sess.get('force_stop'):
 
767
  deadline = time.monotonic() + 2.0
768
  continue
769
  raise SourceStalled('أنبوب FFmpeg ممتلئ ولا يقرأ منذ %.0f ث' % max(0.0, -left))
@@ -799,7 +800,7 @@ class Sender:
799
  stdin، ويوتيوب يبقى مستقبِلًا على آخر ما وصل — لذا يُقاس تدفق البيانات لا حالة العملية.
800
  """
801
  sess.setdefault('stdin_lock', threading.Lock())
802
- sess.setdefault('filling', False); sess.setdefault('filling_at', 0.0); sess.setdefault('fill_emit_at', 0.0); sess.setdefault('reattach_at', 0.0)
803
  it = response.iter_content(None).__iter__()
804
  deadline = time.monotonic() + sess['max_seconds']
805
  chunk_wait = min(read_timeout, max(1.0, self._stall_seconds() / 3.0)) if self._stall_seconds() else read_timeout
@@ -1089,7 +1090,7 @@ class Sender:
1089
  'stall_reason': '', 'spawned': False, 'spawn_error': '',
1090
  'writing': False, 'output_failure': False, 'connection_event': False,
1091
  'ff_last': time.monotonic(),
1092
- 'stdin_lock': threading.Lock(), 'filling': False, 'filling_at': 0.0, 'fill_emit_at': 0.0, 'reattach_at': 0.0}
1093
  self.set(status='الاتصال بيوتيوب', source=candidate['label'], output_seconds=0,
1094
  last_output_at=None, stalled=False, last_source_at=sess['last'], source_bytes=0,
1095
  rtmp_phase='')
@@ -1285,6 +1286,7 @@ class Sender:
1285
  sess['filling']=False;continue
1286
  if fill_state['started'] is None:
1287
  fill_state['started']=now_f;fill_state['last_emit']=0.0
 
1288
  self.log(user,'[FILL] صمت المصدر %.0f ث؛ حشو بإطار مجمّد حتى لا يرى يوتيوب فجوة (سقف %.0f ث)'%(silent_for,fill_max))
1289
  log_event(user,'GAP_FILL_START',{'silent_seconds':round(silent_for,1),'cap_seconds':fill_max})
1290
  telemetry_event(tele_key,user,'GAP_FILL_START',{'silent_seconds':round(silent_for,1),'cap_seconds':fill_max})
@@ -1406,7 +1408,7 @@ class Sender:
1406
  continue
1407
  if (stall_limit and now - _fresh > stall_limit and
1408
  (not recent_attach or sess.get('output_failure') or sess.get('writing')) and
1409
- not (sess.get('filling') and now-float(sess.get('filling_at') or 0)<10) and
1410
  (not sess.get('swapping') or swap_for > stall_limit)):
1411
  # A full stdin pipe proves the source delivered a chunk but FFmpeg stopped
1412
  # consuming it. Reopening TikTok cannot repair a blocked RTMPS output.
 
763
  # خياطة ليس دليل موت خرج (مقيس: 13:06:13 و13:21:46 و10:24:57).
764
  # نجدّد بمهل قصيرة ما دام الحشو قائمًا، وسقف الحشو (90 ث) نفسه
765
  # يحدّ الصبر الكلي، فلا تعليق أبديًا ولا قتل لجلسة تُنقَذ.
766
+ if (sess is not None and sess.get('filling') and not sess.get('force_stop')
767
+ and time.monotonic() < float(sess.get('fill_until') or 0)):
768
  deadline = time.monotonic() + 2.0
769
  continue
770
  raise SourceStalled('أنبوب FFmpeg ممتلئ ولا يقرأ منذ %.0f ث' % max(0.0, -left))
 
800
  stdin، ويوتيوب يبقى مستقبِلًا على آخر ما وصل — لذا يُقاس تدفق البيانات لا حالة العملية.
801
  """
802
  sess.setdefault('stdin_lock', threading.Lock())
803
+ sess.setdefault('filling', False); sess.setdefault('filling_at', 0.0); sess.setdefault('fill_emit_at', 0.0); sess.setdefault('reattach_at', 0.0); sess.setdefault('fill_since', 0.0); sess.setdefault('fill_until', 0.0)
804
  it = response.iter_content(None).__iter__()
805
  deadline = time.monotonic() + sess['max_seconds']
806
  chunk_wait = min(read_timeout, max(1.0, self._stall_seconds() / 3.0)) if self._stall_seconds() else read_timeout
 
1090
  'stall_reason': '', 'spawned': False, 'spawn_error': '',
1091
  'writing': False, 'output_failure': False, 'connection_event': False,
1092
  'ff_last': time.monotonic(),
1093
+ 'stdin_lock': threading.Lock(), 'filling': False, 'filling_at': 0.0, 'fill_emit_at': 0.0, 'fill_since': 0.0, 'fill_until': 0.0, 'reattach_at': 0.0}
1094
  self.set(status='الاتصال بيوتيوب', source=candidate['label'], output_seconds=0,
1095
  last_output_at=None, stalled=False, last_source_at=sess['last'], source_bytes=0,
1096
  rtmp_phase='')
 
1286
  sess['filling']=False;continue
1287
  if fill_state['started'] is None:
1288
  fill_state['started']=now_f;fill_state['last_emit']=0.0
1289
+ sess['fill_since']=now_f;sess['fill_until']=now_f+fill_max+25.0
1290
  self.log(user,'[FILL] صمت المصدر %.0f ث؛ حشو بإطار مجمّد حتى لا يرى يوتيوب فجوة (سقف %.0f ث)'%(silent_for,fill_max))
1291
  log_event(user,'GAP_FILL_START',{'silent_seconds':round(silent_for,1),'cap_seconds':fill_max})
1292
  telemetry_event(tele_key,user,'GAP_FILL_START',{'silent_seconds':round(silent_for,1),'cap_seconds':fill_max})
 
1408
  continue
1409
  if (stall_limit and now - _fresh > stall_limit and
1410
  (not recent_attach or sess.get('output_failure') or sess.get('writing')) and
1411
+ not (sess.get('filling') and now<float(sess.get('fill_until') or 0)) and
1412
  (not sess.get('swapping') or swap_for > stall_limit)):
1413
  # A full stdin pipe proves the source delivered a chunk but FFmpeg stopped
1414
  # consuming it. Reopening TikTok cannot repair a blocked RTMPS output.