Add SRT/FLV/RTMP support and update documentation

Introduced Python scripts for SRT subtitle checking and fixing, and added comprehensive documentation covering advanced features such as protocol detection, subtitle/audio/quality management, keyboard shortcuts, and touch gestures. Updated local settings to allow new build and Python commands, added TypeScript definitions for FLV, and implemented RTMP/FLV protocol support in the player. Removed CHANGELOG.md and made various improvements to styles and example app.
This commit is contained in:
hibna
2025-11-03 02:35:56 +03:00
parent 42a12dfa8b
commit 36f83ff72c
26 changed files with 3833 additions and 1212 deletions
+281
View File
@@ -0,0 +1,281 @@
import re
from datetime import datetime, timedelta
def comprehensive_srt_check(file_path):
"""Kapsamlı SRT format kontrolü - tüm olası hataları yakalar."""
errors = []
warnings = []
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
i = 0
subtitle_count = 0
prev_end_time = None
while i < len(lines):
# Boş satırları atla
while i < len(lines) and lines[i].strip() == '':
i += 1
if i >= len(lines):
break
subtitle_count += 1
start_line = i + 1
# ===== 1. ALTYAZI NUMARASI KONTROLÜ =====
line_num = i + 1
line_content = lines[i].strip()
if not line_content:
errors.append(f"Satir {line_num}: Bos satir, altyazi numarasi bekleniyor")
i += 1
continue
if not line_content.isdigit():
errors.append(f"Satir {line_num}: Altyazi numarasi olmali, bulunan: '{line_content[:50]}'")
# Sonraki geçerli numarayı bulmaya çalış
while i < len(lines) and not lines[i].strip().isdigit():
i += 1
if i >= len(lines):
break
else:
actual_number = int(line_content)
if actual_number != subtitle_count:
warnings.append(f"Satir {line_num}: Numara sırası bozuk - beklenen: {subtitle_count}, bulunan: {actual_number}")
i += 1
# ===== 2. ZAMAN DAMGASI KONTROLÜ =====
if i >= len(lines):
errors.append(f"Altyazi {subtitle_count}: Zaman damgasi eksik (dosya sonu)")
break
line_num = i + 1
timestamp_line = lines[i].strip()
if not timestamp_line:
errors.append(f"Satir {line_num}: Bos satir, zaman damgasi bekleniyor")
i += 1
continue
# Zaman damgası formatını detaylı kontrol et
if '-->' not in timestamp_line:
errors.append(f"Satir {line_num}: '-->' ayirici bulunamadi: '{timestamp_line[:50]}'")
i += 1
continue
parts = timestamp_line.split('-->')
if len(parts) != 2:
errors.append(f"Satir {line_num}: Gecersiz zaman damgasi formati: '{timestamp_line[:50]}'")
i += 1
continue
start_time_str = parts[0].strip()
end_time_str = parts[1].strip()
# Başlangıç zamanı kontrolü
start_errors = validate_timestamp(start_time_str, "baslangic")
if start_errors:
for err in start_errors:
errors.append(f"Satir {line_num} {err}: '{start_time_str}'")
# Bitiş zamanı kontrolü
end_errors = validate_timestamp(end_time_str, "bitis")
if end_errors:
for err in end_errors:
errors.append(f"Satir {line_num} {err}: '{end_time_str}'")
# Zamanları parse et ve mantıksal kontroller yap
if not start_errors and not end_errors:
start_ms = parse_timestamp_to_ms(start_time_str)
end_ms = parse_timestamp_to_ms(end_time_str)
if start_ms is None or end_ms is None:
errors.append(f"Satir {line_num}: Zaman parse edilemedi: '{timestamp_line}'")
else:
# Başlangıç >= Bitiş kontrolü
if start_ms >= end_ms:
errors.append(f"Satir {line_num}: Baslangic zamani bitis zamanindan buyuk/esit: {start_time_str} >= {end_time_str}")
# Negatif zaman kontrolü
if start_ms < 0 or end_ms < 0:
errors.append(f"Satir {line_num}: Negatif zaman degeri: '{timestamp_line}'")
# Çok uzun altyazı kontrolü (>10 saniye)
duration_ms = end_ms - start_ms
if duration_ms > 10000:
warnings.append(f"Satir {line_num}: Cok uzun altyazi suresi ({duration_ms/1000:.1f} saniye): {start_time_str} --> {end_time_str}")
# Çok kısa altyazı kontrolü (<0.1 saniye)
if duration_ms < 100:
warnings.append(f"Satir {line_num}: Cok kisa altyazi suresi ({duration_ms}ms): {start_time_str} --> {end_time_str}")
# Önceki altyazı ile çakışma kontrolü
if prev_end_time is not None and start_ms < prev_end_time:
time_overlap = prev_end_time - start_ms
warnings.append(f"Satir {line_num}: Onceki altyazi ile cakisma ({time_overlap}ms): {start_time_str}")
prev_end_time = end_ms
i += 1
# ===== 3. METİN İÇERİĞİ KONTROLÜ =====
text_lines = []
text_start_line = i + 1
while i < len(lines) and lines[i].strip() != '':
# Bir sonraki satır numara mı kontrol et (yeni altyazı başlangıcı)
if (i + 1 < len(lines) and
lines[i].strip().isdigit() and
'-->' in lines[i + 1]):
break
text_lines.append(lines[i].rstrip())
i += 1
if not text_lines:
warnings.append(f"Altyazi {subtitle_count} (satir {start_line}): Metin icerigi bos")
else:
# Metin kontrolü
full_text = ' '.join([t.strip() for t in text_lines])
# Çok uzun metin kontrolü
if len(full_text) > 200:
warnings.append(f"Altyazi {subtitle_count}: Cok uzun metin ({len(full_text)} karakter)")
# HTML tag kontrolü
if re.search(r'<[^>]+>', full_text):
warnings.append(f"Altyazi {subtitle_count}: HTML/XML tag iceriyor (bazi oynaticilar desteklemeyebilir)")
# Garip karakterler
if re.search(r'[\x00-\x08\x0B-\x0C\x0E-\x1F]', full_text):
warnings.append(f"Altyazi {subtitle_count}: Kontrol karakterleri iceriyor")
return errors, warnings, subtitle_count
def validate_timestamp(time_str, time_type):
"""Tek bir zaman damgasını (HH:MM:SS,mmm) doğrular."""
errors = []
# Format: HH:MM:SS,mmm
pattern = r'^(\d{2}):(\d{2}):(\d{2}),(\d{3})$'
match = re.match(pattern, time_str)
if not match:
# Hangi kısım hatalı bul
if ',' not in time_str and '.' not in time_str:
errors.append(f"({time_type}): Milisaniye ayirici eksik (virgul)")
elif '.' in time_str:
errors.append(f"({time_type}): Milisaniye ayirici nokta olmamali, virgul olmali")
elif time_str.count(':') != 2:
errors.append(f"({time_type}): ':' ayirici sayisi yanlis (2 olmali)")
else:
# Rakam sayısı kontrolü
parts = time_str.replace(',', ':').replace('.', ':').split(':')
if len(parts) == 4:
hours, mins, secs, ms = parts
if len(hours) != 2:
errors.append(f"({time_type}): Saat 2 haneli olmali")
if len(mins) != 2:
errors.append(f"({time_type}): Dakika 2 haneli olmali")
if len(secs) != 2:
errors.append(f"({time_type}): Saniye 2 haneli olmali")
if len(ms) != 3:
errors.append(f"({time_type}): Milisaniye 3 haneli olmali")
else:
errors.append(f"({time_type}): Format hatasi (HH:MM:SS,mmm olmali)")
return errors
# Değer aralığı kontrolü
hours, mins, secs, ms = match.groups()
hours, mins, secs, ms = int(hours), int(mins), int(secs), int(ms)
if hours > 23:
warnings = [] # Videolar 24 saatten uzun olabilir, warning olarak işaretle
if mins > 59:
errors.append(f"({time_type}): Dakika 59'dan buyuk olamaz ({mins})")
if secs > 59:
errors.append(f"({time_type}): Saniye 59'dan buyuk olamaz ({secs})")
if ms > 999:
errors.append(f"({time_type}): Milisaniye 999'dan buyuk olamaz ({ms})")
return errors
def parse_timestamp_to_ms(time_str):
"""Zaman damgasını milisaniyeye çevirir."""
try:
# Format: HH:MM:SS,mmm
pattern = r'^(\d{2}):(\d{2}):(\d{2}),(\d{3})$'
match = re.match(pattern, time_str)
if not match:
return None
hours, mins, secs, ms = match.groups()
total_ms = (int(hours) * 3600 + int(mins) * 60 + int(secs)) * 1000 + int(ms)
return total_ms
except:
return None
def print_results(errors, warnings, subtitle_count, file_path):
"""Sonuçları yazdır."""
print(f"Dosya: {file_path}")
print(f"Toplam altyazi sayisi: {subtitle_count}")
print(f"\n{'='*70}")
if errors:
print(f"\nHATALAR ({len(errors)} adet):")
print("="*70)
for i, error in enumerate(errors[:100], 1):
print(f" {i}. {error}")
if len(errors) > 100:
print(f"\n ... ve {len(errors) - 100} hata daha")
else:
print("\nKritik hata bulunamadi!")
if warnings:
print(f"\nUYARILAR ({len(warnings)} adet):")
print("="*70)
for i, warning in enumerate(warnings[:50], 1):
print(f" {i}. {warning}")
if len(warnings) > 50:
print(f"\n ... ve {len(warnings) - 50} uyari daha")
else:
print("\nUyari bulunamadi!")
print(f"\n{'='*70}")
if not errors and not warnings:
print("\nSonuc: SRT dosyasi MUKEMMEL durumda!")
elif not errors:
print(f"\nSonuc: Format dogru ama {len(warnings)} uyari var")
else:
print(f"\nSonuc: {len(errors)} HATA, {len(warnings)} uyari")
return errors, warnings
if __name__ == "__main__":
import sys
file_path = sys.argv[1] if len(sys.argv) > 1 else "public/ses.srt"
print("\nKAPSAMLI SRT FORMAT KONTROLU")
print("="*70)
print("\nKontrol edilen hususlar:")
print(" - Altyazi numara sirasi")
print(" - Zaman damgasi formati (HH:MM:SS,mmm)")
print(" - Baslangic/bitis zaman mantigi")
print(" - Altyazi cakismalari")
print(" - Altyazi sureleri")
print(" - Metin icerigi")
print("="*70)
errors, warnings, subtitle_count = comprehensive_srt_check(file_path)
print_results(errors, warnings, subtitle_count, file_path)