expo-video 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/android/build.gradle +2 -2
- package/expo-module.config.json +1 -1
- package/ios/VideoPlayer.swift +1 -1
- package/ios/VideoPlayerItem.swift +3 -1
- package/ios/VideoPlayerObserver.swift +74 -22
- package/ios/VideoSourceLoader.swift +44 -8
- package/ios/VideoSourceLoaderListener.swift +34 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.module → 2.2.1/expo.modules.video-2.2.1.module} +7 -7
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.pom → 2.2.1/expo.modules.video-2.2.1.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -1
- package/package.json +2 -2
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha512 +0 -1
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0-sources.jar → 2.2.1/expo.modules.video-2.2.1-sources.jar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0-sources.jar.md5 → 2.2.1/expo.modules.video-2.2.1-sources.jar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0-sources.jar.sha1 → 2.2.1/expo.modules.video-2.2.1-sources.jar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0-sources.jar.sha256 → 2.2.1/expo.modules.video-2.2.1-sources.jar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0-sources.jar.sha512 → 2.2.1/expo.modules.video-2.2.1-sources.jar.sha512} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.aar → 2.2.1/expo.modules.video-2.2.1.aar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.aar.md5 → 2.2.1/expo.modules.video-2.2.1.aar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.aar.sha1 → 2.2.1/expo.modules.video-2.2.1.aar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.aar.sha256 → 2.2.1/expo.modules.video-2.2.1.aar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.2.0/expo.modules.video-2.2.0.aar.sha512 → 2.2.1/expo.modules.video-2.2.1.aar.sha512} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 2.2.1 — 2025-06-10
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
13
17
|
## 2.2.0 — 2025-06-04
|
|
14
18
|
|
|
15
19
|
### 🎉 New features
|
|
@@ -21,6 +25,10 @@
|
|
|
21
25
|
- [Android] Fix `onFirstFrameRender` not being emitted for sources with `pixelWidthHeightRatio` different than 1. ([#37009](https://github.com/expo/expo/pull/37009) by [@behenate](https://github.com/behenate))
|
|
22
26
|
- [Android] Fix `useExoShutter` prop not being exposed to the JS side. ([#37012](https://github.com/expo/expo/pull/37012) by [@behenate](https://github.com/behenate))
|
|
23
27
|
- [Android] Add missing `onFirstFrameRender` event to the `VideoView` definition. ([#37014](https://github.com/expo/expo/pull/37014) by [@behenate](https://github.com/behenate))
|
|
28
|
+
- [iOS] Fix player not entering 'error' state when loading fails on iOS. ([#37177](https://github.com/expo/expo/pull/37177) by [@behenate](https://github.com/behenate))
|
|
29
|
+
- [iOS] Fix player reporting status `readyToPlay` while a source is being loaded asynchronously. ([#37180](https://github.com/expo/expo/pull/37180) by [@behenate](https://github.com/behenate))
|
|
30
|
+
- [iOS] Fix player going into `loading` status for a single frame when unpausing with a full buffer. ([#37181](https://github.com/expo/expo/pull/37181) by [@behenate](https://github.com/behenate))
|
|
31
|
+
- [iOS] Fix player getting stuck in `loading` state for null sources. ([#37183](https://github.com/expo/expo/pull/37183) by [@behenate](https://github.com/behenate))
|
|
24
32
|
|
|
25
33
|
## 2.1.9 — 2025-05-08
|
|
26
34
|
|
package/android/build.gradle
CHANGED
package/expo-module.config.json
CHANGED
package/ios/VideoPlayer.swift
CHANGED
|
@@ -169,7 +169,7 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
169
169
|
|
|
170
170
|
private override init(_ ref: AVPlayer) {
|
|
171
171
|
super.init(ref)
|
|
172
|
-
observer = VideoPlayerObserver(owner: self)
|
|
172
|
+
observer = VideoPlayerObserver(owner: self, videoSourceLoader: videoSourceLoader)
|
|
173
173
|
observer?.registerDelegate(delegate: self)
|
|
174
174
|
VideoManager.shared.register(videoPlayer: self)
|
|
175
175
|
|
|
@@ -37,7 +37,9 @@ class VideoPlayerItem: AVPlayerItem {
|
|
|
37
37
|
|
|
38
38
|
let asset = VideoAsset(url: url, videoSource: videoSource)
|
|
39
39
|
self.urlAsset = asset
|
|
40
|
-
|
|
40
|
+
// We can ignore any exceptions thrown during the load. The asset will be assigned to the `VideoPlayer` anyways
|
|
41
|
+
// and cause it to go into .error state trigerring the `onStatusChange` event.
|
|
42
|
+
_ = try? await asset.load(.duration, .preferredTransform, .isPlayable)
|
|
41
43
|
|
|
42
44
|
super.init(asset: urlAsset, automaticallyLoadedAssetKeys: nil)
|
|
43
45
|
self.createTracksLoadingTask()
|
|
@@ -69,13 +69,15 @@ final class WeakPlayerObserverDelegate: Hashable {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
class VideoPlayerObserver {
|
|
72
|
+
class VideoPlayerObserver: VideoSourceLoaderListener {
|
|
73
73
|
private weak var owner: VideoPlayer?
|
|
74
|
+
private weak var videoSourceLoader: VideoSourceLoader?
|
|
74
75
|
var player: AVPlayer? {
|
|
75
76
|
owner?.ref
|
|
76
77
|
}
|
|
77
78
|
var delegates = Set<WeakPlayerObserverDelegate>()
|
|
78
79
|
private var currentItem: VideoPlayerItem?
|
|
80
|
+
private var isLoadingAsynchronously = false
|
|
79
81
|
private var loadedCurrentItem = false
|
|
80
82
|
private var periodicTimeObserver: Any?
|
|
81
83
|
private var currentVideoTrack: VideoTrack? {
|
|
@@ -98,11 +100,21 @@ class VideoPlayerObserver {
|
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
private var error: Exception?
|
|
101
|
-
private var
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
private var _status: PlayerStatus = .idle
|
|
104
|
+
private var status: PlayerStatus {
|
|
105
|
+
get {
|
|
106
|
+
return _status
|
|
107
|
+
}
|
|
108
|
+
set {
|
|
109
|
+
if newValue != .loading && isLoadingAsynchronously {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if let player, newValue != status {
|
|
114
|
+
let oldStatus = self._status
|
|
115
|
+
_status = newValue
|
|
104
116
|
delegates.forEach { delegate in
|
|
105
|
-
delegate.value?.onStatusChanged(player: player, oldStatus:
|
|
117
|
+
delegate.value?.onStatusChanged(player: player, oldStatus: oldStatus, newStatus: status, error: error)
|
|
106
118
|
}
|
|
107
119
|
}
|
|
108
120
|
}
|
|
@@ -127,9 +139,11 @@ class VideoPlayerObserver {
|
|
|
127
139
|
private var currentSubtitlesObserver: NSObjectProtocol?
|
|
128
140
|
private var currentAudioTracksObserver: NSObjectProtocol?
|
|
129
141
|
|
|
130
|
-
init(owner: VideoPlayer) {
|
|
142
|
+
init(owner: VideoPlayer, videoSourceLoader: VideoSourceLoader) {
|
|
131
143
|
self.owner = owner
|
|
144
|
+
self.videoSourceLoader = videoSourceLoader
|
|
132
145
|
initializePlayerObservers()
|
|
146
|
+
self.videoSourceLoader?.registerListener(listener: self)
|
|
133
147
|
}
|
|
134
148
|
|
|
135
149
|
deinit {
|
|
@@ -146,6 +160,7 @@ class VideoPlayerObserver {
|
|
|
146
160
|
}
|
|
147
161
|
|
|
148
162
|
func cleanup() {
|
|
163
|
+
self.videoSourceLoader?.unregisterListener(listener: self)
|
|
149
164
|
delegates.removeAll()
|
|
150
165
|
invalidatePlayerObservers()
|
|
151
166
|
invalidateCurrentPlayerItemObservers()
|
|
@@ -347,24 +362,18 @@ class VideoPlayerObserver {
|
|
|
347
362
|
if player?.status != .failed {
|
|
348
363
|
error = nil
|
|
349
364
|
}
|
|
350
|
-
|
|
351
|
-
switch playerItem.status {
|
|
352
|
-
case .unknown:
|
|
365
|
+
if owner?.videoSourceLoader.isLoading == true {
|
|
353
366
|
status = .loading
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
367
|
+
return
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
let newStatus = playerItem.status.toVideoPlayerStatus(isPlaybackBufferEmpty: playerItem.isPlaybackBufferEmpty)
|
|
371
|
+
|
|
372
|
+
// The AVPlayerItem.error can't be modified, so we have a custom field for caching errors
|
|
373
|
+
if newStatus == .error {
|
|
374
|
+
let playerItemError = (playerItem as? VideoPlayerItem)?.urlAsset.cachingError ?? playerItem.error ?? error
|
|
357
375
|
error = PlayerItemLoadException(playerItemError?.localizedDescription)
|
|
358
376
|
status = .error
|
|
359
|
-
case .readyToPlay:
|
|
360
|
-
if playerItem.isPlaybackBufferEmpty {
|
|
361
|
-
status = .loading
|
|
362
|
-
} else {
|
|
363
|
-
status = .readyToPlay
|
|
364
|
-
}
|
|
365
|
-
@unknown default:
|
|
366
|
-
log.error("Unhandled `AVPlayerItem.Status` value: \(playerItem.status), returning `.loading` as fallback. Add the missing case as soon as possible.")
|
|
367
|
-
status = .loading
|
|
368
377
|
}
|
|
369
378
|
|
|
370
379
|
if let player, !loadedCurrentItem && (status == .readyToPlay || status == .error) {
|
|
@@ -400,7 +409,16 @@ class VideoPlayerObserver {
|
|
|
400
409
|
if player.timeControlStatus != .waitingToPlayAtSpecifiedRate && player.status == .readyToPlay && currentItem?.isPlaybackBufferEmpty != true {
|
|
401
410
|
status = .readyToPlay
|
|
402
411
|
} else if player.timeControlStatus == .waitingToPlayAtSpecifiedRate {
|
|
403
|
-
|
|
412
|
+
switch player.reasonForWaitingToPlay {
|
|
413
|
+
case .noItemToPlay:
|
|
414
|
+
status = .idle
|
|
415
|
+
case .evaluatingBufferingRate:
|
|
416
|
+
// Every time the player is unpaused timeControlStatus goes into .waitingToPlayAtSpecifiedRate while evaluating buffering rate.
|
|
417
|
+
// This takes less than a frame and we can ignore this change to avoid unnecessary status changes.
|
|
418
|
+
break
|
|
419
|
+
default:
|
|
420
|
+
status = .loading
|
|
421
|
+
}
|
|
404
422
|
}
|
|
405
423
|
|
|
406
424
|
if isPlaying != (player.timeControlStatus == .playing) {
|
|
@@ -445,6 +463,21 @@ class VideoPlayerObserver {
|
|
|
445
463
|
}
|
|
446
464
|
}
|
|
447
465
|
}
|
|
466
|
+
|
|
467
|
+
// MARK: - VideoSourceLoaderListener
|
|
468
|
+
func onLoadingStarted(loader: VideoSourceLoader, videoSource: VideoSource?) {
|
|
469
|
+
isLoadingAsynchronously = true
|
|
470
|
+
status = .loading
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
func onLoadingCancelled(loader: VideoSourceLoader, videoSource: VideoSource?) {
|
|
474
|
+
isLoadingAsynchronously = false
|
|
475
|
+
status = .idle
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
func onLoadingFinished(loader: VideoSourceLoader, videoSource: VideoSource?, result: VideoPlayerItem?) {
|
|
479
|
+
isLoadingAsynchronously = false
|
|
480
|
+
}
|
|
448
481
|
}
|
|
449
482
|
|
|
450
483
|
private extension AVPlayerItemAccessLogEvent {
|
|
@@ -469,3 +502,22 @@ private extension AVPlayerItemAccessLogEvent {
|
|
|
469
502
|
return videoTracks.first { $0.id == id }
|
|
470
503
|
}
|
|
471
504
|
}
|
|
505
|
+
|
|
506
|
+
fileprivate extension AVPlayerItem.Status {
|
|
507
|
+
func toVideoPlayerStatus(isPlaybackBufferEmpty: Bool) -> PlayerStatus {
|
|
508
|
+
switch self {
|
|
509
|
+
case .unknown:
|
|
510
|
+
return .loading
|
|
511
|
+
case .failed:
|
|
512
|
+
return .error
|
|
513
|
+
case .readyToPlay:
|
|
514
|
+
if isPlaybackBufferEmpty {
|
|
515
|
+
return .loading
|
|
516
|
+
}
|
|
517
|
+
return .readyToPlay
|
|
518
|
+
@unknown default:
|
|
519
|
+
log.error("Unhandled `AVPlayerItem.Status` value: \(self), returning `.loading` as fallback. Add the missing case as soon as possible.")
|
|
520
|
+
return .loading
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
@@ -2,7 +2,19 @@ import AVKit
|
|
|
2
2
|
|
|
3
3
|
internal class VideoSourceLoader {
|
|
4
4
|
private(set) var isLoading: Bool = true
|
|
5
|
-
private var
|
|
5
|
+
private var currentSource: VideoSource?
|
|
6
|
+
private var currentTask: Task<LoadingResult, Error>?
|
|
7
|
+
|
|
8
|
+
private var listeners = Set<WeakVideoSourceLoaderListener>()
|
|
9
|
+
|
|
10
|
+
func registerListener(listener: VideoSourceLoaderListener) {
|
|
11
|
+
let weakListener = WeakVideoSourceLoaderListener(value: listener)
|
|
12
|
+
listeners.insert(weakListener)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func unregisterListener(listener: VideoSourceLoaderListener) {
|
|
16
|
+
listeners.remove(WeakVideoSourceLoaderListener(value: listener))
|
|
17
|
+
}
|
|
6
18
|
|
|
7
19
|
/**
|
|
8
20
|
Asynchronously loads a video item from the provided `videoSource`. If another loading operation is in progress, it will be cancelled.
|
|
@@ -12,16 +24,31 @@ internal class VideoSourceLoader {
|
|
|
12
24
|
*/
|
|
13
25
|
func load(videoSource: VideoSource) async throws -> VideoPlayerItem? {
|
|
14
26
|
isLoading = true
|
|
15
|
-
currentTask
|
|
27
|
+
if let currentTask {
|
|
28
|
+
currentTask.cancel()
|
|
29
|
+
listeners.forEach { listener in
|
|
30
|
+
listener.value?.onLoadingCancelled(loader: self, videoSource: currentSource)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
16
33
|
|
|
17
34
|
let newTask = Task {
|
|
18
35
|
return try await loadImpl(videoSource: videoSource)
|
|
19
36
|
}
|
|
20
37
|
|
|
21
38
|
self.currentTask = newTask
|
|
22
|
-
|
|
39
|
+
self.currentSource = videoSource
|
|
40
|
+
let loadingResult = try await newTask.value
|
|
41
|
+
|
|
42
|
+
if !loadingResult.isCancelled {
|
|
43
|
+
listeners.forEach { listener in
|
|
44
|
+
listener.value?.onLoadingFinished(loader: self, videoSource: videoSource, result: loadingResult.value)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
isLoading = false
|
|
24
|
-
|
|
49
|
+
self.currentSource = nil
|
|
50
|
+
self.currentTask = nil
|
|
51
|
+
return loadingResult.value
|
|
25
52
|
}
|
|
26
53
|
|
|
27
54
|
func cancelCurrentTask() {
|
|
@@ -34,20 +61,29 @@ internal class VideoSourceLoader {
|
|
|
34
61
|
cancelCurrentTask()
|
|
35
62
|
}
|
|
36
63
|
|
|
37
|
-
private func loadImpl(videoSource: VideoSource) async throws ->
|
|
64
|
+
private func loadImpl(videoSource: VideoSource) async throws -> LoadingResult {
|
|
65
|
+
listeners.forEach { listener in
|
|
66
|
+
listener.value?.onLoadingStarted(loader: self, videoSource: videoSource)
|
|
67
|
+
}
|
|
68
|
+
|
|
38
69
|
guard
|
|
39
70
|
let url = videoSource.uri
|
|
40
71
|
else {
|
|
41
|
-
return nil
|
|
72
|
+
return LoadingResult(value: nil, isCancelled: false)
|
|
42
73
|
}
|
|
43
74
|
|
|
44
75
|
let playerItem = try await VideoPlayerItem(videoSource: videoSource)
|
|
45
76
|
|
|
46
77
|
if Task.isCancelled {
|
|
47
78
|
print("The loading task has been cancelled")
|
|
48
|
-
return nil
|
|
79
|
+
return LoadingResult(value: nil, isCancelled: true)
|
|
49
80
|
}
|
|
50
81
|
|
|
51
|
-
return playerItem
|
|
82
|
+
return LoadingResult(value: playerItem, isCancelled: false)
|
|
52
83
|
}
|
|
53
84
|
}
|
|
85
|
+
|
|
86
|
+
private struct LoadingResult {
|
|
87
|
+
let value: VideoPlayerItem?
|
|
88
|
+
let isCancelled: Bool
|
|
89
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
protocol VideoSourceLoaderListener: AnyObject {
|
|
4
|
+
func onLoadingStarted(loader: VideoSourceLoader, videoSource: VideoSource?)
|
|
5
|
+
func onLoadingFinished(loader: VideoSourceLoader, videoSource: VideoSource?, result: VideoPlayerItem?)
|
|
6
|
+
func onLoadingCancelled(loader: VideoSourceLoader, videoSource: VideoSource?)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
extension VideoSourceLoaderListener {
|
|
10
|
+
func onLoadingStarted(loader: VideoSourceLoader, videoSource: VideoSource?) {}
|
|
11
|
+
func onLoadingFinished(loader: VideoSourceLoader, videoSource: VideoSource?, result: VideoPlayerItem?) {}
|
|
12
|
+
func onLoadingCancelled(loader: VideoSourceLoader, videoSource: VideoSource?) {}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
final class WeakVideoSourceLoaderListener: Hashable {
|
|
16
|
+
private(set) weak var value: VideoSourceLoaderListener?
|
|
17
|
+
|
|
18
|
+
init(value: VideoSourceLoaderListener? = nil) {
|
|
19
|
+
self.value = value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static func == (lhs: WeakVideoSourceLoaderListener, rhs: WeakVideoSourceLoaderListener) -> Bool {
|
|
23
|
+
guard let lhsValue = lhs.value, let rhsValue = rhs.value else {
|
|
24
|
+
return lhs.value == nil && rhs.value == nil
|
|
25
|
+
}
|
|
26
|
+
return ObjectIdentifier(lhsValue) == ObjectIdentifier(rhsValue)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func hash(into hasher: inout Hasher) {
|
|
30
|
+
if let value {
|
|
31
|
+
hasher.combine(ObjectIdentifier(value))
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.video",
|
|
6
|
-
"version": "2.2.
|
|
6
|
+
"version": "2.2.1",
|
|
7
7
|
"attributes": {
|
|
8
8
|
"org.gradle.status": "release"
|
|
9
9
|
}
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
{
|
|
27
|
-
"name": "expo.modules.video-2.2.
|
|
28
|
-
"url": "expo.modules.video-2.2.
|
|
27
|
+
"name": "expo.modules.video-2.2.1.aar",
|
|
28
|
+
"url": "expo.modules.video-2.2.1.aar",
|
|
29
29
|
"size": 444322,
|
|
30
30
|
"sha512": "a1501f7e947680eba85a049cf0520518bca4feca64832fbdc41383cb2c483f6253ecf8d429ad936966fcce1b0494175035399894dbce9c50f4765bd099edebf1",
|
|
31
31
|
"sha256": "0022fab08b59c4346e67a4bf573af546f4f0e7eb322aee1115335e035318fa2c",
|
|
@@ -113,8 +113,8 @@
|
|
|
113
113
|
],
|
|
114
114
|
"files": [
|
|
115
115
|
{
|
|
116
|
-
"name": "expo.modules.video-2.2.
|
|
117
|
-
"url": "expo.modules.video-2.2.
|
|
116
|
+
"name": "expo.modules.video-2.2.1.aar",
|
|
117
|
+
"url": "expo.modules.video-2.2.1.aar",
|
|
118
118
|
"size": 444322,
|
|
119
119
|
"sha512": "a1501f7e947680eba85a049cf0520518bca4feca64832fbdc41383cb2c483f6253ecf8d429ad936966fcce1b0494175035399894dbce9c50f4765bd099edebf1",
|
|
120
120
|
"sha256": "0022fab08b59c4346e67a4bf573af546f4f0e7eb322aee1115335e035318fa2c",
|
|
@@ -133,8 +133,8 @@
|
|
|
133
133
|
},
|
|
134
134
|
"files": [
|
|
135
135
|
{
|
|
136
|
-
"name": "expo.modules.video-2.2.
|
|
137
|
-
"url": "expo.modules.video-2.2.
|
|
136
|
+
"name": "expo.modules.video-2.2.1-sources.jar",
|
|
137
|
+
"url": "expo.modules.video-2.2.1-sources.jar",
|
|
138
138
|
"size": 52499,
|
|
139
139
|
"sha512": "c7c374ab88183e831ed5a80a5e7a6f9ef2d29d4157c7b9496e30a9f87b14c4952b1e867b29f8feedbab21badccdf1b751f3a20367d1970a5e814311d96618f0e",
|
|
140
140
|
"sha256": "ff54e2221752092ebdece914b77e4504b2864fc94504c8a1887ea67a2afa5ea0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cb55d9d9221ca022327d2de165aedbee
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
be39ceedddcaaf953d676467b3927f50e7ed548b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
53814f15e51286b6229b601265835761f6c64266002c3216fb933fda817efbb2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0954a801c43e9242b4db377ad2b306f55d0f85dea74e8cb11aa206ed7ff680d00ea98ed496496987c4ed87af271f01f16bfff9909ed713aec68321b9abb4704e
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<modelVersion>4.0.0</modelVersion>
|
|
10
10
|
<groupId>host.exp.exponent</groupId>
|
|
11
11
|
<artifactId>expo.modules.video</artifactId>
|
|
12
|
-
<version>2.2.
|
|
12
|
+
<version>2.2.1</version>
|
|
13
13
|
<packaging>aar</packaging>
|
|
14
14
|
<name>expo.modules.video</name>
|
|
15
15
|
<url>https://github.com/expo/expo</url>
|
package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.1/expo.modules.video-2.2.1.pom.md5
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8a19fd97be9c8431c90093d64de9b613
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0e372e48b5871a6a0626cd97273f6c85e835f4a9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b3296cfce3d47bb8a61f69e5faea5ce137f18fece4687b2e24310c974d0d97b5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bbd813cc4afc824a0160cbc648f16b3261b5f223cc78cd29135188337d54c7928cd90c7ec13e87991b7de47c4a4fab6b96e8db1775bcc503ade8fbf3ac036570
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>host.exp.exponent</groupId>
|
|
4
4
|
<artifactId>expo.modules.video</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>2.2.
|
|
7
|
-
<release>2.2.
|
|
6
|
+
<latest>2.2.1</latest>
|
|
7
|
+
<release>2.2.1</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>2.2.
|
|
9
|
+
<version>2.2.1</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20250610113903</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d175f56e996dbf7ca76d75bfe82c4d41
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1776813ac995e4f770f3461f9f4f7d125c03b710
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
56169c737354e30bd868954cb30731441d9fceba388fcf1274f0ee5462378bb3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
abde90e836a99c9272468d5749616b4e8cc162fb1d56fc7d4e7cc62e6233feaffb9e3cbd00c2d7f1af598756ace51c63b55e7b388552a93c5aaf8bed81786bf3
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-video",
|
|
3
3
|
"title": "Expo Video",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"description": "A cross-platform, performant video component for React Native and Expo with Web support",
|
|
6
6
|
"main": "build/index.js",
|
|
7
7
|
"types": "build/index.d.ts",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"react": "*",
|
|
39
39
|
"react-native": "*"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "d0b4f7c27a356e8c53bfe45db39fff9e96906a2e"
|
|
42
42
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
c865db9b1b7212c590b04d5b3d025a92
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6c020a0af93440c2dfa817c46c65626c0be15fa5
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
dc4736ff81e3bdb761a88697e35d0a7612f679f84daab0b6f4147510254413f2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
8e05e96b0ea1f0b9c965ea20642b5654d498a8be3dadfe985675d0b0dbccb06b35dae83f2a0dde27019b678f7c73a8b1cb1dab61503a658150f6a4f55560348b
|
package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.md5
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
54ababb6162596e7ddfa9e1e415a0fd1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
49d5a63d0c4fbfb5dc9f9d45ea1512c281f2a5a2
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
af02050cf8898237faf34bc624abff592a33c4a86a34352ea485a4c3d00361f3
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6354cc8b4f6fc7cdb027d5c6302584ed0d5f8c79c61b77921dd6ffe0f751a1465eae20c7ae3f505a19070ea5f57edcbaff7a6af19934124f740461e734dc0f96
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|