mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-08 17:40:28 +00:00
feat(hls): add native HLS (m3u8) download protocol (#1515)
This commit is contained in:
56 files changed
+4536
-6
No files matched your search
@@ -56,6 +56,7 @@ class ProtocolConfig {
|
||||
HttpConfig http = HttpConfig();
|
||||
BtConfig bt = BtConfig();
|
||||
Ed2kConfig ed2k = Ed2kConfig();
|
||||
HlsConfig hls = HlsConfig();
|
||||
|
||||
ProtocolConfig();
|
||||
|
||||
@@ -65,6 +66,25 @@ class ProtocolConfig {
|
||||
Map<String, dynamic> toJson() => _$ProtocolConfigToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class HlsConfig {
|
||||
int segmentConnections;
|
||||
int maxRetries;
|
||||
int timeoutSeconds;
|
||||
bool prefetchContentLength;
|
||||
|
||||
HlsConfig({
|
||||
this.segmentConnections = 0,
|
||||
this.maxRetries = 0,
|
||||
this.timeoutSeconds = 0,
|
||||
this.prefetchContentLength = false,
|
||||
});
|
||||
|
||||
factory HlsConfig.fromJson(Map<String, dynamic> json) => _$HlsConfigFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$HlsConfigToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class HttpConfig {
|
||||
String userAgent;
|
||||
|
||||
@@ -56,12 +56,28 @@ Map<String, dynamic> _$ApiServerConfigToJson(ApiServerConfig instance) => <Strin
|
||||
ProtocolConfig _$ProtocolConfigFromJson(Map<String, dynamic> json) => ProtocolConfig()
|
||||
..http = HttpConfig.fromJson(json['http'] as Map<String, dynamic>)
|
||||
..bt = BtConfig.fromJson(json['bt'] as Map<String, dynamic>)
|
||||
..ed2k = Ed2kConfig.fromJson(json['ed2k'] as Map<String, dynamic>);
|
||||
..ed2k = Ed2kConfig.fromJson(json['ed2k'] as Map<String, dynamic>)
|
||||
..hls = HlsConfig.fromJson(json['hls'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$ProtocolConfigToJson(ProtocolConfig instance) => <String, dynamic>{
|
||||
'http': instance.http.toJson(),
|
||||
'bt': instance.bt.toJson(),
|
||||
'ed2k': instance.ed2k.toJson(),
|
||||
'hls': instance.hls.toJson(),
|
||||
};
|
||||
|
||||
HlsConfig _$HlsConfigFromJson(Map<String, dynamic> json) => HlsConfig(
|
||||
segmentConnections: (json['segmentConnections'] as num?)?.toInt() ?? 0,
|
||||
maxRetries: (json['maxRetries'] as num?)?.toInt() ?? 0,
|
||||
timeoutSeconds: (json['timeoutSeconds'] as num?)?.toInt() ?? 0,
|
||||
prefetchContentLength: json['prefetchContentLength'] as bool? ?? false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$HlsConfigToJson(HlsConfig instance) => <String, dynamic>{
|
||||
'segmentConnections': instance.segmentConnections,
|
||||
'maxRetries': instance.maxRetries,
|
||||
'timeoutSeconds': instance.timeoutSeconds,
|
||||
'prefetchContentLength': instance.prefetchContentLength,
|
||||
};
|
||||
|
||||
HttpConfig _$HttpConfigFromJson(Map<String, dynamic> json) => HttpConfig(
|
||||
|
||||
@@ -6,7 +6,7 @@ part 'task.g.dart';
|
||||
|
||||
enum Status { ready, running, pause, wait, error, done }
|
||||
|
||||
enum Protocol { http, bt, ed2k }
|
||||
enum Protocol { http, bt, ed2k, hls }
|
||||
|
||||
// ExtractStatus enum matching Go backend
|
||||
enum ExtractStatus {
|
||||
|
||||
@@ -38,7 +38,7 @@ const _$StatusEnumMap = {
|
||||
Status.done: 'done',
|
||||
};
|
||||
|
||||
const _$ProtocolEnumMap = {Protocol.http: 'http', Protocol.bt: 'bt', Protocol.ed2k: 'ed2k'};
|
||||
const _$ProtocolEnumMap = {Protocol.http: 'http', Protocol.bt: 'bt', Protocol.ed2k: 'ed2k', Protocol.hls: 'hls'};
|
||||
|
||||
Progress _$ProgressFromJson(Map<String, dynamic> json) => Progress(
|
||||
used: (json['used'] as num).toInt(),
|
||||
|
||||
@@ -55,7 +55,7 @@ sealed class TaskStats {
|
||||
Protocol.http => HttpTaskStats.fromJson(snapshot),
|
||||
Protocol.bt => BtTaskStats.fromJson(snapshot: snapshot, runtime: runtime),
|
||||
Protocol.ed2k => Ed2kTaskStats.fromJson(snapshot: snapshot, runtime: runtime),
|
||||
null => null,
|
||||
Protocol.hls || null => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
final _maxRunningController = TextEditingController();
|
||||
final _httpUserAgentController = TextEditingController();
|
||||
final _httpConnectionsController = TextEditingController();
|
||||
final _hlsConnectionsController = TextEditingController();
|
||||
final _hlsMaxRetriesController = TextEditingController();
|
||||
final _btListenPortController = TextEditingController();
|
||||
final _btSeedRatioController = TextEditingController();
|
||||
final _btSeedTimeController = TextEditingController();
|
||||
@@ -96,6 +98,8 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
_maxRunningController,
|
||||
_httpUserAgentController,
|
||||
_httpConnectionsController,
|
||||
_hlsConnectionsController,
|
||||
_hlsMaxRetriesController,
|
||||
_btListenPortController,
|
||||
_btSeedRatioController,
|
||||
_btSeedTimeController,
|
||||
@@ -572,6 +576,32 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
_SettingsBlock(
|
||||
key: const ValueKey('settings-hls-block'),
|
||||
title: 'HLS',
|
||||
child: _SettingsGroup(
|
||||
children: [
|
||||
SettingsItem(
|
||||
title: context.l10n.connections,
|
||||
child: _NumberSettingControl(
|
||||
fieldKey: const ValueKey('hls-connections-input'),
|
||||
controller: _hlsConnectionsController,
|
||||
min: 1,
|
||||
max: 256,
|
||||
),
|
||||
),
|
||||
SettingsItem(
|
||||
title: context.l10n.maxRetries,
|
||||
child: _NumberSettingControl(
|
||||
fieldKey: const ValueKey('hls-max-retries-input'),
|
||||
controller: _hlsMaxRetriesController,
|
||||
min: 0,
|
||||
max: 30,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_SettingsBlock(
|
||||
title: 'BitTorrent',
|
||||
child: _SettingsGroup(
|
||||
@@ -953,6 +983,8 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
_maxRunningController.text = _config!.maxRunning.clamp(1, 256).toString();
|
||||
_httpUserAgentController.text = _config!.protocolConfig.http.userAgent;
|
||||
_httpConnectionsController.text = _config!.protocolConfig.http.connections.clamp(1, 256).toString();
|
||||
_hlsConnectionsController.text = _config!.protocolConfig.hls.segmentConnections.clamp(1, 256).toString();
|
||||
_hlsMaxRetriesController.text = _config!.protocolConfig.hls.maxRetries.clamp(0, 30).toString();
|
||||
_btListenPortController.text = _config!.protocolConfig.bt.listenPort.clamp(0, 65535).toString();
|
||||
_btSeedRatioController.text = _config!.protocolConfig.bt.seedRatio.toString();
|
||||
_btSeedTimeController.text = (_config!.protocolConfig.bt.seedTime ~/ 60).clamp(0, 100000000).toString();
|
||||
@@ -1048,6 +1080,18 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
min: 1,
|
||||
max: 256,
|
||||
);
|
||||
config.protocolConfig.hls.segmentConnections = _boundedInt(
|
||||
_hlsConnectionsController,
|
||||
fallback: config.protocolConfig.hls.segmentConnections,
|
||||
min: 1,
|
||||
max: 256,
|
||||
);
|
||||
config.protocolConfig.hls.maxRetries = _boundedInt(
|
||||
_hlsMaxRetriesController,
|
||||
fallback: config.protocolConfig.hls.maxRetries,
|
||||
min: 0,
|
||||
max: 30,
|
||||
);
|
||||
config.protocolConfig.bt.listenPort = _boundedInt(
|
||||
_btListenPortController,
|
||||
fallback: config.protocolConfig.bt.listenPort,
|
||||
|
||||
@@ -294,7 +294,7 @@ TaskAssetType _assetType(String name, {required bool isFolder, required api_task
|
||||
return switch (protocol) {
|
||||
api_task.Protocol.bt => TaskAssetType.torrent,
|
||||
api_task.Protocol.ed2k => TaskAssetType.ed2k,
|
||||
api_task.Protocol.http || null => TaskAssetType.file,
|
||||
api_task.Protocol.hls || api_task.Protocol.http || null => TaskAssetType.file,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "حفظ كمجلد التنزيل الافتراضي",
|
||||
"downloadDirValid": "الرجاء تحديد مجلد التنزيل",
|
||||
"connections": "الاتصالات",
|
||||
"maxRetries": "الحد الأقصى لإعادة المحاولات",
|
||||
"useServerCtime": "استخدام وقت الخادم لإنشاء الملف",
|
||||
"maxRunning": "الحد الأقصى للمهام المتزامنة",
|
||||
"defaultDirectDownload": "تفعيل التنزيل المباشر افتراضياً",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Standart endirmə qovluğu kimi yadda saxla",
|
||||
"downloadDirValid": "Zəhmət olmasa endirmə qovluğunu seçin",
|
||||
"connections": "Əlaqələr",
|
||||
"maxRetries": "Maksimum cəhd sayı",
|
||||
"useServerCtime": "Fayl yaratma tarixi üçün server vaxtından istifadə et",
|
||||
"maxRunning": "Paralel Endirmələr",
|
||||
"defaultDirectDownload": "Standart olaraq Birbaşa Endirmə",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Desa com a carpeta de baixades predeterminada",
|
||||
"downloadDirValid": "Seleccioneu la carpeta de baixades",
|
||||
"connections": "Connexions",
|
||||
"maxRetries": "Reintents màxims",
|
||||
"useServerCtime": "Utilitza l'hora del servidor per a la creació de fitxers",
|
||||
"maxRunning": "Màxim de tasques en execució",
|
||||
"defaultDirectDownload": "Activa la baixada directa per defecte",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Als Standard-Downloadordner speichern",
|
||||
"downloadDirValid": "Bitte wählen Sie das Download-Verzeichnis",
|
||||
"connections": "Anschlüsse",
|
||||
"maxRetries": "Maximale Wiederholungsversuche",
|
||||
"useServerCtime": "Serverzeit für die Dateierstellung verwenden",
|
||||
"maxRunning": "Maximale Anzahl ausgeführter Aufgaben",
|
||||
"defaultDirectDownload": "Direkten Download standardmäßig aktivieren",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Save as default download directory",
|
||||
"downloadDirValid": "Please select the download directory",
|
||||
"connections": "Connections",
|
||||
"maxRetries": "Max retries",
|
||||
"useServerCtime": "Use server time for file creation",
|
||||
"maxRunning": "Concurrent Downloads",
|
||||
"defaultDirectDownload": "Direct Download by Default",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Guardar como carpeta de descargas predeterminada",
|
||||
"downloadDirValid": "Por favor, selecciona el directorio de descarga",
|
||||
"connections": "Conexiones",
|
||||
"maxRetries": "Reintentos máximos",
|
||||
"useServerCtime": "Usar tiempo del servidor para la creación de archivos",
|
||||
"maxRunning": "Máximo de Tareas en Ejecución",
|
||||
"defaultDirectDownload": "Ver descarga directa por defecto",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "ذخیره بهعنوان پوشه پیشفرض دانلود",
|
||||
"downloadDirValid": "لطفا دایرکتوری دانلود را انتخاب کنید",
|
||||
"connections": "اتصالات",
|
||||
"maxRetries": "حداکثر تلاش مجدد",
|
||||
"useServerCtime": "استفاده از زمان سرور برای ایجاد فایل",
|
||||
"maxRunning": "حداکثر وظایف در حال اجرا",
|
||||
"defaultDirectDownload": "دانلود مستقیم را به صورت پیش فرض بررسی کنید",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Enregistrer comme dossier de téléchargement par défaut",
|
||||
"downloadDirValid": "Veuillez sélectionner le répertoire de téléchargement",
|
||||
"connections": "Connexions",
|
||||
"maxRetries": "Nombre maximal de tentatives",
|
||||
"useServerCtime": "Utiliser l'heure du serveur pour la création de fichier",
|
||||
"maxRunning": "Tâches en cours maximum",
|
||||
"defaultDirectDownload": "Vérifiez le téléchargement direct par défaut",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Mentés alapértelmezett letöltési mappaként",
|
||||
"downloadDirValid": "Kérjük, válassza ki a letöltési könyvtárat",
|
||||
"connections": "Kapcsolatok",
|
||||
"maxRetries": "Maximális újrapróbálkozások",
|
||||
"useServerCtime": "Használja a szerveridőt a fájl létrehozásához",
|
||||
"maxRunning": "Maximális futó feladatok",
|
||||
"defaultDirectDownload": "Alapértelmezettként ellenőrizze a közvetlen letöltést",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Simpan sebagai folder unduhan default",
|
||||
"downloadDirValid": "Silahkan pilih direktori unduhan",
|
||||
"connections": "Koneksi",
|
||||
"maxRetries": "Percobaan ulang maks.",
|
||||
"useServerCtime": "Gunakan waktu server untuk pembuatan file",
|
||||
"maxRunning": "Tugas Maksimum yang Berjalan",
|
||||
"defaultDirectDownload": "Pilih unduhan langsung sebagai opsi standar",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Salva come cartella di download predefinita",
|
||||
"downloadDirValid": "Seleziona la directory di scaricamento",
|
||||
"connections": "Connessioni",
|
||||
"maxRetries": "Tentativi massimi",
|
||||
"useServerCtime": "Utilizza l'ora del server per la creazione dei file",
|
||||
"maxRunning": "Numero massimo di attività in esecuzione",
|
||||
"defaultDirectDownload": "Controlla il download diretto per impostazione predefinita",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "デフォルトのダウンロード先として保存",
|
||||
"downloadDirValid": "ダウンロードディレクトリを選択してください",
|
||||
"connections": "接続",
|
||||
"maxRetries": "最大リトライ回数",
|
||||
"useServerCtime": "ファイル作成時にサーバー時間を使用する",
|
||||
"maxRunning": "最大実行タスク",
|
||||
"defaultDirectDownload": "デフォルトで直接ダウンロードにチェックを入れる",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "기본 다운로드 폴더로 저장",
|
||||
"downloadDirValid": "다운로드 폴더를 선택해 주세요",
|
||||
"connections": "연결 수",
|
||||
"maxRetries": "최대 재시도 횟수",
|
||||
"useServerCtime": "파일 생성 시간에 서버 시간 사용",
|
||||
"maxRunning": "최대 동시 작업 수",
|
||||
"defaultDirectDownload": "기본으로 바로 다운로드 사용",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Zapisz jako domyślny folder pobierania",
|
||||
"downloadDirValid": "Wskaż folder pobierania",
|
||||
"connections": "Połączenia",
|
||||
"maxRetries": "Maks. liczba ponownych prób",
|
||||
"useServerCtime": "Użyj czasu serwera do utworzenia pliku",
|
||||
"maxRunning": "Maksymalna liczba zadań",
|
||||
"defaultDirectDownload": "Domyślnie sprawdź bezpośredni pobór",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Salvar como pasta de download padrão",
|
||||
"downloadDirValid": "Por favor, selecione a pasta",
|
||||
"connections": "Conexões",
|
||||
"maxRetries": "Tentativas máximas",
|
||||
"useServerCtime": "Usar o tempo de servidor para a criação de ficheiros",
|
||||
"maxRunning": "Máximo de Tarefas Simultâneas",
|
||||
"defaultDirectDownload": "Marcar download direto por padrão",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Сохранить как папку загрузок по умолчанию",
|
||||
"downloadDirValid": "Пожалуйста, выберите папку для загрузки",
|
||||
"connections": "Соединений",
|
||||
"maxRetries": "Макс. число повторов",
|
||||
"useServerCtime": "Использовать время сервера для создания файла",
|
||||
"maxRunning": "Максимальное количество активных задач",
|
||||
"defaultDirectDownload": "Прямая загрузка по умолчанию",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "இயல்புநிலை பதிவிறக்க கோப்புறையாக சேமி",
|
||||
"downloadDirValid": "பதிவிரக்குமிடத்தை தேர்வு செயுங்கள்",
|
||||
"connections": "தொடர்புகள்",
|
||||
"maxRetries": "அதிகபட்ச மறுமுயற்சிகள்",
|
||||
"useServerCtime": "கோப்பு உருவாக்க சேவையக நேரத்தைப் பயன்படுத்தவும்",
|
||||
"maxRunning": "அதிகபட்ச இயங்கும் பணிகள்",
|
||||
"defaultDirectDownload": "இயல்புநிலையாக நேரடிப் பதிவிறக்கத்தைச் சரிபார்க்கவும்",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Varsayılan indirme klasörü olarak kaydet",
|
||||
"downloadDirValid": "Lütfen indirme dizinini seçin",
|
||||
"connections": "Bağlantılar",
|
||||
"maxRetries": "Maksimum yeniden deneme",
|
||||
"useServerCtime": "Dosya oluşturma tarihi için sunucu zamanını kullan",
|
||||
"maxRunning": "Maksimum Çalışan İşlem",
|
||||
"defaultDirectDownload": "Varsayılan olarak direkt indirmeyi işaretle",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Зберегти як типову папку завантажень",
|
||||
"downloadDirValid": "Будь ласка, виберіть каталог завантажень",
|
||||
"connections": "З’єднання",
|
||||
"maxRetries": "Макс. кількість повторів",
|
||||
"useServerCtime": "Використовувати час сервера для створення файлу",
|
||||
"maxRunning": "Макс. завдань у черзі",
|
||||
"defaultDirectDownload": "Пряме завантаження за замовчуванням",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "Lưu làm thư mục tải xuống mặc định",
|
||||
"downloadDirValid": "Vui lòng chọn thư mục tải về",
|
||||
"connections": "Kết nối",
|
||||
"maxRetries": "Số lần thử lại tối đa",
|
||||
"useServerCtime": "Sử dụng thời gian máy chủ cho việc tạo tệp",
|
||||
"maxRunning": "Số nhiệm vụ tối đa",
|
||||
"defaultDirectDownload": "Kiểm tra trực tiếp tải về theo mặc định",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "保存为默认下载目录",
|
||||
"downloadDirValid": "请选择下载目录",
|
||||
"connections": "连接数",
|
||||
"maxRetries": "最大重试次数",
|
||||
"useServerCtime": "创建文件使用服务器时间",
|
||||
"maxRunning": "最大下载数",
|
||||
"defaultDirectDownload": "默认启用直接下载",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"rememberLastDownloadDir": "儲存為預設下載目錄",
|
||||
"downloadDirValid": "請選擇下載目錄",
|
||||
"connections": "連接數",
|
||||
"maxRetries": "最大重試次數",
|
||||
"useServerCtime": "使用伺服器時間作為檔案建立時間",
|
||||
"maxRunning": "最大執行任務數",
|
||||
"defaultDirectDownload": "預設勾選直接下載",
|
||||
|
||||
Reference in new issue
Block a user