Hode / README.md
Reooiq's picture
Replace app entirely with Reoo88/Tktktk (TikTok->YouTube relay manager)
35c2217
|
Raw History Blame Contribute Delete
4.96 kB
---
title: '97'
sdk: docker
emoji: 🐨
colorFrom: pink
colorTo: gray
---
# إصلاحات مطلوبة — ملخص B / C / D
## B — عاصفة `start_sender()` ورمز 187
**المشكلة:** `tick()` / `drive_event()` كانت تستدعي `start_sender()` بلا شرط في أول الدورة، فتدفع `ffmpeg` إلى `rtmps://a.rtmps.youtube.com:443/live2` قبل أن يكون `liveBroadcast` مربوطًا وبحالة `ready/testing/live` → 7 إخفاقات 187 خلال 5 دقائق، بداية متأخرة 5:22 و ~116 ثانية ضائعة.
**الحل في `youtube_manager.py`:**
- `start_sender()` الآن تحرس نفسها:
```python
if not ev.get('bound') or not ev.get('broadcast_id'): return
if ev.get('youtube_status') in ('complete','revoked','created'): return
```
- `drive_event()` لم يعد يستدعيها فورًا بعد `ensure_broadcast()`. بدلًا من ذلك:
1. بعد `ensure_broadcast()` نحدث `ev` ونَمسح الملاحظة العالقة ثم نسقط إلى **بوابة مشروطة**
2. نقرأ `lifeCycleStatus` الحقيقي من `liveBroadcasts` (مع احترام كوتا 45 ث)
3. نسمح بالإرسال فقط إذا كانت `life in ('ready','testing','live')`، وإلا نُوقف المرسل ونكتب `انتظار جاهزية الاستقبال`
4. `life == 'live'` → نشغّل المرسل ثم `stream_health`، `ready/testing + streamStatus==active` → نطلب `transition` إلى `live`
النتيجة: لا دفع قبل وجود الـ ingest، لا عاصفة 187، ولا تأخير 5 دقائق.
---
## C — `youtube_api.py` بلا إعادة محاولة + الملاحظة لا تُمسح
**المشكلة 1:** `_request()` كانت تفعل `urlopen(timeout=25)` مرة واحدة. أي فشل TLS عابر → `SSLError / URLError` → تُرمى كـ `خطأ داخلي ... (SSLError)` وتكتبها `_event_error()` في `note` ولا شيء يمسحها → بقيت 40 دقيقة رغم أن البث سليم.
**الحل في `youtube_api.py`:**
- إضافة `import ssl`
- حلقة إعادة محاولة 3 مرات مع backoff أسي (1ث، 2ث، 4ث):
- `HTTP 429/500/502/503/504` → إعادة محاولة مع `1.2*(attempt+1)` ث
- `URLError, TimeoutError, OSError, ValueError, ssl.SSLError, SSLEOFError ...` → إعادة محاولة، ثم `APIError(None,'networkOrInvalidResponse')` فقط بعد نفاد المحاولات
- هذا يحول الفشل اللحظي لـ TLS من رسالة "حماية الأحداث" إلى نجاح صامت بعد ثانية.
**المشكلة 2:** `_event_error()` تكتب `note` ولا مسح عند التعافي.
**الحل في `youtube_manager.py`:**
- دالة جديدة `_clear_stale_error_note(key)` تمسح `note` إذا احتوت `حماية الأحداث` أو `خطأ داخلي` أو `networkOrInvalidResponse`
- تُستدعى في `drive_event()` في 4 نقاط تعافي:
1. بداية الدورة بعد تأكد `obs status == live`
2. بعد `ensure_stream()` ناجح
3. بعد `ensure_broadcast()` ناجح
4. بعد كل `remote('liveBroadcasts')` ناجح (التحقق الفعلي من الشبكة)
فإذا تعافت الشبكة، تختفي الملاحظة فورًا بدل 40 دقيقة.
---
## D — `Dockerfile.txt` في المستودع
**المشكلة:** رفعت `Dockerfile` باسم `Dockerfile.txt` (sha `89e0bc09` = نسختي السابقة) فتجاهله Docker وبنى من القديم بدون:
```
YOUTUBE_FORMAT_GUARD=off
YOUTUBE_FIFO_TIMESHIFT=10
YOUTUBE_HEALTH_INTERVAL=180
```
فبقي `timeshift=10` يعمل فقط من القيمة الافتراضية في `relay.py` (`ts = int(os.getenv('YOUTUBE_FIFO_TIMESHIFT','10'))`) ولم تكن واضحة في الـ image.
**الحل:**
- الملف المرفق `Dockerfile` هو النسخة الصحيحة (محتوى `Dockerfile.txt` السابق) — يحتوي كل متغيرات YouTube ingestion + التعليقات الكاملة.
- **احذف `Dockerfile.txt` من المستودع** (أو على الأقل لا ترفعه):
```bash
git rm Dockerfile.txt
git add Dockerfile youtube_api.py youtube_manager.py
git commit -m "fix: gate start_sender (187 storm), retry youtube_api TLS, clear stale note, fix Dockerfile name"
git push
```
- بعدها `docker build` سيقرأ `Dockerfile` الصحيح مباشرة، والقيم ستكون صريحة في الـ image وليس فقط default الكود.
---
## الملفات المرفقة
- `youtube_api.py` — مع retry
- `youtube_manager.py` — مع guard + مسح الملاحظة
- `Dockerfile` — النسخة الصحيحة (احذف Dockerfile.txt)
> كل الإصلاحات في الكود فقط كما طلبت، بلا تغيير سلوك الحالات السليمة، وباحترام كوتا YouTube (poll كل 45ث، health كل 180ث).