Skip to content

Commit

Permalink
VEX-5938: Update resource loader to handle encrypted local files (24i#12
Browse files Browse the repository at this point in the history
)

Adds offline decryption key and uses it to decrypt content during offline playback

Jira: VEX-5938
https://jira.tenkasu.net/browse/VEX-5938

- Update to accept scheme for key required to play offline playback
- Uses provided scheme to intercept call from player and return the key
- Fixes player item observer removal pattern

### Reviews
- Major reviewer (domain expert): @armadilio3
  • Loading branch information
nickfujita authored Oct 28, 2021
1 parent 8b75438 commit e27baeb
Show file tree
Hide file tree
Showing 12 changed files with 570 additions and 376 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ var styles = StyleSheet.create({
* [trackId](#trackId)
* [useTextureView](#usetextureview)
* [volume](#volume)
* [localSourceEncryptionKeyScheme](#localSourceEncryptionKeyScheme)

### Event props
* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
Expand Down Expand Up @@ -915,6 +916,18 @@ Adjust the volume.

Platforms: all

#### localSourceEncryptionKeyScheme
Set the url scheme for stream encryption key for local assets

Type: String

Example:
```
localSourceEncryptionKeyScheme="my-offline-key"
```

Platforms: iOS


### Event props

Expand Down
1 change: 1 addition & 0 deletions Video.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ Video.propTypes = {
certificateUrl: PropTypes.string,
getLicense: PropTypes.func,
}),
localSourceEncryptionKeyScheme: PropTypes.string,
minLoadRetryCount: PropTypes.number,
maxBitRate: PropTypes.number,
resizeMode: PropTypes.string,
Expand Down
32 changes: 18 additions & 14 deletions ios/Video/Features/RCTPlayerObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,39 +28,43 @@ class RCTPlayerObserver: NSObject {
var _handlers: RCTPlayerObserverHandler!

var player:AVPlayer? {
willSet {
removePlayerObservers()
removePlayerTimeObserver()
}
didSet {
if player == nil {
removePlayerObservers()
removePlayerTimeObserver()
} else {
if player != nil {
addPlayerObservers()
addPlayerTimeObserver()
}
}
}
var playerItem:AVPlayerItem? {
willSet {
removePlayerItemObservers()
}
didSet {
if playerItem == nil {
removePlayerItemObservers()
} else {
if playerItem != nil {
addPlayerItemObservers()
}
}
}
var playerViewController:AVPlayerViewController? {
willSet {
removePlayerViewControllerObservers()
}
didSet {
if playerViewController == nil {
removePlayerViewControllerObservers()
} else {
if playerViewController != nil {
addPlayerViewControllerObservers()
}
}
}
var playerLayer:AVPlayerLayer? {
willSet {
removePlayerLayerObserver()
}
didSet {
if playerLayer == nil {
removePlayerLayerObserver()
} else {
addPlayerLayerObserver()
}
}
Expand Down Expand Up @@ -148,8 +152,8 @@ class RCTPlayerObserver: NSObject {

/* Cancels the previously registered time observer. */
func removePlayerTimeObserver() {
if let timeObserver = _timeObserver {
player?.removeTimeObserver(timeObserver)
if _timeObserver != nil {
player?.removeTimeObserver(_timeObserver)
_timeObserver = nil
}
}
Expand Down
20 changes: 20 additions & 0 deletions ios/Video/Features/RCTPlayerOperations.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AVFoundation
import MediaAccessibility
import Promises

let RCTVideoUnset = -1

Expand Down Expand Up @@ -157,4 +158,23 @@ enum RCTPlayerOperations {
}

}

static func seek(player: AVPlayer, playerItem:AVPlayerItem, paused:Bool, seekTime:Float, seekTolerance:Float) -> Promise<Bool> {
let timeScale:Int = 1000
let cmSeekTime:CMTime = CMTimeMakeWithSeconds(Float64(seekTime), preferredTimescale: Int32(timeScale))
let current:CMTime = playerItem.currentTime()
let tolerance:CMTime = CMTimeMake(value: Int64(seekTolerance), timescale: Int32(timeScale))

return Promise<Bool>(on: .global()) { fulfill, reject in
guard CMTimeCompare(current, cmSeekTime) != 0 else {
reject(NSError())
return
}
if !paused { player.pause() }

player.seek(to: cmSeekTime, toleranceBefore:tolerance, toleranceAfter:tolerance, completionHandler:{ (finished:Bool) in
fulfill(finished)
})
}
}
}
Loading

0 comments on commit e27baeb

Please sign in to comment.