Skip to content

Commit cf35e0d

Browse files
daytime-emandrewjl-mux
authored andcommitted
Add Initial DRM implementation (#36)
* Add API for DRM * chore: scaffolding for key value observation * Add Fairplay folder * Some delegate methods * up * up * Internal skeleton done * Add DRM config to separate playback policy * up * Added session delegate and content key session * up * Add AVPlayerItem stuff * Add DRM Token to the AVURLAsset * Now we have done it mostly * Add signed playback initializers back * move FairplaySessionManager singleton * Update Sources/MuxPlayerSwift/PublicAPI/Extensions/AVPlayerItem+Mux.swift Co-authored-by: AJ Lauer Barinov <abarinov@mux.com> * ok really move the singleton * ok really move the singleton * Caps * api support for custom domain * More capitalization * Ignore xcshareddata and .swiftpm directores, they are user-private * Fix crash on simulator (drm wont work still) * Some logging * Making license url * Add method for requesting licenses * Add Example videos * up * track playback ids * getting there * now we are maybe possibly getting somewhere * Yes we are now getting our certs and things * we don't need this method * ok here we are so far * more stuff * e2e, doesnt work yet * comments * one more todo * more * Fixes * un-dumb a comment * More logging * L O G N O I S E * comments * respect the safe area * Some adjustments * logging change * unneeded field, nonsense comment * here we go * todo- error handling * dont crash * Rename a completion handler * Now that is cleaner * Less pointless base64 * eke a little more progress * One more step * rename slightly * testability * here we go * Custom domains mostly in * calculating license correctly * Ok thats custom domains afaik * here we go * here we go * ok * app cert url * ok custom domains * fetch app certs * And one rename * And one rename * cleaning up * comment: recapitalize FairplaySessionManager * up * one last thing * More cleanup, even more oh my god * Extract FairPlaySessionManager into a protocol --------- Co-authored-by: AJ Lauer Barinov <abarinov@mux.com> maint: Add Unit Tests for FairPlaySessionManager + good DRM errors + small testability changes (#40) * Ok here we go * different URLSessions * Fairplay -> FairPlay * move helpers out of the protocol * root domain testable * file for fpssm tests * warnings * there we go. one test * Rename FairPlaySessionManagerImpl to DefaultFPSMangaer * Ok that's the trivial tests * do the URLProtcol thing * Mock URLSession * Test success case for requestLicense * Errors * Error * ok there's license almost done * some tests * Tests added * So far so good * now throw the right errors * Added tests, need to update license error returns * Ok now that's some good error handling * Finished Cert and license tests * test app cert request * no more warnings * Ok removed TempError * cleanup a little * little note * Cleanup more * Oops forgot ckc request headers * refactor: redirect singleton calls to injected dependencies refactor: place AVContentKeySession behind a protocol build: fix build issues and tests test setup fix test inject correctly remove empty extension and avoid docc style comments for internal methods remove optionals * Rename abbreviated identifiers and split apart protocols * Remove test session delegate * turns out we do not need this * refactor: minimize implicit singleton calls * test: validate DRM registration when drm token provided * Non-public API, use extension to initialize URL * avoid tripping up docc for internal extensions * cleaner test * route calls to one chokepoint for simplicity * We can use generics instead I think * add a few comments * some comments * some comments * Need to set ContentKeyDelegate * Tests for ContentKeySessionDelegate + Testability Tweaks (#44) * Extract AVContentKeyRequest protocol * remove ContentKeyDelegate methods we're not using * Hook in KeyRequest * record some mocks * ok this is what we can do * here is something * Something more * now we are somewhere * lol * setting up * now we have something goin * errors * there we go * tests * more error * more tests * Content key path * happy path * more * Now that works * now we are somewhere * PR Comment: back to one SessionManager * PR Comments: back to SessionMangaer * And the tests * PR comments: make some stuff optional * nit --------- Co-authored-by: AJ Lauer Barinov <abarinov@mux.com> Remove region-check for staging Beta notice for DRM chore: merge v1.0.0 changes (#46) * feat: expose API for configuring existing player view controllers (#41) * feat: expose API for configuring existing player view controllers to match what is provided for AVPlayerLayer * docs: fixup grammar * fix: remove rendition order ascending (#43) * docs: fixups (#42) * Fix up AVPlayerLayer too * docs: typos * docs: monitoring options improvements * feat: HLS proxy server and URLCache integration (#24) * fix: expose initializers (#26) * feat: reverse proxy server * test: add additional ui for testing * use URLCache built-in as storage * chore: add basic ABR observation * chore: extract manifest processing to separate class, log cache size and segment size * chore: rename playlist parsing to reflect technical definitions and purpose (including tests) (#27) * test: account for percent encoding when checking URLs in query params --------- Co-authored-by: Christian Pillsbury <cjpillsbury@gmail.com> * chore: emit SDK diagnostics into unified logging system (#30) * fix: Add basic cmaf support. (#31) * fix: invert API for the smart cache (#32) * fix: add extra percent encoding to avoid origin url truncation (#37) * fix: add extra percent encoding to avoid origin url truncation * fix tests * fix: cache error fallback (#38) * build: update Data SDK * [NFC] reverse proxy cleanup * use Foundation APIs to extract origin URL query value * Squashed commit of the following: commit d83a9aca216c77ea8997bd6111165c6cf5019e4e Author: AJ Lauer Barinov <abarinov@mux.com> Date: Mon May 6 19:28:48 2024 -0700 fix customer data passthrough to data commit 8048f53fde6f32552835e159a46f641b55b161cb Author: AJ Lauer Barinov <abarinov@mux.com> Date: Mon May 6 19:28:27 2024 -0700 fix asc commit 4e673dec1858d0b8f08160abfed0873370da0396 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Mon May 6 19:28:15 2024 -0700 experiments commit cff3c873a33182755eff6326bdfa1250a4b0b191 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Fri May 3 14:41:32 2024 -0700 configurable playback modifiers when testing cache commit 2e3d21e Author: AJ Lauer Barinov <abarinov@mux.com> Date: Fri May 3 13:42:44 2024 -0700 configrable playback modifiers in example commit e013cc3 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Thu May 2 14:02:09 2024 -0700 fix: cache error fallback (#38) * build: update Data SDK * [NFC] reverse proxy cleanup * use Foundation APIs to extract origin URL query value commit a642a87 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Fri Apr 26 12:19:43 2024 -0700 fix: add extra percent encoding to avoid origin url truncation (#37) * fix: add extra percent encoding to avoid origin url truncation * fix tests commit 47cfaf7 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Fri Feb 23 16:24:39 2024 -0800 fix: invert API for the smart cache (#32) commit efdeee0 Author: Christian Pillsbury <cjpillsbury@gmail.com> Date: Fri Feb 16 08:50:51 2024 -0800 fix: Add basic cmaf support. (#31) commit f03a419 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Tue Feb 13 14:45:59 2024 -0800 chore: emit SDK diagnostics into unified logging system (#30) commit 4d56d11 Author: AJ Lauer Barinov <abarinov@mux.com> Date: Tue Feb 13 11:54:41 2024 -0800 feat: HLS proxy server and URLCache integration (#24) * fix: expose initializers (#26) * feat: reverse proxy server * test: add additional ui for testing * use URLCache built-in as storage * chore: add basic ABR observation * chore: extract manifest processing to separate class, log cache size and segment size * chore: rename playlist parsing to reflect technical definitions and purpose (including tests) (#27) * test: account for percent encoding when checking URLs in query params --------- Co-authored-by: Christian Pillsbury <cjpillsbury@gmail.com> * chore: example cleanup * chore: update version * chore: remove debug view * ci: add documentation generation scripts * remove debug view controller * feat: gate smart cache to single rendition playlists * docs: release instructions * docs: fixup single rendition enum descriptions * docs: add the actual release steps * build: update to AVPlayer Data SDK with privacy manifest * start-up reverse proxy only when required include additional examples * SingleResolutionTier -> SingleRenditionResolutionTier * Update installation version in README * remove readme callout and create consolidated script for docs regeneration * fix example * fix capitalization * disable diagnostics logging when in release mode * Separate initialization method for single renditions To help with example in guide. A separate init method rather than a default parameter helps with discoverability of the enableSmartCache option * test: improve tests * chore: expose environment variable accessors * docs: add DRM example scaffolding * add TODO * restart player when example menu options change --------- Co-authored-by: Christian Pillsbury <cjpillsbury@gmail.com> fix: avoid setting empty custom domain in example (#47) fix: initialize player item only once (#48) chore: content key internal improvements (#49) * additional environment variables * chore: add a content key logger * refactor: centralize URL construction inputs * refactor: simplify URL construction logic add recovery for when license or application certificate endpoint URLs fail to be constructed * fix: silent exception when deserializing empty response * chore: use logger in content key session delegate and some minor syntactic clean-up * chore: emit failure to find playback ID in SKD log in the caller chore: enable background mode picture in picture playback in the example (#50) chore: synchronize project/drm with main (#51) * feat: expose API for configuring existing player view controllers (#41) * feat: expose API for configuring existing player view controllers to match what is provided for AVPlayerLayer * docs: fixup grammar * fix: remove rendition order ascending (#43) * docs: fixups (#42) * Fix up AVPlayerLayer too * docs: typos * docs: monitoring options improvements * v1.0.0 (#45) * feat: HLS proxy server and URLCache integration (#24) * test: add additional ui for testing * use URLCache built-in as storage * chore: add basic ABR observation * chore: extract manifest processing to separate class, log cache size and segment size * chore: rename playlist parsing to reflect technical definitions and purpose (including tests) (#27) * test: account for percent encoding when checking URLs in query params --------- Co-authored-by: Christian Pillsbury <cjpillsbury@gmail.com> * chore: emit SDK diagnostics into unified logging system (#30) * fix: Add basic cmaf support. (#31) * fix: invert API for the smart cache (#32) * fix: add extra percent encoding to avoid origin url truncation (#37) * fix: cache error fallback (#38) * build: update Data SDK
1 parent ffc6b34 commit cf35e0d

25 files changed

+2470
-200
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,8 @@ fastlane/test_output
9696
# https://github.com/johnno1962/injectionforxcode
9797

9898
iOSInjectionProject/
99+
100+
# The Example App xcodeproj creates these files when a custom scheme is made
101+
102+
.swiftpm
103+
Examples/MuxPlayerSwiftExample/MuxPlayerSwiftExample.xcodeproj/xcshareddata

Examples/MuxPlayerSwiftExample/MuxPlayerSwiftExample.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
19DD16AF2BEC010400F4DF4F /* SinglePlayerExampleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19DD16AE2BEC010400F4DF4F /* SinglePlayerExampleController.swift */; };
2121
19DD16B12BEC028C00F4DF4F /* SmartCacheExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19DD16B02BEC028C00F4DF4F /* SmartCacheExampleViewController.swift */; };
2222
19DD16B32BEC048300F4DF4F /* SinglePlayerLayerExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19DD16B22BEC048300F4DF4F /* SinglePlayerLayerExampleViewController.swift */; };
23+
19F6A1CE2C2F23EC00EE408A /* DRMExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19F6A1CD2C2F23EC00EE408A /* DRMExampleViewController.swift */; };
2324
/* End PBXBuildFile section */
2425

