added ios module
This commit is contained in:
95
ios/OralTrainer/Models/TrainingModels.swift
Normal file
95
ios/OralTrainer/Models/TrainingModels.swift
Normal file
@@ -0,0 +1,95 @@
|
||||
import Foundation
|
||||
|
||||
struct SentenceBoundary: Identifiable, Equatable, Decodable {
|
||||
let index: Int
|
||||
let startMs: Int64
|
||||
let endMs: Int64
|
||||
let text: String?
|
||||
let language: String?
|
||||
let referenceSpeechDurationMs: Int64?
|
||||
|
||||
var id: Int { index }
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case index, text, language
|
||||
case startMs = "start_ms"
|
||||
case endMs = "end_ms"
|
||||
case referenceSpeechDurationMs = "reference_speech_duration_ms"
|
||||
}
|
||||
}
|
||||
|
||||
struct SentenceBoundaryDocument: Decodable {
|
||||
let videoHash: String
|
||||
let durationMs: Int64
|
||||
let algorithmVersion: String
|
||||
let sentences: [SentenceBoundary]
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case videoHash = "video_hash"
|
||||
case durationMs = "duration_ms"
|
||||
case algorithmVersion = "algorithm_version"
|
||||
case sentences
|
||||
}
|
||||
}
|
||||
|
||||
struct TrainingVideoSummary: Identifiable, Decodable {
|
||||
let videoHash: String
|
||||
let title: String
|
||||
let streamUrl: String
|
||||
let durationMs: Int64?
|
||||
let sizeBytes: Int64
|
||||
let language: String?
|
||||
let sentenceCount: Int
|
||||
let status: String
|
||||
|
||||
var id: String { videoHash }
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case title, language, status
|
||||
case videoHash = "video_hash"
|
||||
case streamUrl = "stream_url"
|
||||
case durationMs = "duration_ms"
|
||||
case sizeBytes = "size_bytes"
|
||||
case sentenceCount = "sentence_count"
|
||||
}
|
||||
|
||||
/// 与安卓端一致:相对路径基于服务地址解析;服务地址为 http 时强制使用 http 流地址。
|
||||
func resolvedStreamURL(baseURL: String) -> URL? {
|
||||
guard let base = URL(string: baseURL) else { return nil }
|
||||
var absolute = URL(string: streamUrl, relativeTo: base)?.absoluteString ?? streamUrl
|
||||
if base.scheme == "http" {
|
||||
absolute = absolute.replacingOccurrences(
|
||||
of: "https://",
|
||||
with: "http://",
|
||||
options: [.anchored]
|
||||
)
|
||||
}
|
||||
return URL(string: absolute)
|
||||
}
|
||||
}
|
||||
|
||||
struct TrainingMediaItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let title: String
|
||||
let url: URL
|
||||
let sentences: [SentenceBoundary]
|
||||
let isLocalFile: Bool
|
||||
|
||||
init(
|
||||
id: String,
|
||||
title: String,
|
||||
url: URL,
|
||||
sentences: [SentenceBoundary] = [],
|
||||
isLocalFile: Bool = false
|
||||
) {
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.url = url
|
||||
self.sentences = sentences
|
||||
self.isLocalFile = isLocalFile
|
||||
}
|
||||
|
||||
static func == (lhs: TrainingMediaItem, rhs: TrainingMediaItem) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user