import 'dart:developer'; import 'package:flutter/widgets.dart'; import 'package:collection/collection.dart'; import 'package:fladder/util/localization_helper.dart'; import 'package:fladder/util/string_extensions.dart'; enum Bitrate { original(null), auto(0), b120Mbps(120000000), b80Mbps(80000000), b60Mbps(60000000), b40Mbps(40000000), b20Mbps(20000000), b15Mbps(15000000), b10Mbps(10000000), b8Mbps(8000000), b6Mbps(6000000), b4Mbps(4000000), b3Mbps(3000000), b1_5Mbps(1500000), b720Kbps(720000), b420Kbps(420000); final int? bitRate; const Bitrate(this.bitRate); int get calculatedBitRate => bitRate ?? -1; String label(BuildContext context) => switch (this) { Bitrate.original => context.localized.qualityOptionsOriginal, Bitrate.auto => context.localized.qualityOptionsAuto, _ => name.toString().replaceFirst('b', '').replaceAll('_', '.').toUpperCaseSplit() }; } class VideoQualitySettings { final Bitrate? maxBitRate; final int videoBitRate; final String? videoCodec; VideoQualitySettings({ required this.maxBitRate, required this.videoBitRate, required this.videoCodec, }); } Map getVideoQualityOptions(VideoQualitySettings options) { try { final maxStreamingBitrate = options.maxBitRate; final videoBitRate = options.videoBitRate; final videoCodec = options.videoCodec; double referenceBitRate = videoBitRate.toDouble(); final bitRateValues = Bitrate.values.where((value) => value.calculatedBitRate > 0).toSet(); final qualityOptions = {Bitrate.original, Bitrate.auto}; if (videoBitRate > 0 && videoBitRate < bitRateValues.first.calculatedBitRate) { if (videoCodec != null && ['hevc', 'av1', 'vp9'].contains(videoCodec) && referenceBitRate <= 20000000) { referenceBitRate *= 1.5; } final sourceOption = bitRateValues.where((value) => value.calculatedBitRate > referenceBitRate).lastOrNull; if (sourceOption != null) { qualityOptions.add(sourceOption); } } qualityOptions .addAll(bitRateValues.where((value) => videoBitRate <= 0 || value.calculatedBitRate <= referenceBitRate)); Bitrate? selectedQualityOption; if (maxStreamingBitrate != null && maxStreamingBitrate != Bitrate.original) { selectedQualityOption = qualityOptions .where((value) => value.calculatedBitRate > 0 && value.calculatedBitRate <= maxStreamingBitrate.calculatedBitRate) .firstOrNull; } return qualityOptions.toList().asMap().map( (_, bitrate) => MapEntry( bitrate, bitrate == maxStreamingBitrate || bitrate == selectedQualityOption, ), ); } catch (e) { log(e.toString()); return {}; } }