2526
/* Begin PBXContainerItemProxy section */
@@ -40,6 +41,7 @@
4041
/* End PBXContainerItemProxy section */
4142

4243
/* Begin PBXFileReference section */
44+
190579AD2BEDC90E00A697B8 /* DRMExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DRMExampleViewController.swift; sourceTree = "<group>"; };
4345
193228B72ACF6AC700966FE1 /* MuxPlayerSwiftExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MuxPlayerSwiftExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
4446
193228BA2ACF6AC700966FE1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
4547
193228BC2ACF6AC700966FE1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -56,6 +58,8 @@
5658
19DD16AE2BEC010400F4DF4F /* SinglePlayerExampleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SinglePlayerExampleController.swift; sourceTree = "<group>"; };
5759
19DD16B02BEC028C00F4DF4F /* SmartCacheExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartCacheExampleViewController.swift; sourceTree = "<group>"; };
5860
19DD16B22BEC048300F4DF4F /* SinglePlayerLayerExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SinglePlayerLayerExampleViewController.swift; sourceTree = "<group>"; };
61+
19F6A1CD2C2F23EC00EE408A /* DRMExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DRMExampleViewController.swift; sourceTree = "<group>"; };
62+
358572012BD9FB700098C3F6 /* DRMExamples.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DRMExamples.swift; sourceTree = "<group>"; };
5963
/* End PBXFileReference section */
6064

