Files
streamyfin/docs/ks-player/KSOptions.md

350 lines
9.6 KiB
Markdown

# KSOptions
`KSOptions` is the configuration class for KSPlayer. It contains both instance properties (per-player settings) and static properties (global defaults).
## Creating Options
```swift
let options = KSOptions()
// Configure instance properties
options.isLoopPlay = true
options.startPlayTime = 30.0 // Start at 30 seconds
// Use with player
playerView.set(url: url, options: options)
```
## Instance Properties
### Buffering
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `preferredForwardBufferDuration` | `TimeInterval` | `3.0` | Minimum buffer duration before playback starts |
| `maxBufferDuration` | `TimeInterval` | `30.0` | Maximum buffer duration |
| `isSecondOpen` | `Bool` | `false` | Enable fast open (instant playback) |
### Seeking
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `isAccurateSeek` | `Bool` | `false` | Enable frame-accurate seeking |
| `seekFlags` | `Int32` | `1` | FFmpeg seek flags (AVSEEK_FLAG_BACKWARD) |
| `isSeekedAutoPlay` | `Bool` | `true` | Auto-play after seeking |
### Playback
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `isLoopPlay` | `Bool` | `false` | Loop playback (for short videos) |
| `startPlayTime` | `TimeInterval` | `0` | Initial playback position (seconds) |
| `startPlayRate` | `Float` | `1.0` | Initial playback rate |
| `registerRemoteControll` | `Bool` | `true` | Enable system remote control |
### Video
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `display` | `DisplayEnum` | `.plane` | Display mode (`.plane`, `.vr`, `.vrBox`) |
| `videoDelay` | `Double` | `0.0` | Video delay in seconds |
| `autoDeInterlace` | `Bool` | `false` | Auto-detect interlacing |
| `autoRotate` | `Bool` | `true` | Auto-rotate based on metadata |
| `destinationDynamicRange` | `DynamicRange?` | `nil` | Target HDR mode |
| `videoAdaptable` | `Bool` | `true` | Enable adaptive bitrate |
| `videoFilters` | `[String]` | `[]` | FFmpeg video filters |
| `syncDecodeVideo` | `Bool` | `false` | Synchronous video decoding |
| `hardwareDecode` | `Bool` | `true` | Use hardware decoding |
| `asynchronousDecompression` | `Bool` | `false` | Async hardware decompression |
| `videoDisable` | `Bool` | `false` | Disable video track |
### Audio
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `audioFilters` | `[String]` | `[]` | FFmpeg audio filters |
| `syncDecodeAudio` | `Bool` | `false` | Synchronous audio decoding |
### Subtitles
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `autoSelectEmbedSubtitle` | `Bool` | `true` | Auto-select embedded subtitles |
| `isSeekImageSubtitle` | `Bool` | `false` | Seek for image subtitles |
### Picture-in-Picture
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `canStartPictureInPictureAutomaticallyFromInline` | `Bool` | `true` | Auto-start PiP when app backgrounds |
### Window (macOS)
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `automaticWindowResize` | `Bool` | `true` | Auto-resize window to video aspect ratio |
### Network/HTTP
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `referer` | `String?` | `nil` | HTTP referer header |
| `userAgent` | `String?` | `"KSPlayer"` | HTTP user agent |
| `cache` | `Bool` | `false` | Enable FFmpeg HTTP caching |
| `outputURL` | `URL?` | `nil` | URL to record/save stream |
### FFmpeg Options
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `avOptions` | `[String: Any]` | `[:]` | AVURLAsset options |
| `formatContextOptions` | `[String: Any]` | See below | FFmpeg format context options |
| `decoderOptions` | `[String: Any]` | See below | FFmpeg decoder options |
| `probesize` | `Int64?` | `nil` | FFmpeg probe size |
| `maxAnalyzeDuration` | `Int64?` | `nil` | Max analyze duration |
| `lowres` | `UInt8` | `0` | Low resolution decoding |
| `nobuffer` | `Bool` | `false` | Disable buffering |
| `codecLowDelay` | `Bool` | `false` | Low delay codec mode |
#### Default formatContextOptions
```swift
[
"user_agent": "KSPlayer",
"scan_all_pmts": 1,
"reconnect": 1,
"reconnect_streamed": 1
]
```
#### Default decoderOptions
```swift
[
"threads": "auto",
"refcounted_frames": "1"
]
```
### Read-Only Timing Properties
| Property | Type | Description |
|----------|------|-------------|
| `formatName` | `String` | Detected format name |
| `prepareTime` | `Double` | Time when prepare started |
| `dnsStartTime` | `Double` | DNS lookup start time |
| `tcpStartTime` | `Double` | TCP connection start time |
| `tcpConnectedTime` | `Double` | TCP connected time |
| `openTime` | `Double` | File open time |
| `findTime` | `Double` | Stream find time |
| `readyTime` | `Double` | Ready to play time |
| `readAudioTime` | `Double` | First audio read time |
| `readVideoTime` | `Double` | First video read time |
| `decodeAudioTime` | `Double` | First audio decode time |
| `decodeVideoTime` | `Double` | First video decode time |
## Static Properties (Global Defaults)
### Player Types
```swift
// Primary player type (default: AVPlayer)
KSOptions.firstPlayerType: MediaPlayerProtocol.Type = KSAVPlayer.self
// Fallback player type (default: FFmpeg)
KSOptions.secondPlayerType: MediaPlayerProtocol.Type? = KSMEPlayer.self
```
### Buffering Defaults
```swift
KSOptions.preferredForwardBufferDuration: TimeInterval = 3.0
KSOptions.maxBufferDuration: TimeInterval = 30.0
KSOptions.isSecondOpen: Bool = false
```
### Playback Defaults
```swift
KSOptions.isAccurateSeek: Bool = false
KSOptions.isLoopPlay: Bool = false
KSOptions.isAutoPlay: Bool = true
KSOptions.isSeekedAutoPlay: Bool = true
```
### Decoding
```swift
KSOptions.hardwareDecode: Bool = true
KSOptions.asynchronousDecompression: Bool = false
KSOptions.canStartPictureInPictureAutomaticallyFromInline: Bool = true
```
### UI Options
```swift
// Top bar visibility: .always, .horizantalOnly, .none
KSOptions.topBarShowInCase: KSPlayerTopBarShowCase = .always
// Auto-hide controls delay
KSOptions.animateDelayTimeInterval: TimeInterval = 5.0
// Gesture controls
KSOptions.enableBrightnessGestures: Bool = true
KSOptions.enableVolumeGestures: Bool = true
KSOptions.enablePlaytimeGestures: Bool = true
// Background playback
KSOptions.canBackgroundPlay: Bool = false
```
### PiP
```swift
KSOptions.isPipPopViewController: Bool = false
```
### Logging
```swift
// Log levels: .panic, .fatal, .error, .warning, .info, .verbose, .debug, .trace
KSOptions.logLevel: LogLevel = .warning
KSOptions.logger: LogHandler = OSLog(lable: "KSPlayer")
```
### System
```swift
KSOptions.useSystemHTTPProxy: Bool = true
KSOptions.preferredFrame: Bool = true
```
### Subtitle Data Sources
```swift
KSOptions.subtitleDataSouces: [SubtitleDataSouce] = [DirectorySubtitleDataSouce()]
```
## Methods
### HTTP Headers
```swift
let options = KSOptions()
options.appendHeader(["Referer": "https://example.com"])
options.appendHeader(["Authorization": "Bearer token123"])
```
### Cookies
```swift
let cookies = [HTTPCookie(properties: [
.name: "session",
.value: "abc123",
.domain: "example.com",
.path: "/"
])!]
options.setCookie(cookies)
```
## Overridable Methods
Subclass `KSOptions` to customize behavior:
### Buffering Algorithm
```swift
class CustomOptions: KSOptions {
override func playable(capacitys: [CapacityProtocol], isFirst: Bool, isSeek: Bool) -> LoadingState {
// Custom buffering logic
super.playable(capacitys: capacitys, isFirst: isFirst, isSeek: isSeek)
}
}
```
### Adaptive Bitrate
```swift
override func adaptable(state: VideoAdaptationState?) -> (Int64, Int64)? {
// Return (currentBitrate, targetBitrate) or nil
super.adaptable(state: state)
}
```
### Track Selection
```swift
// Select preferred video track
override func wantedVideo(tracks: [MediaPlayerTrack]) -> Int? {
// Return index of preferred track or nil for auto
return tracks.firstIndex { $0.bitRate > 5_000_000 }
}
// Select preferred audio track
override func wantedAudio(tracks: [MediaPlayerTrack]) -> Int? {
// Return index of preferred track or nil for auto
return tracks.firstIndex { $0.languageCode == "en" }
}
```
### Display Layer
```swift
override func isUseDisplayLayer() -> Bool {
// Return true to use AVSampleBufferDisplayLayer (supports HDR10+)
// Return false for other display modes
display == .plane
}
```
### Track Processing
```swift
override func process(assetTrack: some MediaPlayerTrack) {
super.process(assetTrack: assetTrack)
// Custom processing before decoder creation
}
```
### Live Playback Rate
```swift
override func liveAdaptivePlaybackRate(loadingState: LoadingState) -> Float? {
// Return adjusted playback rate for live streams
// Return nil to keep current rate
if loadingState.loadedTime > preferredForwardBufferDuration + 5 {
return 1.2 // Speed up if too far behind
}
return nil
}
```
## Example: Custom Options
```swift
class StreamingOptions: KSOptions {
override init() {
super.init()
// Low latency settings
preferredForwardBufferDuration = 1.0
isSecondOpen = true
nobuffer = true
codecLowDelay = true
// Custom headers
appendHeader(["X-Custom-Header": "value"])
}
override func wantedAudio(tracks: [MediaPlayerTrack]) -> Int? {
// Prefer English audio
return tracks.firstIndex { $0.languageCode == "en" }
}
}
// Usage
let options = StreamingOptions()
playerView.set(url: streamURL, options: options)
```