import AVFoundation import CoreMedia import Foundation public extension SubtitleStyle { /// Die Regeln, wie AVFoundation sie erwartet. /// /// **Vier Fallen stecken hier drin, und jede ist lautlos:** /// /// 1. **Die Farbe ist ein Feld aus vier Zahlen von 0 bis 1, Alpha /// zuerst** — A, R, G, B. Kein `CGColor`, kein `UIColor`; ein solcher /// wird ohne Fehlermeldung ignoriert. /// 2. **Die Grösse ist ein Prozentwert**, hundert heisst unverändert. /// `BaseFontSizePercentageRelativeToVideoHeight` **nicht** zusätzlich /// setzen — die beiden beziehen sich auf Verschiedenes und streiten /// sich. /// 3. **Den Hintergrund immer setzen, auch für „durchsichtig".** Ihn /// wegzulassen ist nicht dasselbe wie Alpha null: dann gilt, was der /// Untertitel selbst mitbringt, und Jellyfins WebVTT bringt oft einen /// schwarzen Kasten mit. /// 4. **`AVTextStyleRule(textMarkupAttributes:)` kann fehlschlagen.** Ein /// falscher Schlüssel ergibt `nil` — und damit gar keine Regel, ohne /// dass irgendwo etwas auffiele. Genau dafür gibt es den Test. var textStyleRules: [AVTextStyleRule] { var attribute: [String: Any] = [ kCMTextMarkupAttribute_ForegroundColorARGB as String: foreground.argb, kCMTextMarkupAttribute_BackgroundColorARGB as String: background.argb, kCMTextMarkupAttribute_RelativeFontSize as String: Double(size.rawValue), ] if wantsEdgeShadow { attribute[kCMTextMarkupAttribute_CharacterEdgeStyle as String] = kCMTextMarkupCharacterEdgeStyle_DropShadow as String } return [AVTextStyleRule(textMarkupAttributes: attribute)].compactMap(\.self) } } extension SubtitleStyle.RGBA { /// Alpha zuerst — die Reihenfolge, die CoreMedia verlangt. var argb: [NSNumber] { [alpha, red, green, blue].map(NSNumber.init(value:)) } }