import Foundation /// Eine einzelne Spur in einer Datei: Bild, Ton oder Untertitel. /// /// Die Feldnamen folgen der JSON-Antwort von Plex. Was dort fehlen darf, ist /// hier optional — Plex lässt bei unvollständig analysierten Dateien ganze /// Felder weg, und ein nicht-optionales Feld würde den gesamten Titel /// unlesbar machen statt nur eine Angabe. public struct PlexStream: Sendable, Equatable, Codable, Identifiable { /// Plex unterscheidet die Spurart über eine Zahl. public enum Kind: Int, Sendable, Codable { case video = 1 case audio = 2 case subtitle = 3 } public let id: Int public let streamType: Int public let codec: String? public let language: String? public let languageCode: String? public let displayTitle: String? public let title: String? /// Bei Ton: die Kanalzahl. Entscheidet mit darüber, ob AVPlayer den /// Ton annimmt — 5.1-DTS kann es nicht, 2.0-AAC schon. public let channels: Int? public let bitDepth: Int? /// Nur bei Untertiteln: liegt die Spur als eigene Datei neben dem Video? /// Solche lassen sich bei DirectPlay dazuschalten, eingebettete nicht /// immer. public let key: String? private let selected: Bool? private let `default`: Bool? private let forced: Bool? public var kind: Kind? { Kind(rawValue: streamType) } public var isSelected: Bool { selected ?? false } public var isDefault: Bool { `default` ?? false } public var isForced: Bool { forced ?? false } /// Untertitel, die als eigene Datei vorliegen. public var isExternal: Bool { key != nil } public init( id: Int, streamType: Int, codec: String? = nil, language: String? = nil, languageCode: String? = nil, displayTitle: String? = nil, title: String? = nil, channels: Int? = nil, bitDepth: Int? = nil, key: String? = nil, selected: Bool? = nil, default: Bool? = nil, forced: Bool? = nil ) { self.id = id self.streamType = streamType self.codec = codec self.language = language self.languageCode = languageCode self.displayTitle = displayTitle self.title = title self.channels = channels self.bitDepth = bitDepth self.key = key self.selected = selected self.default = `default` self.forced = forced } }