import 'emby_ticks.dart'; String? formatRuntimeMinutes(int? minutes) { if (minutes == null || minutes <= 0) return null; final h = minutes ~/ 60; final m = minutes % 60; if (h > 0) return m > 0 ? '$h小时$m分钟' : '$h小时'; return '$m分钟'; } String formatFileSize(int bytes) { if (bytes >= 1073741824) { return '${(bytes / 1073741824).toStringAsFixed(2)}G'; } if (bytes >= 1048576) { return '${(bytes / 1048576).toStringAsFixed(0)}M'; } return '${(bytes / 1024).toStringAsFixed(0)}K'; } String? formatEpisodeNumber(int? index) { if (index == null) return null; return '第$index集'; } String? formatSeasonNumber(int? season) { if (season == null) return null; return '第$season季'; } double? downloadProgressValue({required int received, required int total}) { if (total <= 0) return null; final value = received / total; return value.clamp(0, 1).toDouble(); } String formatDownloadBytes(int bytes) { if (bytes <= 0) return '-- MB'; return '${(bytes / 1024 / 1024).toStringAsFixed(1)} MB'; } String formatDownloadSpeed(double bytesPerSec) { if (bytesPerSec <= 0) return '0 B/s'; if (bytesPerSec >= 1024 * 1024) { return '${(bytesPerSec / (1024 * 1024)).toStringAsFixed(1)} MB/s'; } if (bytesPerSec >= 1024) { return '${(bytesPerSec / 1024).toStringAsFixed(0)} KB/s'; } return '${bytesPerSec.toStringAsFixed(0)} B/s'; } String formatDurationClock(Duration duration) { final h = duration.inHours; final m = duration.inMinutes.remainder(60).toString().padLeft(2, '0'); final s = duration.inSeconds.remainder(60).toString().padLeft(2, '0'); return h > 0 ? '$h:$m:$s' : '$m:$s'; } String formatTicksAsClock(int ticks) => formatDurationClock(ticks <= 0 ? Duration.zero : durationFromTicks(ticks));