Skip to content

Commit

Permalink
Merge branch 'release/2.2.2_xcode16' of https://github.com/kimbely032…
Browse files Browse the repository at this point in the history
…0/mamba into release/2.2.2_xcode16
  • Loading branch information
kimbely0320 committed Oct 3, 2024
2 parents 18535c2 + 2f3f81e commit 24ee325
Show file tree
Hide file tree
Showing 18 changed files with 1,889 additions and 201 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build and test

on:
pull_request:
branches: [ "develop", "develop_1.x", "main", "main_1.x" ]

jobs:
define-ios-device:
name: Get iOS simulator device to run iOS tests on
runs-on: macos-latest
outputs:
device: ${{ steps.ios.outputs.device }}
steps:
- id: ios
run: echo "device=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}' | sed -e "s/ Simulator$//"`" >> "$GITHUB_OUTPUT"

build:
name: Build and Test mamba and mambaTVOS
runs-on: macos-latest
needs: define-ios-device
strategy:
matrix:
target:
- scheme: mamba
platform: iOS Simulator
device: ${{ needs.define-ios-device.outputs.device }}
- scheme: mambaTVOS
platform: tvOS Simulator
device: Apple TV
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
env:
scheme: ${{ matrix.target.scheme }}
platform: ${{ matrix.target.platform }}
device: ${{ matrix.target.device }}
run: |
echo "scheme = $scheme"
echo "platform = $platform"
echo "device = $device"
xcodebuild build-for-testing -scheme "$scheme" -"workspace" "mamba.xcworkspace" -destination "platform=$platform,name=$device"
- name: Test
env:
scheme: ${{ matrix.target.scheme }}
platform: ${{ matrix.target.platform }}
device: ${{ matrix.target.device }}
run: |
echo "scheme = $scheme"
echo "platform = $platform"
echo "device = $device"
xcodebuild test-without-building -scheme "$scheme" -"workspace" "mamba.xcworkspace" -destination "platform=$platform,name=$device"
42 changes: 41 additions & 1 deletion mamba.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@

/* Begin PBXBuildFile section */
01CD2E7A1DE4D46F002510E7 /* EXT_X_MAPTagParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CD2E791DE4D46F002510E7 /* EXT_X_MAPTagParserTests.swift */; };
1447582D2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447582C2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift */; };
1447582E2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447582C2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift */; };
1447582F2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447582C2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift */; };
144758312C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758302C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift */; };
144758322C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758302C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift */; };
144758332C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758302C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift */; };
144758352C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758342C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift */; };
144758362C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758342C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift */; };
144758372C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758342C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift */; };
144758392C8620C000D12CCD /* ChannelsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758382C8620C000D12CCD /* ChannelsTests.swift */; };
1447583A2C8620C000D12CCD /* ChannelsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758382C8620C000D12CCD /* ChannelsTests.swift */; };
1447583B2C8620C000D12CCD /* ChannelsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 144758382C8620C000D12CCD /* ChannelsTests.swift */; };
1447583D2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447583C2C8693E000D12CCD /* VideoLayoutTests.swift */; };
1447583E2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447583C2C8693E000D12CCD /* VideoLayoutTests.swift */; };
1447583F2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1447583C2C8693E000D12CCD /* VideoLayoutTests.swift */; };
1D28F3451EAA9E500010320B /* hls_ad_master_playlist.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 1D28F3401EAA9E500010320B /* hls_ad_master_playlist.m3u8 */; };
1D28F3461EAA9E500010320B /* hls_ad_variant_playlist.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 1D28F3411EAA9E500010320B /* hls_ad_variant_playlist.m3u8 */; };
1D28F3471EAA9E500010320B /* hls_master_playlist_sap.m3u8 in Resources */ = {isa = PBXBuildFile; fileRef = 1D28F3421EAA9E500010320B /* hls_master_playlist_sap.m3u8 */; };
Expand Down Expand Up @@ -635,6 +650,11 @@