6165
/* Begin PBXFrameworksBuildPhase section */
@@ -91,6 +95,7 @@
9195
193228D02ACF6AC900966FE1 /* MuxPlayerSwiftExampleTests */,
9296
193228DA2ACF6AC900966FE1 /* MuxPlayerSwiftExampleUITests */,
9397
193228B82ACF6AC700966FE1 /* Products */,
98+
19F6A1CC2C2F227200EE408A /* Recovered References */,
9499
);
95100
sourceTree = "<group>";
96101
};
@@ -112,6 +117,7 @@
112117
19DD16AE2BEC010400F4DF4F /* SinglePlayerExampleController.swift */,
113118
19DD16B02BEC028C00F4DF4F /* SmartCacheExampleViewController.swift */,
114119
19DD16B22BEC048300F4DF4F /* SinglePlayerLayerExampleViewController.swift */,
120+
19F6A1CD2C2F23EC00EE408A /* DRMExampleViewController.swift */,
115121
193228C02ACF6AC700966FE1 /* Main.storyboard */,
116122
193228C32ACF6AC800966FE1 /* Assets.xcassets */,
117123
193228C52ACF6AC800966FE1 /* LaunchScreen.storyboard */,
@@ -138,6 +144,15 @@
138144
path = MuxPlayerSwiftExampleUITests;
139145
sourceTree = "<group>";
140146
};
147+
19F6A1CC2C2F227200EE408A /* Recovered References */ = {
148+
isa = PBXGroup;
149+
children = (
150+
358572012BD9FB700098C3F6 /* DRMExamples.swift */,
151+
190579AD2BEDC90E00A697B8 /* DRMExampleViewController.swift */,
152+
);
153+
name = "Recovered References";
154+
sourceTree = "<group>";
155+
};
141156
/* End PBXGroup section */
142157

