import Foundation enum PlaybackState: String { case idle case buffering case ready case ended } struct PlaybackSnapshot: Equatable { var mediaId: String? var positionMs: Int64 = 0 var durationMs: Int64 = -1 var bufferedPositionMs: Int64 = 0 var isPlaying = false var state: PlaybackState = .idle var speed: Float = 1 var sentenceIndex: Int? } struct PlayerConfig { var sentenceMode = true var defaultSeekStepMs: Int64 = 10_000 var autoPlay = false var continuousPlayback = true var minPlaybackSpeed: Float = 0.5 var maxPlaybackSpeed: Float = 2.0 } enum LoopMode { case off case one case all } enum SwipeAction { case none case rewind case forward case previousSentence case nextSentence case previousSentenceOrRewind case nextSentenceOrForward } enum GestureKind { case singleTap case swipeLeft case swipeRight case longPressSpeed } enum SwipeBackResult { case restartedCurrent case movedPrevious case stayedAtFirst case rewound } enum BoundaryState: Equatable { case idle case loading(isLocal: Bool) case loaded(count: Int) case failed(message: String) } /// 云端视频必须先完成整文件下载;下载未完成前不允许创建可播放的 AVPlayerItem。 enum VideoCacheState: Equatable { case notRequired case downloading case ready case failed(message: String) var statusMessage: String? { switch self { case .notRequired, .ready: return nil case .downloading: return "正在下载完整视频,下载完成后才能播放" case .failed(let message): return "视频缓存失败:\(message)" } } }