/* Begin PBXFileReference section */
01CD2E791DE4D46F002510E7 /* EXT_X_MAPTagParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EXT_X_MAPTagParserTests.swift; sourceTree = "<group>"; };
1447582C2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXT_X_SESSION_KEYValidator.swift; sourceTree = "<group>"; };
144758302C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXT_X_SESSION_DATATagValidator.swift; sourceTree = "<group>"; };
144758342C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EXT_X_SESSION_DATAPlaylistValidator.swift; sourceTree = "<group>"; };
144758382C8620C000D12CCD /* ChannelsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsTests.swift; sourceTree = "<group>"; };
1447583C2C8693E000D12CCD /* VideoLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoLayoutTests.swift; sourceTree = "<group>"; };
1D28F3401EAA9E500010320B /* hls_ad_master_playlist.m3u8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = hls_ad_master_playlist.m3u8; sourceTree = "<group>"; };
1D28F3411EAA9E500010320B /* hls_ad_variant_playlist.m3u8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = hls_ad_variant_playlist.m3u8; sourceTree = "<group>"; };
1D28F3421EAA9E500010320B /* hls_master_playlist_sap.m3u8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = hls_master_playlist_sap.m3u8; sourceTree = "<group>"; };
Expand Down Expand Up @@ -930,6 +950,9 @@
EC3B01A11DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupNAMEValidator.swift */,
EC3B01A21DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupTYPEValidator.swift */,
43DE4EFC1E564DBE00EEE800 /* EXT_X_MEDIARenditionINSTREAMIDValidator.swift */,
144758342C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift */,
144758302C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift */,
1447582C2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift */,
43DE4EFA1E564DA300EEE800 /* EXT_X_STARTTimeOffsetValidator.swift */,
EC3B01A31DD4D47900B512E3 /* EXT_X_STREAM_INFRenditionGroupValidator.swift */,
EC3B01A41DD4D47900B512E3 /* EXT_X_TARGETDURATIONLengthValidator.swift */,
Expand Down Expand Up @@ -1318,10 +1341,12 @@
EC9BCAA21D749D8B0032BEBE /* Value Types */ = {
isa = PBXGroup;
children = (
144758382C8620C000D12CCD /* ChannelsTests.swift */,
EC7492AF1DD29F8900AF4E20 /* CodecArrayTests.swift */,
EC7492B01DD29F8900AF4E20 /* MediaTypeTests.swift */,
EC7492B21DD29F8900AF4E20 /* ResolutionTests.swift */,
EC7492B11DD29F8900AF4E20 /* PlaylistTypeTests.swift */,
EC7492B21DD29F8900AF4E20 /* ResolutionTests.swift */,
1447583C2C8693E000D12CCD /* VideoLayoutTests.swift */,
);
path = "Value Types";
sourceTree = "<group>";
Expand Down Expand Up @@ -1773,6 +1798,7 @@
EC7491811DD29C3500AF4E20 /* String+Trim.swift in Sources */,
EC7491C31DD29D5C00AF4E20 /* PlaylistValidationIssue.swift in Sources */,
ECDE184C22383230008566BB /* PlaylistParser.swift in Sources */,
144758352C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */,
EC74916E1DD29B5D00AF4E20 /* CollectionType+FindExtensions.swift in Sources */,
EC7491DA1DD29D9600AF4E20 /* GenericNoDataTagParser.swift in Sources */,
EC7491C91DD29D5C00AF4E20 /* PlaylistWriter.swift in Sources */,
Expand Down Expand Up @@ -1847,6 +1873,8 @@
EC349ACE2236C3A60077432B /* PlaylistStructureInterface.swift in Sources */,
EC3B01A71DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupAUTOSELECTValidator.swift in Sources */,
F700CD391E78A2BE001C9487 /* MambaStringRef_ConcreteNSString.m in Sources */,
144758312C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */,
1447582D2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */,
43DE4EFB1E564DA300EEE800 /* EXT_X_STARTTimeOffsetValidator.swift in Sources */,
EC74918A1DD29CCB00AF4E20 /* StringDictionaryParser.swift in Sources */,
ECDE184022381146008566BB /* MasterPlaylist.swift in Sources */,
Expand Down Expand Up @@ -1930,8 +1958,10 @@
ECFBD9101E5CCC2200379FC2 /* ParseArrayTests.m in Sources */,
EC7492B31DD29F8900AF4E20 /* CodecArrayTests.swift in Sources */,
01CD2E7A1DE4D46F002510E7 /* EXT_X_MAPTagParserTests.swift in Sources */,
144758392C8620C000D12CCD /* ChannelsTests.swift in Sources */,
EC7492AB1DD29F7000AF4E20 /* OrderedDictionaryTests.swift in Sources */,
EC7492781DD29EC800AF4E20 /* EXT_X_MEDIATagParserTests.swift in Sources */,
1447583D2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1945,6 +1975,7 @@
EC3B01AA1DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupDEFAULTValidator.swift in Sources */,
EC3B01C41DD4D49A00B512E3 /* PlaylistOneToManyValidator.swift in Sources */,
ECDE184D22383230008566BB /* PlaylistParser.swift in Sources */,
144758362C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */,
EC7491821DD29C3500AF4E20 /* String+Trim.swift in Sources */,
EC7491C41DD29D5C00AF4E20 /* PlaylistValidationIssue.swift in Sources */,
EC74916F1DD29B5D00AF4E20 /* CollectionType+FindExtensions.swift in Sources */,
Expand Down Expand Up @@ -2019,6 +2050,8 @@
EC349ACF2236C3A60077432B /* PlaylistStructureInterface.swift in Sources */,
EC7491471DD299B400AF4E20 /* PlaylistTypes.swift in Sources */,
F700CD3A1E78A2BE001C9487 /* MambaStringRef_ConcreteNSString.m in Sources */,
144758322C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */,
1447582E2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */,
EC3B01A81DD4D47900B512E3 /* EXT_X_MEDIARenditionGroupAUTOSELECTValidator.swift in Sources */,
EC74918B1DD29CCB00AF4E20 /* StringDictionaryParser.swift in Sources */,
ECDE184122381146008566BB /* MasterPlaylist.swift in Sources */,
Expand Down Expand Up @@ -2102,8 +2135,10 @@
ECFBD9111E5CCC2200379FC2 /* ParseArrayTests.m in Sources */,
EC7492B81DD29F8900AF4E20 /* PlaylistTypeTests.swift in Sources */,
EC7492B41DD29F8900AF4E20 /* CodecArrayTests.swift in Sources */,
1447583A2C8620C000D12CCD /* ChannelsTests.swift in Sources */,
EC7492AC1DD29F7000AF4E20 /* OrderedDictionaryTests.swift in Sources */,
EC7492791DD29EC800AF4E20 /* EXT_X_MEDIATagParserTests.swift in Sources */,
1447583E2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -2118,6 +2153,7 @@
EC1CCD32209A2CF9006B59FF /* String+Trim.swift in Sources */,
EC1CCD46209A2CF9006B59FF /* GenericSingleTagValidator.swift in Sources */,
ECDE184E22383230008566BB /* PlaylistParser.swift in Sources */,
144758372C83D23100D12CCD /* EXT_X_SESSION_DATAPlaylistValidator.swift in Sources */,
EC1CCD30209A2CF9006B59FF /* String+DateParsing.swift in Sources */,
EC1CCD53209A2CF9006B59FF /* GenericDictionaryTagWriter.swift in Sources */,
EC1CCD55209A2CF9006B59FF /* GenericTagWriter.swift in Sources */,
Expand Down Expand Up @@ -2189,7 +2225,9 @@
EC1CCD4F209A2CF9006B59FF /* PlaylistTagCardinalityValidation.swift in Sources */,
EC1CCD2B209A2CF9006B59FF /* IndeterminateBool.swift in Sources */,
EC349AD02236C3A60077432B /* PlaylistStructureInterface.swift in Sources */,
144758332C83C72B00D12CCD /* EXT_X_SESSION_DATATagValidator.swift in Sources */,
EC1CCD43209A2CF9006B59FF /* EXT_X_STREAM_INFRenditionGroupValidator.swift in Sources */,
1447582F2C83C20800D12CCD /* EXT_X_SESSION_KEYValidator.swift in Sources */,
EC1CCD35209A2CF9006B59FF /* StringDictionaryParser.swift in Sources */,
EC1CCD02209A2CF9006B59FF /* MambaStringRef_ConcreteNSString.m in Sources */,
EC1CCD38209A2CF9006B59FF /* GenericNoDataTagParser.swift in Sources */,
Expand Down Expand Up @@ -2272,10 +2310,12 @@
ECE253FD209A50B500D388CE /* ThirdPartyTagListSupportTests.swift in Sources */,
ECE25408209A50B500D388CE /* ResolutionTests.swift in Sources */,
ECE253F6209A50B500D388CE /* GenericSingleValueTagParserTests.swift in Sources */,
1447583B2C8620C000D12CCD /* ChannelsTests.swift in Sources */,
ECE253FA209A50B500D388CE /* GenericSingleTagValidatorTests.swift in Sources */,
ECE253F1209A50B500D388CE /* EXT_X_KEYTagParserTests.swift in Sources */,
ECE25403209A50B500D388CE /* String+Helio.swift in Sources */,
ECE25400209A50B500D388CE /* IndeterminateBoolTests.swift in Sources */,
1447583F2C8693E000D12CCD /* VideoLayoutTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// EXT_X_SESSION_DATAPlaylistValidator.swift
// mamba
//
// Created by Robert Galluccio on 8/31/24.
// Copyright © 2024 Comcast Corporation.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License. All rights reserved.
//

import Foundation

final class EXT_X_SESSION_DATAPlaylistValidator: MasterPlaylistValidator {
static func validate(masterPlaylist: any MasterPlaylistInterface) -> [PlaylistValidationIssue] {
var issues = [PlaylistValidationIssue]()

if let issue = duplicateIssue(
tags: masterPlaylist.tags.filter { $0.tagDescriptor == PantosTag.EXT_X_SESSION_DATA }
) {
issues.append(issue)
}

return issues
}

// A Playlist MAY contain multiple EXT-X-SESSION-DATA tags with the same DATA-ID attribute. A Playlist MUST NOT
// contain more than one EXT-X-SESSION-DATA tag with the same DATA-ID attribute and the same LANGUAGE attribute.
private static func duplicateIssue(tags: [PlaylistTag]) -> PlaylistValidationIssue? {
var dataIdToLanguagesMap = [String: [String?]]()
for tag in tags {
guard let dataId = tag.value(forValueIdentifier: PantosValue.dataId) else { continue }
var existingLanguages = dataIdToLanguagesMap[dataId] ?? []
existingLanguages.append(tag.value(forValueIdentifier: PantosValue.language))
dataIdToLanguagesMap[dataId] = existingLanguages
}
for languages in dataIdToLanguagesMap.values {
if languages.count != Set(languages).count {
return PlaylistValidationIssue(description: .EXT_X_SESSION_DATAPlaylistValidator, severity: .error)
}
}
return nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// EXT_X_SESSION_DATATagValidator.swift
// mamba
//
// Created by Robert Galluccio on 8/31/24.
// Copyright © 2024 Comcast Corporation.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License. All rights reserved.
//

import Foundation

struct EXT_X_SESSION_DATATagValidator: PlaylistTagValidator {
private var genericValidator: GenericDictionaryTagValidator

init() {
genericValidator = GenericDictionaryTagValidator(
tag: PantosTag.EXT_X_SESSION_DATA,
dictionaryValueIdentifiers: [
DictionaryTagValueIdentifierImpl(
valueId: PantosValue.dataId,
optional: false,
expectedType: String.self
),
DictionaryTagValueIdentifierImpl(
valueId: PantosValue.value,
optional: true,
expectedType: String.self
),
DictionaryTagValueIdentifierImpl(
valueId: PantosValue.uri,
optional: true,
expectedType: String.self
),
DictionaryTagValueIdentifierImpl(
valueId: PantosValue.format,
optional: true,
expectedType: SessionDataFormat.self
),
DictionaryTagValueIdentifierImpl(
valueId: PantosValue.language,
optional: true,
expectedType: String.self
),
]
)
}

func validate(tag: PlaylistTag) -> [PlaylistValidationIssue]? {
var issueList = genericValidator.validate(tag: tag) ?? []

// Each EXT-X-SESSION-DATA tag MUST contain either a VALUE or URI attribute, but not both.
switch (tag.value(forValueIdentifier: PantosValue.value), tag.value(forValueIdentifier: PantosValue.uri)) {
case (.none, .some), (.some, .none):
break
case (.some, .some), (.none, .none):
issueList.append(PlaylistValidationIssue(description: .EXT_X_SESSION_DATATagValidator, severity: .error))
}

return issueList.isEmpty ? nil : issueList
}
}
Loading

0 comments on commit 24ee325

Please sign in to comment.