Skip to content

Commit d93cd82

Browse files
authored
Merge pull request #86 from Comcast/release/2.2.0
Release/2.2.0
2 parents c4abe3e + 6744a84 commit d93cd82

File tree

13 files changed

+829
-10
lines changed

13 files changed

+829
-10
lines changed

mamba.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22

33
s.name = "mamba"
4-
s.version = "2.0.3"
4+
s.version = "2.2.0"
55
s.license = { :type => 'Apache License, Version 2.0',
66
:text => <<-LICENSE
77
Copyright 2017 Comcast Cable Communications Management, LLC

mamba.xcodeproj/project.pbxproj

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@
2626
43DE4EFD1E564DBE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DE4EFC1E564DBE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift */; };
2727
43DE4F0D1E564FEE00EEE800 /* EXT_X_STARTTimeOffsetValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DE4EFA1E564DA300EEE800 /* EXT_X_STARTTimeOffsetValidator.swift */; };
2828
43DE4F0E1E564FFE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DE4EFC1E564DBE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift */; };
29+
6DD0A1AD242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1AC242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift */; };
30+
6DD0A1AE242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1AC242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift */; };
31+
6DD0A1AF242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1AC242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift */; };
32+
6DD0A1B1242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1B0242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift */; };
33+
6DD0A1B2242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1B0242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift */; };
34+
6DD0A1B3242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DD0A1B0242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift */; };
35+
6DD9C898242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 6DD9C897242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 */; };
36+
6DD9C899242CCE5300B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 6DD9C897242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 */; };
37+
6DD9C89A242CCE5400B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 6DD9C897242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 */; };
2938
883290561EA172170064588B /* MambaStringRefExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 883290551EA172170064588B /* MambaStringRefExtensionTests.swift */; };
3039
D44E03771E3BAC9F00126B52 /* PlaylistTag+Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44E03761E3BAC9F00126B52 /* PlaylistTag+Util.swift */; };
3140
D44E03781E3BAC9F00126B52 /* PlaylistTag+Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44E03761E3BAC9F00126B52 /* PlaylistTag+Util.swift */; };
@@ -634,6 +643,9 @@
634643
3D933C192193367C0029069F /* EXT-X-BITRATETagParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EXT-X-BITRATETagParserTests.swift"; sourceTree = "<group>"; };
635644
43DE4EFA1E564DA300EEE800 /* EXT_X_STARTTimeOffsetValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = EXT_X_STARTTimeOffsetValidator.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
636645
43DE4EFC1E564DBE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EXT_X_MEDIARenditionINSTREAMIDValidator.swift; sourceTree = "<group>"; };
646+
6DD0A1AC242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXT_X_DATERANGETagValidator.swift; sourceTree = "<group>"; };
647+
6DD0A1B0242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXT_X_DATERANGEPlaylistValidator.swift; sourceTree = "<group>"; };
648+
6DD9C897242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = hls_variant_playlist_with_daterange_metadata.m3u8; sourceTree = "<group>"; };
637649
883290551EA172170064588B /* MambaStringRefExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MambaStringRefExtensionTests.swift; sourceTree = "<group>"; };
638650
D44E03761E3BAC9F00126B52 /* PlaylistTag+Util.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PlaylistTag+Util.swift"; sourceTree = "<group>"; };
639651
D4BB018C1E2EABD500CA006E /* PlaylistTagArray+RenditionGroups.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PlaylistTagArray+RenditionGroups.swift"; sourceTree = "<group>"; };
@@ -914,6 +926,8 @@
914926
isa = PBXGroup;
915927
children = (
916928
EC7491F71DD29DD300AF4E20 /* DictionaryTagValueIdentifier.swift */,
929+
6DD0A1B0242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift */,
930+
6DD0A1AC242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift */,
917931
EC3B019E1DD4D47900B512E3 /* EXT_X_KEYValidator.swift */,
918932
EC3B019F1DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupAUTOSELECTValidator.swift */,
919933
EC3B01A01DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupDEFAULTValidator.swift */,
@@ -1234,6 +1248,7 @@
12341248
EC7492001DD29E2900AF4E20 /* hls_sampleMediaFile.txt */,
12351249
EC7492011DD29E2900AF4E20 /* hls_singleMediaFile.txt */,
12361250
1D28F3441EAA9E500010320B /* hls_variant_playlist.m3u8 */,
1251+
6DD9C897242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 */,
12371252
EC7492021DD29E2900AF4E20 /* hls_writer_parser_roundtrip_tester.txt */,
12381253
EC7492061DD29E2900AF4E20 /* super8demuxed1_4242.m3u8 */,
12391254
EC7492071DD29E2900AF4E20 /* super8demuxed2_IP_1080p24_51_TS.m3u8 */,
@@ -1662,6 +1677,7 @@
16621677
EC7492201DD29E2900AF4E20 /* ThirdPartyTagsTestFixture.txt in Resources */,
16631678
EC74920A1DD29E2900AF4E20 /* bipbopall.m3u8 in Resources */,
16641679
EC1705421DFB490A00C969F9 /* linear_ad_insertion_CONTENT_end_ad_forced.m3u8 in Resources */,
1680+
6DD9C898242CCE4A00B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */,
16651681
EC74921A1DD29E2900AF4E20 /* super8demuxed1_4242.m3u8 in Resources */,
16661682
EC74921E1DD29E2900AF4E20 /* super8demuxed3_1376214110461.m3u8 in Resources */,
16671683
EC74920C1DD29E2900AF4E20 /* hls_sampleMasterFile.txt in Resources */,
@@ -1698,6 +1714,7 @@
16981714
EC7492211DD29E2900AF4E20 /* ThirdPartyTagsTestFixture.txt in Resources */,
16991715
EC74920B1DD29E2900AF4E20 /* bipbopall.m3u8 in Resources */,
17001716
EC1705431DFB490A00C969F9 /* linear_ad_insertion_CONTENT_end_ad_forced.m3u8 in Resources */,
1717+
6DD9C899242CCE5300B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */,
17011718
EC74921B1DD29E2900AF4E20 /* super8demuxed1_4242.m3u8 in Resources */,
17021719
EC74921F1DD29E2900AF4E20 /* super8demuxed3_1376214110461.m3u8 in Resources */,
17031720
EC74920D1DD29E2900AF4E20 /* hls_sampleMasterFile.txt in Resources */,
@@ -1734,6 +1751,7 @@
17341751
ECE253C0209A508700D388CE /* Super8_muxed1_4242.m3u8 in Resources */,
17351752
ECE253CE209A508700D388CE /* super8demuxed1_4242.m3u8 in Resources */,
17361753
ECE253CB209A508700D388CE /* hls_singleMediaFile.txt in Resources */,
1754+
6DD9C89A242CCE5400B90E1C /* hls_variant_playlist_with_daterange_metadata.m3u8 in Resources */,
17371755
ECE253C7209A508700D388CE /* hls_master_playlist.m3u8 in Resources */,
17381756
ECE253BF209A508700D388CE /* linear_ad_insertion_CONTENT_start_ad.m3u8 in Resources */,
17391757
ECE253BD209A508700D388CE /* linear_ad_insertion_CONTENT_end_ad_natural.m3u8 in Resources */,
@@ -1778,6 +1796,7 @@
17781796
EC7491BF1DD29D5C00AF4E20 /* PlaylistTagValueIdentifier.swift in Sources */,
17791797
EC3B01C91DD4D49A00B512E3 /* PlaylistRenditionGroupMatchingPROGRAM_IDValidator.swift in Sources */,
17801798
EC349AC52236BFF10077432B /* PlaylistInterface.swift in Sources */,
1799+
6DD0A1AD242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */,
17811800
F700CD331E78A0B9001C9487 /* MambaStringRef_ConcreteUnownedBytes.m in Sources */,
17821801
EC95478B1E5CC86300962535 /* EXTINFValidator.swift in Sources */,
17831802
EC9826021DD3A113003BCDA5 /* URLSchemeChangeExtension.swift in Sources */,
@@ -1791,6 +1810,7 @@
17911810
EC03B6541E5CC56B00BF1F97 /* RapidParser.m in Sources */,
17921811
F70E9E9A1E8C43C8006022C6 /* PlaylistParserError.swift in Sources */,
17931812
EC7491701DD29B5D00AF4E20 /* CollectionType+Safe.swift in Sources */,
1813+
6DD0A1B1242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */,
17941814
EC7491BB1DD29D5C00AF4E20 /* PlaylistTagParser.swift in Sources */,
17951815
EC7491C11DD29D5C00AF4E20 /* PlaylistTagWriter.swift in Sources */,
17961816
EC3B01CD1DD4D49A00B512E3 /* PlaylistTagCardinalityValidation.swift in Sources */,
@@ -1948,6 +1968,7 @@
19481968
EC9547861E5CC83C00962535 /* NoOpTagParser.swift in Sources */,
19491969
EC7491FB1DD29DD300AF4E20 /* GenericSingleTagValidator.swift in Sources */,
19501970
EC349AC62236BFF10077432B /* PlaylistInterface.swift in Sources */,
1971+
6DD0A1AE242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */,
19511972
F700CD341E78A0B9001C9487 /* MambaStringRef_ConcreteUnownedBytes.m in Sources */,
19521973
EC95478C1E5CC86300962535 /* EXTINFValidator.swift in Sources */,
19531974
EC7491C01DD29D5C00AF4E20 /* PlaylistTagValueIdentifier.swift in Sources */,
@@ -1961,6 +1982,7 @@
19611982
EC03B65B1E5CC56B00BF1F97 /* MambaStringRef.m in Sources */,
19621983
EC7491801DD29C3500AF4E20 /* String+EquatableMambaTypes.swift in Sources */,
19631984
F70E9E9B1E8C43C8006022C6 /* PlaylistParserError.swift in Sources */,
1985+
6DD0A1B2242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */,
19641986
EC03B6551E5CC56B00BF1F97 /* RapidParser.m in Sources */,
19651987
EC7491711DD29B5D00AF4E20 /* CollectionType+Safe.swift in Sources */,
19661988
EC7491BC1DD29D5C00AF4E20 /* PlaylistTagParser.swift in Sources */,
@@ -2118,6 +2140,7 @@
21182140
EC1CCD4D209A2CF9006B59FF /* PlaylistRenditionGroupMatchingPROGRAM_IDValidator.swift in Sources */,
21192141
EC1CCD24209A2CF9006B59FF /* CollectionType+Safe.swift in Sources */,
21202142
EC1CCCF5209A2CF9006B59FF /* PlaylistTimelineTranslator.swift in Sources */,
2143+
6DD0A1AF242F85C800FF7AAE /* EXT_X_DATERANGETagValidator.swift in Sources */,
21212144
EC1CCD58209A2CF9006B59FF /* PantosValue.swift in Sources */,
21222145
EC349AC72236BFF10077432B /* PlaylistInterface.swift in Sources */,
21232146
EC1CCD63209A2CF9006B59FF /* Mamba.swift in Sources */,
@@ -2131,6 +2154,7 @@
21312154
EC1CCD50209A2CF9006B59FF /* PlaylistTagGroupValidator.swift in Sources */,
21322155
EC1CCCFE209A2CF9006B59FF /* MambaStringRefFactory.m in Sources */,
21332156
EC349AD42236CB860077432B /* PlaylistStructureCore.swift in Sources */,
2157+
6DD0A1B3242FADC600FF7AAE /* EXT_X_DATERANGEPlaylistValidator.swift in Sources */,
21342158
EC1CCD3A209A2CF9006B59FF /* NoOpTagParser.swift in Sources */,
21352159
EC1CCD5D209A2CF9006B59FF /* PlaylistTagValidator.swift in Sources */,
21362160
EC1CCD62209A2CF9006B59FF /* PlaylistWriter.swift in Sources */,
@@ -2300,7 +2324,7 @@
23002324
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23012325
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
23022326
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2303-
MARKETING_VERSION = 2.1.0;
2327+
MARKETING_VERSION = 2.2.0;
23042328
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
23052329
PRODUCT_NAME = "$(TARGET_NAME)";
23062330
SKIP_INSTALL = YES;
@@ -2327,7 +2351,7 @@
23272351
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23282352
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
23292353
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2330-
MARKETING_VERSION = 2.1.0;
2354+
MARKETING_VERSION = 2.2.0;
23312355
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
23322356
PRODUCT_NAME = "$(TARGET_NAME)";
23332357
SKIP_INSTALL = YES;
@@ -2391,7 +2415,7 @@
23912415
INFOPLIST_FILE = mamba/Info.plist;
23922416
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23932417
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2394-
MARKETING_VERSION = 2.1.0;
2418+
MARKETING_VERSION = 2.2.0;
23952419
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
23962420
PRODUCT_NAME = mamba;
23972421
SDKROOT = appletvos;
@@ -2421,7 +2445,7 @@
24212445
INFOPLIST_FILE = mamba/Info.plist;
24222446
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
24232447
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2424-
MARKETING_VERSION = 2.1.0;
2448+
MARKETING_VERSION = 2.2.0;
24252449
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
24262450
PRODUCT_NAME = mamba;
24272451
SDKROOT = appletvos;
@@ -2499,7 +2523,7 @@
24992523
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25002524
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
25012525
MACOSX_DEPLOYMENT_TARGET = 10.13;
2502-
MARKETING_VERSION = 2.1.0;
2526+
MARKETING_VERSION = 2.2.0;
25032527
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
25042528
PRODUCT_MODULE_NAME = mamba;
25052529
PRODUCT_NAME = mamba;
@@ -2532,7 +2556,7 @@
25322556
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25332557
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
25342558
MACOSX_DEPLOYMENT_TARGET = 10.13;
2535-
MARKETING_VERSION = 2.1.0;
2559+
MARKETING_VERSION = 2.2.0;
25362560
PRODUCT_BUNDLE_IDENTIFIER = com.comcast.mamba;
25372561
PRODUCT_MODULE_NAME = mamba;
25382562
PRODUCT_NAME = mamba;
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//
2+
// EXT_X_DATERANGEPlaylistValidator.swift
3+
// mamba
4+
//
5+
// Created by Robert Galluccio on 28/03/2020.
6+
// Copyright © 2020 Comcast Corporation.
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License. All rights reserved.
18+
//
19+
20+
import Foundation
21+
22+
/// This class provides the validation for EXT-X-DATERANGE tags for rules which require the whole playlist information.
23+
///
24+
/// All validation issues for EXT-X-DATERANGE are treated as `.warning` due to this comment in the HLS specification:
25+
///
26+
/// Clients SHOULD ignore EXT-X-DATERANGE tags with illegal syntax.
27+
///
28+
class EXT_X_DATERANGEPlaylistValidator: VariantPlaylistValidator {
29+
30+
static func validate(variantPlaylist: VariantPlaylistInterface) -> [PlaylistValidationIssue] {
31+
32+
var programDateTimeTagsCount = 0
33+
var daterangeTags = [PlaylistTag]()
34+
for tag in variantPlaylist.tags {
35+
if tag.tagDescriptor == PantosTag.EXT_X_PROGRAM_DATE_TIME {
36+
programDateTimeTagsCount += 1
37+
} else if tag.tagDescriptor == PantosTag.EXT_X_DATERANGE {
38+
daterangeTags.append(tag)
39+
}
40+
}
41+
42+
var validationIssues = [PlaylistValidationIssue]()
43+
validationIssues.append(contentsOf: validateProgramDateTime(programDateTimeTagsCount: programDateTimeTagsCount, daterangeTagsCount: daterangeTags.count))
44+
validationIssues.append(contentsOf: validateMultipleTags(daterangeTags: daterangeTags))
45+
46+
return validationIssues
47+
}
48+
49+
// If a Playlist contains an EXT-X-DATERANGE tag, it MUST also contain
50+
// at least one EXT-X-PROGRAM-DATE-TIME tag.
51+
private static func validateProgramDateTime(programDateTimeTagsCount: Int, daterangeTagsCount: Int) -> [PlaylistValidationIssue] {
52+
53+
guard daterangeTagsCount > 0, programDateTimeTagsCount == 0 else {
54+
return []
55+
}
56+
return [PlaylistValidationIssue(description: .EXT_X_DATERANGEExistsWithNoEXT_X_PROGRAM_DATE_TIME, severity: .warning)]
57+
}
58+
59+
// If a Playlist contains two EXT-X-DATERANGE tags with the same ID
60+
// attribute value, then any AttributeName that appears in both tags
61+
// MUST have the same AttributeValue.
62+
private static func validateMultipleTags(daterangeTags: [PlaylistTag]) -> [PlaylistValidationIssue] {
63+
64+
// first fill out a map of ID to tags to group tags with matching ID
65+
var idTagMap = [String: [PlaylistTag]]()
66+
for tag in daterangeTags {
67+
guard let id = tag.value(forValueIdentifier: PantosValue.id) else {
68+
// This should not happen, but if it does, this is a validation issue that will be caught by the tag validator
69+
continue
70+
}
71+
if let matchingTags = idTagMap[id] {
72+
idTagMap[id] = matchingTags + [tag]
73+
} else {
74+
idTagMap[id] = [tag]
75+
}
76+
}
77+
// next we pick out ID values with multiple tags and validate the attributes match between them
78+
var validationIssues = [PlaylistValidationIssue]()
79+
for (_, tags) in idTagMap {
80+
guard tags.count > 1 else {
81+
continue
82+
}
83+
// make a map of attributes to values to ensure any matching attributes also match value
84+
var attributeToValueMap = [String: String]()
85+
for tag in tags {
86+
for attribute in tag.keys {
87+
guard let attributeValue = tag.value(forKey: attribute) else {
88+
assertionFailure("tag.keys gave us a key that had no value in the tag - key: \(attribute), tag: \(tag), tag.keys: \(tag.keys)")
89+
continue
90+
}
91+
if let matchingAttributeValue = attributeToValueMap[attribute] {
92+
if attributeValue != matchingAttributeValue {
93+
validationIssues.append(PlaylistValidationIssue(description: .EXT_X_DATERANGEAttributeMismatchForTagsWithSameID, severity: .warning))
94+
}
95+
} else {
96+
attributeToValueMap[attribute] = attributeValue
97+
}
98+
}
99+
}
100+
}
101+
102+
return validationIssues
103+
}
104+
}

0 commit comments

Comments
 (0)