Skip to content

Commit 7846ce1

Browse files
authored
Merge pull request #108 from THEOplayer/bugfix/sideloaded-subtitles-handle-http-errors
Bugfix/sideloaded subtitles handle http errors
2 parents 4aac087 + 6a0f123 commit 7846ce1

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
## [10.8.0.1] - 2026-01-20
11+
12+
### Fixed
13+
14+
- SideloadedSubtitle
15+
- Fixed an issue where a bad http response code for subtitle sources would cause playback issues.
1016

1117
## [10.8.0] - 2026-01-15
1218

Code/Sideloaded-TextTracks/Sources/THEOplayerConnectorSideloadedSubtitle/AVSubtitlesLoader.swift

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ class AVSubtitlesLoader: NSObject {
1616
Self.instances.removeAll { $0._id == id }
1717
}
1818

19-
private let subtitles: [TextTrackDescription]
19+
private let _subtitles: [TextTrackDescription]
20+
private var subtitles: [TextTrackDescription] = []
2021
private let transformer = SubtitlesTransformer()
2122
private let synchronizer: SubtitlesSynchronizer?
2223
private let _id: String
2324
private var variantTotalDuration: Double = 0
2425

2526
init(subtitles: [TextTrackDescription], id: String, player: THEOplayer? = nil) {
26-
self.subtitles = subtitles
27+
self._subtitles = subtitles
2728
self._id = id
2829
self.synchronizer = SubtitlesSynchronizer(player: player)
2930
self.synchronizer?.delegate = self.transformer
@@ -43,7 +44,6 @@ class AVSubtitlesLoader: NSObject {
4344

4445
func handleMasterManifestRequest(_ url: URL) async -> Data? {
4546
let parser = MasterPlaylistParser(url: url)
46-
4747
guard let responseData = await parser.sideLoadSubtitles(subtitles: subtitles) else {
4848
print("[AVSubtitlesLoader] ERROR: Couldn't find manifest data")
4949
return nil
@@ -122,6 +122,20 @@ class AVSubtitlesLoader: NSObject {
122122
Self.removeInstance(by: _id)
123123
}
124124

125+
private func validateSubtitles() async -> [TextTrackDescription] {
126+
var validSubtitles: [TextTrackDescription] = []
127+
for subtitle in _subtitles {
128+
if let encodedURLString = subtitle.src.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
129+
let encodedURL = URL(string: encodedURLString),
130+
let (_, response) = try? await URLSession.shared.data(from: encodedURL),
131+
let httpResponse = response as? HTTPURLResponse,
132+
200..<300 ~= httpResponse.statusCode {
133+
validSubtitles.append(subtitle)
134+
}
135+
}
136+
return validSubtitles
137+
}
138+
125139
#if os(iOS)
126140
private func handleCachingTaskStateChangeEvent(task: CachingTask?) {
127141
guard let task,
@@ -163,19 +177,27 @@ extension AVSubtitlesLoader: MediaPlaylistInterceptor {
163177
if THEOplayerConnectorSideloadedSubtitle.SHOW_DEBUG_LOGS {
164178
print("[AVSubtitlesLoader] intercept url", url.absoluteString, self)
165179
}
166-
return await interceptResponse(type: type, url: url, data: data)
180+
let response = await interceptResponse(type: type, url: url, data: data)
181+
if response == data {
182+
print("[AVSubtitlesLoader] keeping original response for url", url.absoluteString, self)
183+
}
184+
return response
167185
}
168186

169187
private func interceptResponse(type: HlsPlaylistType, url: URL, data: Data) async -> Data {
170188
switch type {
171189
case .master :
172190
// intercept the master manifest to append the subtitles
191+
subtitles = await validateSubtitles()
192+
if subtitles.isEmpty { return data }
173193
return await self.handleMasterManifestRequest(url) ?? data
174194
case .video:
175195
// intercept the variant manifest to get the duration
196+
if subtitles.isEmpty { return data }
176197
return await self.handleVariantManifest(url) ?? data
177198
case .subtitles:
178199
// intercept the subtitle request to respond with the HLS subtitle
200+
if subtitles.isEmpty { return data }
179201
return self.handleSubtitles(url) ?? data
180202
default:
181203
break

0 commit comments

Comments
 (0)