Files
yattee/Yattee/Models/Caption.swift
Arkadiusz Fal 8faf20c9e9 Add loading external subtitle files for media-source playback
Adds a "Load subtitle from file…" row to the Subtitles section on iOS
(document picker) and macOS (open panel), available when playing files
from local folder, SMB, or WebDAV sources. The picked file is copied
into the per-video temp subtitle directory, registered as a selectable
Caption (displayed by filename), and activated through the existing
loadCaption flow. The Subtitles tab and captions control button now
also appear for media-source files without any subtitles.
2026-08-03 23:34:06 +02:00

78 lines
2.3 KiB
Swift

//
// Caption.swift
// Yattee
//
// Model representing a video caption/subtitle track.
//
import Foundation
/// Represents a caption/subtitle track for a video.
struct Caption: Identifiable, Codable, Hashable, Sendable {
/// The display label (e.g., "English", "English (auto-generated)")
let label: String
/// The language code (e.g., "en", "de-DE", "es-419")
let languageCode: String
/// The URL to fetch the caption content
let url: URL
/// Original filename of a user-picked external subtitle file.
/// When set, it is used as the display name so two picked files with the
/// same language remain distinguishable from API captions and each other.
var pickedFileName: String? = nil
/// Whether this is an auto-generated caption
var isAutoGenerated: Bool {
label.contains("auto-generated")
}
/// The base language code without region (e.g., "en" from "en-US")
var baseLanguageCode: String {
if let hyphenIndex = languageCode.firstIndex(of: "-") {
return String(languageCode[..<hyphenIndex])
}
return languageCode
}
var id: String {
"\(languageCode):\(label)"
}
/// Formatted display name for the caption
var displayName: String {
if let pickedFileName {
return pickedFileName
}
// Try to get localized language name (AUTO badge shown separately in UI)
if let localizedName = Locale.current.localizedString(forLanguageCode: baseLanguageCode) {
return localizedName
}
// Strip "(auto-generated)" from label if present
return label.replacingOccurrences(of: " (auto-generated)", with: "")
}
}
// MARK: - Preview Data
extension Caption {
/// A sample English caption for SwiftUI previews.
static var preview: Caption {
Caption(
label: "English",
languageCode: "en",
url: URL(string: "https://example.com/captions/en.vtt")!
)
}
/// A sample auto-generated caption for SwiftUI previews.
static var autoGeneratedPreview: Caption {
Caption(
label: "English (auto-generated)",
languageCode: "en",
url: URL(string: "https://example.com/captions/en-auto.vtt")!
)
}
}