iOS 0.5.46: do not live-trim F1/VOD HLS playlists (replay stalled after ~12s).
This commit is contained in:
parent
622e2cdb56
commit
42c856eb47
3 changed files with 22 additions and 13 deletions
|
|
@ -345,7 +345,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEVELOPMENT_TEAM = X25NYX3K49;
|
DEVELOPMENT_TEAM = X25NYX3K49;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
|
@ -360,7 +360,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks"
|
"@executable_path/Frameworks"
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.5.45;
|
MARKETING_VERSION = 0.5.46;
|
||||||
OTHER_LDFLAGS = ("$(inherited)", "-ObjC");
|
OTHER_LDFLAGS = ("$(inherited)", "-ObjC");
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = nl.vonas.mediacluster.ios;
|
PRODUCT_BUNDLE_IDENTIFIER = nl.vonas.mediacluster.ios;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|
@ -378,7 +378,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEVELOPMENT_TEAM = X25NYX3K49;
|
DEVELOPMENT_TEAM = X25NYX3K49;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
|
@ -393,7 +393,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks"
|
"@executable_path/Frameworks"
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.5.45;
|
MARKETING_VERSION = 0.5.46;
|
||||||
OTHER_LDFLAGS = ("$(inherited)", "-ObjC");
|
OTHER_LDFLAGS = ("$(inherited)", "-ObjC");
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = nl.vonas.mediacluster.ios;
|
PRODUCT_BUNDLE_IDENTIFIER = nl.vonas.mediacluster.ios;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|
|
||||||
|
|
@ -674,6 +674,7 @@ final class ClearKeyDashProxy {
|
||||||
var mediaSequence: Int?
|
var mediaSequence: Int?
|
||||||
var targetDuration: Int = 6
|
var targetDuration: Int = 6
|
||||||
var hasEndList = false
|
var hasEndList = false
|
||||||
|
var playlistType: String?
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let trimmed = line.trimmingCharacters(in: .whitespaces)
|
let trimmed = line.trimmingCharacters(in: .whitespaces)
|
||||||
|
|
@ -681,7 +682,8 @@ final class ClearKeyDashProxy {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if trimmed.hasPrefix("#EXT-X-PLAYLIST-TYPE:") {
|
if trimmed.hasPrefix("#EXT-X-PLAYLIST-TYPE:") {
|
||||||
// EVENT met uren history → AVPlayer start verkeerd / audio-only. Behandel als live.
|
playlistType = trimmed.split(separator: ":").last
|
||||||
|
.map { String($0).trimmingCharacters(in: .whitespaces).uppercased() }
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if trimmed.hasPrefix("#EXT-X-MEDIA-SEQUENCE:") {
|
if trimmed.hasPrefix("#EXT-X-MEDIA-SEQUENCE:") {
|
||||||
|
|
@ -727,27 +729,34 @@ final class ClearKeyDashProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Live-edge window: ~12–16 segmenten (±60–90s bij 5–6s ESPN, ±40–60s bij 3.8s).
|
// Live-edge alleen voor echte live (ESPN). F1-replays / VOD hebben ENDLIST of
|
||||||
|
// een lange statische lijst: trim + START=-12 + geen ENDLIST → ~12s beeld, dan vast.
|
||||||
|
let host = (playlistURL.host ?? "").lowercased()
|
||||||
|
let isComplete = hasEndList || playlistType == "VOD"
|
||||||
|
let isF1 = host.contains("formula1.com")
|
||||||
let keep = 14
|
let keep = 14
|
||||||
let startIdx: Int
|
let startIdx: Int
|
||||||
let seqBase = mediaSequence ?? 0
|
let seqBase = mediaSequence ?? 0
|
||||||
if !hasEndList, segments.count > keep {
|
if isComplete || isF1 {
|
||||||
startIdx = segments.count - keep
|
startIdx = 0
|
||||||
} else if segments.count > 40 {
|
} else if segments.count > keep {
|
||||||
// VOD/EVENT-achtig met enorme history: toch trimmen naar einde.
|
|
||||||
startIdx = segments.count - keep
|
startIdx = segments.count - keep
|
||||||
} else {
|
} else {
|
||||||
startIdx = 0
|
startIdx = 0
|
||||||
}
|
}
|
||||||
let window = Array(segments.suffix(from: startIdx))
|
let window = Array(segments.suffix(from: startIdx))
|
||||||
let seq = seqBase + startIdx
|
let seq = seqBase + startIdx
|
||||||
|
proxyLog.info("hls rewrite segs=\(segments.count, privacy: .public) keep=\(window.count, privacy: .public) endlist=\(hasEndList, privacy: .public) type=\(playlistType ?? "-", privacy: .public) f1=\(isF1, privacy: .public) startIdx=\(startIdx, privacy: .public)")
|
||||||
|
|
||||||
out.append("#EXTM3U")
|
out.append("#EXTM3U")
|
||||||
out.append("#EXT-X-VERSION:7")
|
out.append("#EXT-X-VERSION:7")
|
||||||
out.append("#EXT-X-TARGETDURATION:\(targetDuration)")
|
out.append("#EXT-X-TARGETDURATION:\(targetDuration)")
|
||||||
out.append("#EXT-X-MEDIA-SEQUENCE:\(seq)")
|
out.append("#EXT-X-MEDIA-SEQUENCE:\(seq)")
|
||||||
out.append("#EXT-X-INDEPENDENT-SEGMENTS")
|
out.append("#EXT-X-INDEPENDENT-SEGMENTS")
|
||||||
// Live-achtig: start dicht bij einde.
|
if isComplete {
|
||||||
|
out.append("#EXT-X-PLAYLIST-TYPE:VOD")
|
||||||
|
}
|
||||||
|
// Live-achtig: start dicht bij einde. Nooit op een complete/F1-replay.
|
||||||
if startIdx > 0 {
|
if startIdx > 0 {
|
||||||
out.append("#EXT-X-START:TIME-OFFSET=-12.0,PRECISE=YES")
|
out.append("#EXT-X-START:TIME-OFFSET=-12.0,PRECISE=YES")
|
||||||
}
|
}
|
||||||
|
|
@ -763,7 +772,7 @@ final class ClearKeyDashProxy {
|
||||||
let resolved = join(base: asDirectory(playlistURL.deletingLastPathComponent()), relative: seg.uri)
|
let resolved = join(base: asDirectory(playlistURL.deletingLastPathComponent()), relative: seg.uri)
|
||||||
out.append(proxyAbsoluteURL(resolved, lane: lane))
|
out.append(proxyAbsoluteURL(resolved, lane: lane))
|
||||||
}
|
}
|
||||||
if hasEndList && startIdx == 0 {
|
if isComplete {
|
||||||
out.append("#EXT-X-ENDLIST")
|
out.append("#EXT-X-ENDLIST")
|
||||||
}
|
}
|
||||||
return out.joined(separator: "\n")
|
return out.joined(separator: "\n")
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ struct SettingsScreen: View {
|
||||||
|
|
||||||
Section("Info") {
|
Section("Info") {
|
||||||
LabeledContent("App", value: "VMC iOS")
|
LabeledContent("App", value: "VMC iOS")
|
||||||
LabeledContent("Versie", value: "0.5.45")
|
LabeledContent("Versie", value: "0.5.46")
|
||||||
LabeledContent("Live TV", value: app.iptvEnabled ? "Aan" : "Uit")
|
LabeledContent("Live TV", value: app.iptvEnabled ? "Aan" : "Uit")
|
||||||
LabeledContent("Events", value: app.eventsEnabled ? "Aan" : "Uit")
|
LabeledContent("Events", value: app.eventsEnabled ? "Aan" : "Uit")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue