health: send_mode+youtube fields; skip 1440p on 2nd concurrent (cpu-basic measured)
Browse files- app.py +3 -1
- relay.py +4 -0
- youtube_manager.py +22 -7
app.py
CHANGED
|
@@ -577,6 +577,7 @@ def _relay_snapshot(user):
|
|
| 577 |
'session_title':slot.get('title') if slot else '',
|
| 578 |
'relay_dest':slot.get('dest') if slot else '',
|
| 579 |
'restarts':hub.restart_count(user),
|
|
|
|
| 580 |
}
|
| 581 |
|
| 582 |
def _cgroup_usage_ns():
|
|
@@ -785,7 +786,8 @@ def health_public():
|
|
| 785 |
'room_id':tsk.get('room_id') or '','source':tsk.get('source') or '',
|
| 786 |
'restarts':rs.get('restarts') or 0,'dest':rs.get('relay_dest') or '',
|
| 787 |
'last_error':tsk.get('last_error') or '','source_age':rs.get('source_age'),
|
| 788 |
-
'output_seconds':rs.get('output_seconds') or 0
|
|
|
|
| 789 |
res=resource_snapshot()
|
| 790 |
mgr=bool(youtube.manager_thread and youtube.manager_thread.is_alive())
|
| 791 |
y_events=0; y_hist=0; y_senders=0; y_status=''; y_skip=''
|
|
|
|
| 577 |
'session_title':slot.get('title') if slot else '',
|
| 578 |
'relay_dest':slot.get('dest') if slot else '',
|
| 579 |
'restarts':hub.restart_count(user),
|
| 580 |
+
'send_mode':snap.get('send_mode') or '',
|
| 581 |
}
|
| 582 |
|
| 583 |
def _cgroup_usage_ns():
|
|
|
|
| 786 |
'room_id':tsk.get('room_id') or '','source':tsk.get('source') or '',
|
| 787 |
'restarts':rs.get('restarts') or 0,'dest':rs.get('relay_dest') or '',
|
| 788 |
'last_error':tsk.get('last_error') or '','source_age':rs.get('source_age'),
|
| 789 |
+
'output_seconds':rs.get('output_seconds') or 0,
|
| 790 |
+
'send_mode':rs.get('send_mode') or ''})
|
| 791 |
res=resource_snapshot()
|
| 792 |
mgr=bool(youtube.manager_thread and youtube.manager_thread.is_alive())
|
| 793 |
y_events=0; y_hist=0; y_senders=0; y_status=''; y_skip=''
|
relay.py
CHANGED
|
@@ -116,6 +116,10 @@ class Sender:
|
|
| 116 |
d=dict(self.data)
|
| 117 |
stamp=d.get('last_source_at')
|
| 118 |
if stamp:d['source_age']=round(max(0.0,time.monotonic()-stamp),1)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
return d
|
| 120 |
def wait_until(self,condition,stop,poll=1.0,timeout=None):
|
| 121 |
"""Block while `condition()` holds; returns as soon as it stops or a stop is requested."""
|
|
|
|
| 116 |
d=dict(self.data)
|
| 117 |
stamp=d.get('last_source_at')
|
| 118 |
if stamp:d['source_age']=round(max(0.0,time.monotonic()-stamp),1)
|
| 119 |
+
try:
|
| 120 |
+
d['send_mode']=self.sticky_mode or self.mode_override or ''
|
| 121 |
+
except Exception:
|
| 122 |
+
d['send_mode']=''
|
| 123 |
return d
|
| 124 |
def wait_until(self,condition,stop,poll=1.0,timeout=None):
|
| 125 |
"""Block while `condition()` holds; returns as soon as it stops or a stop is requested."""
|
youtube_manager.py
CHANGED
|
@@ -141,13 +141,28 @@ class ManagedYouTube:
|
|
| 141 |
before the broadcast ends, and the next rendition must be reachable in the same tick.
|
| 142 |
"""
|
| 143 |
mode=os.getenv('YOUTUBE_VIDEO_MODE','h264').strip().lower()
|
| 144 |
-
|
| 145 |
-
if mode
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
@staticmethod
|
| 152 |
def _adult_account(user):
|
| 153 |
# ููุฏ ุฌู
ููุฑ 18+ ุบูุฑ ู
ุฏุนูู
ูู ูุงุฌูุฉ ููุชููุจ ุงูุฑุณู
ูุฉ (ageGating/ytRating ูุฑุงุกุฉ ููุท
|
|
|
|
| 141 |
before the broadcast ends, and the next rendition must be reachable in the same tick.
|
| 142 |
"""
|
| 143 |
mode=os.getenv('YOUTUBE_VIDEO_MODE','h264').strip().lower()
|
| 144 |
+
limit=int(os.getenv('YOUTUBE_SOURCE_LIMIT','6'))
|
| 145 |
+
if mode=='h264':
|
| 146 |
+
out=[c for c in sources if any(k in str(c.get('codec','')).lower() or k in str(c.get('label') or '').lower() for k in ('h264','avc'))]
|
| 147 |
+
elif mode=='original':
|
| 148 |
+
supported=[c for c in sources if any(k in str(c.get('label') or '').lower() for k in ('h264','avc','h265','hevc'))]
|
| 149 |
+
prefer=str(os.getenv('YOUTUBE_PREFER_H264','1')).strip().lower() in ('1','on','true','yes')
|
| 150 |
+
if prefer and os.getenv('YOUTUBE_SEND_MODE','auto').strip().lower() in ('auto','copy'):
|
| 151 |
+
supported=sorted(supported,key=lambda c:0 if any(k in str(c.get('codec','')).lower() for k in ('h264','avc')) else 1)
|
| 152 |
+
out=supported
|
| 153 |
+
else:
|
| 154 |
+
raise RuntimeError('YOUTUBE_VIDEO_MODE ูุฌุจ ุฃู ูููู original ุฃู h264')
|
| 155 |
+
# Measured on cpu-basic: 1440p+1280p copy pegged quota ~100%; two 1280p ~73% with stable pids.
|
| 156 |
+
# Additional concurrent session skips 1440p/2160p when a lighter H.264 rendition exists.
|
| 157 |
+
try:
|
| 158 |
+
busy=hub.active_count()
|
| 159 |
+
except Exception:
|
| 160 |
+
busy=0
|
| 161 |
+
if busy>=1:
|
| 162 |
+
light=[c for c in out if not any(x in str(c.get('label') or c.get('brief') or '') for x in ('1440','2160','4k','4K'))]
|
| 163 |
+
if light:
|
| 164 |
+
out=light
|
| 165 |
+
return out[:limit]
|
| 166 |
@staticmethod
|
| 167 |
def _adult_account(user):
|
| 168 |
# ููุฏ ุฌู
ููุฑ 18+ ุบูุฑ ู
ุฏุนูู
ูู ูุงุฌูุฉ ููุชููุจ ุงูุฑุณู
ูุฉ (ageGating/ytRating ูุฑุงุกุฉ ููุท
|