143158
/* Begin PBXNativeTarget section */
@@ -275,6 +290,7 @@
275290
isa = PBXSourcesBuildPhase;
276291
buildActionMask = 2147483647;
277292
files = (
293+
19F6A1CE2C2F23EC00EE408A /* DRMExampleViewController.swift in Sources */,
278294
19DD16B32BEC048300F4DF4F /* SinglePlayerLayerExampleViewController.swift in Sources */,
279295
193228BB2ACF6AC700966FE1 /* AppDelegate.swift in Sources */,
280296
19DD16B12BEC028C00F4DF4F /* SmartCacheExampleViewController.swift in Sources */,

Examples/MuxPlayerSwiftExample/MuxPlayerSwiftExample/AppDelegate.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
// MuxPlayerSwiftExample
44
//
55

6+
import AVFoundation
67
import UIKit
78

89
@main
910
class AppDelegate: UIResponder, UIApplicationDelegate {
1011
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
11-
// Override point for customization after application launch.
12+
let audioSession = AVAudioSession.sharedInstance()
13+
do {
14+
try audioSession.setCategory(AVAudioSession.Category.playback)
15+
} catch {
16+
print("Setting category to AVAudioSessionCategoryPlayback failed.")
17+
}
18+
1219
return true
1320
}
1421

Examples/MuxPlayerSwiftExample/MuxPlayerSwiftExample/Base.lproj/Main.storyboard

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,33 @@
101101
<segue destination="JrU-9c-zyG" kind="show" id="q3v-VV-Yv9"/>
102102
</connections>
103103
</tableViewCell>
104+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="OjC-bp-Jb4" detailTextLabel="bKF-tz-9d2" rowHeight="88" style="IBUITableViewCellStyleSubtitle" id="odP-sm-cIe">
105+
<rect key="frame" x="0.0" y="314" width="393" height="88"/>
106+
<autoresizingMask key="autoresizingMask"/>
107+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="odP-sm-cIe" id="dOo-zJ-LIx">
108+
<rect key="frame" x="0.0" y="0.0" width="393" height="88"/>
109+
<autoresizingMask key="autoresizingMask"/>
110+
<subviews>
111+
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="DRM Example" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="OjC-bp-Jb4" userLabel="DRM Example">
112+
<rect key="frame" x="20.000000000000007" y="21.333333333333329" width="122.66666666666667" height="24"/>
113+
<autoresizingMask key="autoresizingMask"/>
114+
<fontDescription key="fontDescription" type="system" pointSize="20"/>
115+
<nil key="textColor"/>
116+
<nil key="highlightedColor"/>
117+
</label>
118+
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Using AVPlayerViewController" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bKF-tz-9d2" userLabel="Using AVPlayerViewController">
119+
<rect key="frame" x="20" y="49" width="169.33333333333334" height="14.333333333333334"/>
120+
<autoresizingMask key="autoresizingMask"/>
121+
<fontDescription key="fontDescription" type="system" pointSize="0.0"/>
122+
<nil key="textColor"/>
123+
<nil key="highlightedColor"/>
124+
</label>
125+
</subviews>
126+
</tableViewCellContentView>
127+
<connections>
128+
<segue destination="buK-6n-LKx" kind="show" id="eWu-XH-VJ4"/>
129+
</connections>
130+
</tableViewCell>
104131
</cells>
105132
</tableViewSection>
106133
</sections>
@@ -163,6 +190,22 @@
163190
</objects>
164191
<point key="canvasLocation" x="-161" y="271"/>
165192
</scene>
193+
<!--Example View Controller-->
194+
<scene sceneID="U4Y-IB-cxt">
195+
<objects>
196+
<viewController id="buK-6n-LKx" customClass="DRMExampleViewController" customModule="MuxPlayerSwiftExample" customModuleProvider="target" sceneMemberID="viewController">
197+
<view key="view" contentMode="scaleToFill" id="FcW-4i-Ijl">
198+
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
199+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
200+
<viewLayoutGuide key="safeArea" id="kho-JC-OWZ"/>
201+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
202+
</view>
203+
<navigationItem key="navigationItem" id="ZYa-D0-7Yh"/>
204+
</viewController>
205+
<placeholder placeholderIdentifier="IBFirstResponder" id="vny-A5-ZSO" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
206+
</objects>
207+
<point key="canvasLocation" x="434" y="573"/>
208+
</scene>
166209
<!--Navigation Controller-->
167210
<scene sceneID="2gk-Ck-Rao">
168211
<objects>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//
2+
// DRMExampleViewController.swift
3+
// MuxPlayerSwiftExample
4+
//
5+
6+
import AVKit
7+
import UIKit
8+
9+
import MuxPlayerSwift
10+
11+
class DRMExampleViewController: UIViewController {
12+
13+
// MARK: Player View Controller
14+
15+
lazy var playerViewController = AVPlayerViewController(
16+
playbackID: playbackID,
17+
playbackOptions: PlaybackOptions(
18+
playbackToken: playbackToken,
19+
drmToken: drmToken,
20+
customDomain: customDomain
21+
)
22+
)
23+
24+
// MARK: Mux Data Monitoring Parameters
25+
26+
var playerName: String = "MuxPlayerSwift-DRMExample"
27+
28+
var environmentKey: String? {
29+
ProcessInfo.processInfo.environmentKey
30+
}
31+
32+
// MARK: Mux Video Playback Parameters
33+
34+
var playbackID: String {
35+
ProcessInfo.processInfo.playbackID ?? "qxb01i6T202018GFS02vp9RIe01icTcDCjVzQpmaB00CUisJ4"
36+
}
37+
38+
// TODO: Display error alert if ProcessInfo returns nil
39+
var playbackToken: String {
40+
ProcessInfo.processInfo.playbackToken ?? ""
41+
}
42+
43+
// TODO: Display error alert if ProcessInfo returns nil
44+
var drmToken: String {
45+
ProcessInfo.processInfo.drmToken ?? ""
46+
}
47+
48+
// TODO: Display error alert if ProcessInfo returns nil
49+
var customDomain: String? {
50+
ProcessInfo.processInfo.customDomain ?? nil
51+
}
52+
53+
// MARK: Status Bar Appearance
54+
55+
override var childForStatusBarStyle: UIViewController? {
56+
playerViewController
57+
}
58+
59+
// MARK: View Controller Lifecycle
60+
61+
override func viewDidLoad() {
62+
super.viewDidLoad()
63+
64+
view.backgroundColor = .black
65+
66+
playerViewController.delegate = self
67+
playerViewController.allowsPictureInPicturePlayback = true
68+
playerViewController.canStartPictureInPictureAutomaticallyFromInline = true
69+
70+
displayPlayerViewController()
71+
}
72+
73+
// MARK: Player Lifecycle
74+
75+
func displayPlayerViewController() {
76+
playerViewController.willMove(toParent: self)
77+
addChild(playerViewController)
78+
view.addSubview(playerViewController.view)
79+
playerViewController.didMove(toParent: self)
80+
playerViewController
81+
.view
82+
.translatesAutoresizingMaskIntoConstraints = false
83+
view.addConstraints([
84+
playerViewController.view.leadingAnchor.constraint(
85+
equalTo: view.leadingAnchor
86+
),
87+
playerViewController.view.trailingAnchor.constraint(
88+
equalTo: view.trailingAnchor
89+
),
90+
playerViewController.view.layoutMarginsGuide.topAnchor.constraint(
91+
equalTo: view.topAnchor
92+
),
93+
playerViewController.view.layoutMarginsGuide.bottomAnchor
94+
.constraint(equalTo: view.bottomAnchor),
95+
])
96+
}
97+
98+
func hidePlayerViewController() {
99+
playerViewController.willMove(toParent: nil)
100+
playerViewController.view.removeFromSuperview()
101+
playerViewController.removeFromParent()
102+
}
103+
104+
}
105+
106+
extension DRMExampleViewController: AVPlayerViewControllerDelegate{
107+
func playerViewController(
108+
_ playerViewController: AVPlayerViewController,
109+
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
110+
) {
111+
completionHandler(true)
112+
}
113+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Examples.swift
3+
// MuxPlayerSwiftExample
4+
//
5+
// Created by Emily Dixon on 4/24/24.
6+
//
7+
8+
import Foundation
9+
10+
struct DRMExample {
11+
let title: String
12+
let playbackID: String
13+
let playbackToken: String
14+
let drmToken: String
15+
}
16+
17+
extension DRMExample {
18+
static let DRM_EXAMPLES = [
19+
DRMExample(
20+
title: "Staging test PlaybackID 1",
21+
playbackID: "UHMpUMz4l00SmDcgAAQPd4Yk01200IDwD4uD7K24GPp01yg" ,
22+
playbackToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ2IiwiZXhwIjoxNzIyNjE2OTc0LCJraWQiOiJFelE2SkI1ZkQwMmd5TmVxUmE4MDJYT2xnMDE0SzAxckxwdXNDbklRSjJobEtYbyIsInN1YiI6IlVITXBVTXo0bDAwU21EY2dBQVFQZDRZazAxMjAwSUR3RDR1RDdLMjRHUHAwMXlnIn0.rDymk2prKKDqlSKMnWDl24YNQ_LfnPlEzkBFr2-M3Yb_0mABE_bp-a2NeIKgwmqPxSvS0VAXpJApMbNa1j43yzW8oQxyZZXWnw0NLTQfdKfafDs83JVJB7uhL7MeEXcs1lpJGwLPSDYwdIPt2dKNzbATjqRViYbUO4GF14cq_35xsCb-kZy4D42_pdn62K6XnDUqccEeUmBav8W7m8ZILZ4eBJJJdCGVB9B85uGse_YTokGrXZ-chVO-uZ328B6ns_ehnhbJPtpstmUHvaqo0Xf0qF1J7pKkpbVoMwyhERB6M70m3oijP2GM1kLKAayrh1ujmNRNTXLcRJeBobqmPg",
23+
drmToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsIiwiZXhwIjoxNzIyNjE2OTE0LCJraWQiOiJFelE2SkI1ZkQwMmd5TmVxUmE4MDJYT2xnMDE0SzAxckxwdXNDbklRSjJobEtYbyIsInN1YiI6IlVITXBVTXo0bDAwU21EY2dBQVFQZDRZazAxMjAwSUR3RDR1RDdLMjRHUHAwMXlnIn0.tHmqMgHf3pY2adP9QVvx9VIUVZvaxzWZP8Qf4DSUBnT4Zxac-tRPBsHDtBlFIILhmPhjBa2IAmD2PdqgHopSxw_zDp9ktTl6QAKCGgw40ZUKt4GD4aZKubKzAyfPm5q0-7f8aW8oNDbejQ1VjN5QqIBb50ytyPc4NkIzwqJ3P3azrr4TSlo-NiXbXhwWuiMHGqspoNPk8BGBcXpSML7vghlncxwKWYAwbpPaz5q5AEMmN5sqKo7woSVsXBxoe78al6cfT2SRdDR6bu92kMf5zSZ9600boNSjmNn2Dx5IidFAZMYy9qVj22W1T-7rCthmc37c9OcUGK9g0unHEAFE6A"
24+
),
25+
DRMExample(
26+
title: "Staging Test PlaybackID 2",
27+
playbackID: "OZYvDVHsfLebZw00En9vOO8Ta1pcIeuPO4Esbv2yCv4E",
28+
playbackToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ2IiwiZXhwIjoxNzIyNjE4ODQxLCJraWQiOiJFelE2SkI1ZkQwMmd5TmVxUmE4MDJYT2xnMDE0SzAxckxwdXNDbklRSjJobEtYbyIsInN1YiI6Ik9aWXZEVkhzZkxlYlp3MDBFbjl2T084VGExcGNJZXVQTzRFc2J2MnlDdjRFIn0.p4D33mKmiHZYiO4Zhihx48MNcJQu0orZkezy1Wubrr3rTMInJSSlBEqaqEKgfSo505qXHx9n-zabIuM4hbGmpVNPY2aX8L3jDZU-o076NuYCjpiB87eQd6ilimOw5U-n55uCeYDXO6WYENmsy3trq-8hBMTmdloNeFXnCx1aECETU4ZmXXo3GnZBkWEWpRHyVqhFFOYxkeEWWHMvgrGoqkZHvLhHC93H9maz3KKCrqFqJeFrEo_idoJ-AsBqYhTGKhO2uGV_fhGUda6Qetc9QrqEK0WuxHwqpRbjR1cyvTbWDwCcvES1gXx4UDiWs1wdpZuyC3j2Y4LuPGAiLVWatA",
29+
drmToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJsIiwiZXhwIjoxNzIyNjE4ODI4LCJraWQiOiJFelE2SkI1ZkQwMmd5TmVxUmE4MDJYT2xnMDE0SzAxckxwdXNDbklRSjJobEtYbyIsInN1YiI6Ik9aWXZEVkhzZkxlYlp3MDBFbjl2T084VGExcGNJZXVQTzRFc2J2MnlDdjRFIn0.K6CCI-RGsTXGK0y-u2SseXea33tR5SbbX9wvucF7j0UictV6_VB0TsZe3SPlU_3ST0ecedLegbyJu-_4I6h7-XDApfXCGslYFoqM5iZnQ_5YtL0Zkdeh2iHJZKyS-mH_z6lyojggbFPLFGgRC0gZVfXJwdDtAUi33wOnlvkvGOdzNXmJCrRInkg7OfRKvLzxkQnQ0kTagKtq74Uv5JpG6XeascSi6tXExM8KVxG-4VEWHvBqCQvrpV6xlZmSnlOvoLT7E2oQB-6rwvy4cFnA_1ZASxHxiAZTNppPTmdmDYxDUd8qwJiL7MtF73sfqcrooH-z9p35u9t7eqiUGlslcA"
30+
)
31+
]
32+
}

Examples/MuxPlayerSwiftExample/MuxPlayerSwiftExample/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,9 @@
2121
</array>
2222
</dict>
2323
</dict>
24+
<key>UIBackgroundModes</key>
25+
<array>
26+
<string>audio</string>
27+
</array>
2428
</dict>
2529
</plist>

0 commit comments

Comments
 (0)