package services import ( "go.uber.org/zap" ) // BitrateStrategy représente une stratégie d'adaptation de bitrate // T0361: Create Bitrate Adaptation Strategy Service type BitrateStrategy string const ( // StrategyConservative est une stratégie conservatrice qui adapte le bitrate // seulement quand les conditions sont vraiment défavorables StrategyConservative BitrateStrategy = "conservative" // StrategyAggressive est une stratégie agressive qui adapte le bitrate // rapidement pour éviter les problèmes de streaming StrategyAggressive BitrateStrategy = "aggressive" // StrategyBalanced est une stratégie équilibrée entre conservative et aggressive StrategyBalanced BitrateStrategy = "balanced" ) // StrategyThresholds représente les seuils pour une stratégie type StrategyThresholds struct { BufferLevelThreshold float64 // Seuil de niveau de buffer (0.0 à 1.0) BandwidthRatioThreshold float64 // Seuil de ratio de bande passante (0.0 à 1.0) UseOrCondition bool // Si true, utilise OR au lieu de AND } // BitrateStrategyService gère les stratégies d'adaptation de bitrate type BitrateStrategyService struct { logger *zap.Logger } // NewBitrateStrategyService crée un nouveau service de stratégies d'adaptation func NewBitrateStrategyService(logger *zap.Logger) *BitrateStrategyService { if logger == nil { logger = zap.NewNop() } return &BitrateStrategyService{ logger: logger, } } // GetThresholds retourne les seuils pour une stratégie donnée func (s *BitrateStrategyService) GetThresholds(strategy BitrateStrategy) StrategyThresholds { switch strategy { case StrategyConservative: // Conservative: adapte seulement si buffer ET bande passante sont faibles return StrategyThresholds{ BufferLevelThreshold: 0.3, // 30% de buffer BandwidthRatioThreshold: 0.7, // 70% de la bande passante nécessaire UseOrCondition: false, // Utilise AND } case StrategyAggressive: // Aggressive: adapte si buffer OU bande passante est faible return StrategyThresholds{ BufferLevelThreshold: 0.15, // 15% de buffer BandwidthRatioThreshold: 0.5, // 50% de la bande passante nécessaire UseOrCondition: true, // Utilise OR } case StrategyBalanced: fallthrough default: // Balanced: adapte si buffer ET bande passante sont modérément faibles return StrategyThresholds{ BufferLevelThreshold: 0.2, // 20% de buffer BandwidthRatioThreshold: 0.6, // 60% de la bande passante nécessaire UseOrCondition: false, // Utilise AND } } } // ShouldAdapt détermine si une adaptation de bitrate est nécessaire // selon la stratégie, le niveau de buffer et le ratio de bande passante // bufferLevel: niveau de buffer (0.0 = vide, 1.0 = plein) // bandwidthRatio: ratio de bande passante disponible / nécessaire (0.0 à 1.0+) // Retourne true si une adaptation est nécessaire func (s *BitrateStrategyService) ShouldAdapt(strategy BitrateStrategy, bufferLevel float64, bandwidthRatio float64) bool { thresholds := s.GetThresholds(strategy) // Valider les paramètres if bufferLevel < 0 || bufferLevel > 1 { s.logger.Warn("Invalid buffer level", zap.Float64("buffer_level", bufferLevel), zap.String("strategy", string(strategy))) return false } if bandwidthRatio < 0 { s.logger.Warn("Invalid bandwidth ratio", zap.Float64("bandwidth_ratio", bandwidthRatio), zap.String("strategy", string(strategy))) return false } // Vérifier si le buffer est faible bufferLow := bufferLevel < thresholds.BufferLevelThreshold // Vérifier si la bande passante est faible // bandwidthRatio < threshold signifie que la bande passante disponible // est inférieure au seuil requis bandwidthLow := bandwidthRatio < thresholds.BandwidthRatioThreshold // Appliquer la logique selon la stratégie if thresholds.UseOrCondition { // OR: adapter si buffer OU bande passante est faible return bufferLow || bandwidthLow } else { // AND: adapter seulement si buffer ET bande passante sont faibles return bufferLow && bandwidthLow } } // SelectStrategy sélectionne une stratégie selon le contexte // networkStability: stabilité du réseau (0.0 = instable, 1.0 = stable) // userPreference: préférence de l'utilisateur (peut être nil pour auto) // Retourne la stratégie recommandée func (s *BitrateStrategyService) SelectStrategy(networkStability float64, userPreference *BitrateStrategy) BitrateStrategy { // Si l'utilisateur a une préférence, l'utiliser if userPreference != nil { return *userPreference } // Sélectionner automatiquement selon la stabilité du réseau if networkStability < 0.3 { // Réseau instable: utiliser une stratégie conservative return StrategyConservative } else if networkStability > 0.7 { // Réseau stable: utiliser une stratégie aggressive pour meilleure qualité return StrategyAggressive } else { // Réseau modéré: utiliser une stratégie balanced return StrategyBalanced } } // IsValidStrategy vérifie si une stratégie est valide func (s *BitrateStrategyService) IsValidStrategy(strategy BitrateStrategy) bool { return strategy == StrategyConservative || strategy == StrategyAggressive || strategy == StrategyBalanced }