iOS 0.5.45: decrypt F1TV cbcs audio with constant IV when senc is absent.
This commit is contained in:
parent
9658ec6465
commit
622e2cdb56
3 changed files with 17 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 = 57;
|
CURRENT_PROJECT_VERSION = 58;
|
||||||
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.44;
|
MARKETING_VERSION = 0.5.45;
|
||||||
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 = 57;
|
CURRENT_PROJECT_VERSION = 58;
|
||||||
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.44;
|
MARKETING_VERSION = 0.5.45;
|
||||||
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)";
|
||||||
|
|
|
||||||
|
|
@ -456,7 +456,11 @@ enum CencMp4Decryptor {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard !sampleSizes.isEmpty, sencSamples.count == sampleSizes.count || sencSamples.isEmpty == false else {
|
// cbcs audio (F1TV): tenc heeft constant_IV + iv_size=0, fragmenten hebben géén senc.
|
||||||
|
// ISO 23001-7: elk sample ontsleutelen met die IV (geen per-sample IV, geen subsample).
|
||||||
|
let constantIv = crypto?.constantIv
|
||||||
|
let canUseConstantIv = (constantIv?.count ?? 0) >= 8
|
||||||
|
guard !sampleSizes.isEmpty, !sencSamples.isEmpty || canUseConstantIv else {
|
||||||
diag("frag track=\(trackId) skip: samples=\(sampleSizes.count) senc=\(sencSamples.count) tfhd=0x\(String(tfhdFlagsSeen, radix: 16)) trun=0x\(String(trunFlagsSeen, radix: 16))")
|
diag("frag track=\(trackId) skip: samples=\(sampleSizes.count) senc=\(sencSamples.count) tfhd=0x\(String(tfhdFlagsSeen, radix: 16)) trun=0x\(String(trunFlagsSeen, radix: 16))")
|
||||||
// Advance cursor even if we cannot decrypt.
|
// Advance cursor even if we cannot decrypt.
|
||||||
for sz in sampleSizes { mdatCursor += sz }
|
for sz in sampleSizes { mdatCursor += sz }
|
||||||
|
|
@ -478,34 +482,34 @@ enum CencMp4Decryptor {
|
||||||
let cryptBlocks = crypto?.cryptByteBlock ?? 0
|
let cryptBlocks = crypto?.cryptByteBlock ?? 0
|
||||||
let skipBlocks = crypto?.skipByteBlock ?? 0
|
let skipBlocks = crypto?.skipByteBlock ?? 0
|
||||||
|
|
||||||
var didDecrypt = false
|
var decryptedCount = 0
|
||||||
for i in 0..<sampleSizes.count {
|
for i in 0..<sampleSizes.count {
|
||||||
let size = sampleSizes[i]
|
let size = sampleSizes[i]
|
||||||
guard size > 0, mdatCursor + size <= data.count else { break }
|
guard size > 0, mdatCursor + size <= data.count else { break }
|
||||||
let sampleRange = mdatCursor..<(mdatCursor + size)
|
let sampleRange = mdatCursor..<(mdatCursor + size)
|
||||||
var sample = data.subdata(in: sampleRange)
|
var sample = data.subdata(in: sampleRange)
|
||||||
let senc = i < sencSamples.count ? sencSamples[i] : nil
|
let senc = i < sencSamples.count ? sencSamples[i] : nil
|
||||||
if let senc {
|
let iv = senc?.iv ?? constantIv
|
||||||
|
if let iv {
|
||||||
if let decrypted = decryptSample(
|
if let decrypted = decryptSample(
|
||||||
sample,
|
sample,
|
||||||
key: key,
|
key: key,
|
||||||
iv: senc.iv,
|
iv: iv,
|
||||||
subsamples: senc.subsamples,
|
subsamples: senc?.subsamples,
|
||||||
scheme: scheme,
|
scheme: scheme,
|
||||||
cryptByteBlock: cryptBlocks,
|
cryptByteBlock: cryptBlocks,
|
||||||
skipByteBlock: skipBlocks
|
skipByteBlock: skipBlocks
|
||||||
) {
|
) {
|
||||||
sample = decrypted
|
sample = decrypted
|
||||||
data.replaceSubrange(sampleRange, with: sample)
|
data.replaceSubrange(sampleRange, with: sample)
|
||||||
didDecrypt = true
|
decryptedCount += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mdatCursor += size
|
mdatCursor += size
|
||||||
}
|
}
|
||||||
let decryptedCount = didDecrypt ? min(sencSamples.count, sampleSizes.count) : 0
|
|
||||||
diag("frag track=\(trackId) crypto=\(crypto != nil) scheme=\(scheme) pat=\(cryptBlocks):\(skipBlocks) samples=\(sampleSizes.count) senc=\(sencSamples.count) iv=\(sencSamples.first?.iv.count ?? 0) subs=\(sencSamples.first?.subsamples?.count ?? -1) size0=\(sampleSizes.first ?? 0) dec=\(decryptedCount) tfhd=0x\(String(tfhdFlagsSeen, radix: 16)) trun=0x\(String(trunFlagsSeen, radix: 16)) mdat=\(mdat.payloadLength)")
|
diag("frag track=\(trackId) crypto=\(crypto != nil) scheme=\(scheme) pat=\(cryptBlocks):\(skipBlocks) samples=\(sampleSizes.count) senc=\(sencSamples.count) iv=\(sencSamples.first?.iv.count ?? 0) subs=\(sencSamples.first?.subsamples?.count ?? -1) size0=\(sampleSizes.first ?? 0) dec=\(decryptedCount) tfhd=0x\(String(tfhdFlagsSeen, radix: 16)) trun=0x\(String(trunFlagsSeen, radix: 16)) mdat=\(mdat.payloadLength)")
|
||||||
// AVPlayer/VLC mogen geen tweede decrypt-poging doen op clear samples.
|
// AVPlayer/VLC mogen geen tweede decrypt-poging doen op clear samples.
|
||||||
if didDecrypt {
|
if decryptedCount > 0 {
|
||||||
for senc in findBoxesInRange(data, type: "senc", from: traf.payloadStart, to: traf.payloadEnd) {
|
for senc in findBoxesInRange(data, type: "senc", from: traf.payloadStart, to: traf.payloadEnd) {
|
||||||
writeFourCC(&data, senc.start + 4, "free")
|
writeFourCC(&data, senc.start + 4, "free")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.44")
|
LabeledContent("Versie", value: "0.5.45")
|
||||||
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