expo-video 1.1.2 → 1.1.4

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 CHANGED
@@ -10,6 +10,14 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.1.4 — 2024-04-25
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 1.1.3 — 2024-04-24
18
+
19
+ _This version does not introduce any user-facing changes._
20
+
13
21
  ## 1.1.2 — 2024-04-24
14
22
 
15
23
  _This version does not introduce any user-facing changes._
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'host.exp.exponent'
4
- version = '1.1.2'
4
+ version = '1.1.4'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -14,7 +14,7 @@ android {
14
14
  namespace "expo.modules.video"
15
15
  defaultConfig {
16
16
  versionCode 1
17
- versionName '1.1.2'
17
+ versionName '1.1.4'
18
18
  }
19
19
  }
20
20
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @hidden
3
+ */
1
4
  declare const _default: any;
2
5
  export default _default;
3
6
  //# sourceMappingURL=NativeVideoModule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoModule.d.ts","sourceRoot":"","sources":["../src/NativeVideoModule.ts"],"names":[],"mappings":";AAEA,wBAAgD"}
1
+ {"version":3,"file":"NativeVideoModule.d.ts","sourceRoot":"","sources":["../src/NativeVideoModule.ts"],"names":[],"mappings":"AAEA;;GAEG;;AACH,wBAAgD"}
@@ -1,3 +1,6 @@
1
1
  import { requireNativeModule } from 'expo-modules-core';
2
+ /**
3
+ * @hidden
4
+ */
2
5
  export default requireNativeModule('ExpoVideo');
3
6
  //# sourceMappingURL=NativeVideoModule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoModule.js","sourceRoot":"","sources":["../src/NativeVideoModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAe,mBAAmB,CAAC,WAAW,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nexport default requireNativeModule('ExpoVideo');\n"]}
1
+ {"version":3,"file":"NativeVideoModule.js","sourceRoot":"","sources":["../src/NativeVideoModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,eAAe,mBAAmB,CAAC,WAAW,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\n/**\n * @hidden\n */\nexport default requireNativeModule('ExpoVideo');\n"]}
package/build/index.d.ts CHANGED
@@ -2,5 +2,5 @@ import Video from './NativeVideoModule';
2
2
  export { VideoView, isPictureInPictureSupported } from './VideoView';
3
3
  export { useVideoPlayer } from './VideoPlayer';
4
4
  export { Video };
5
- export { VideoSource, VideoPlayerEvents, VideoPlayerStatus, VideoContentFit, } from './VideoView.types';
5
+ export * from './VideoView.types';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,cAAc,mBAAmB,CAAC"}
package/build/index.js CHANGED
@@ -2,4 +2,5 @@ import Video from './NativeVideoModule';
2
2
  export { VideoView, isPictureInPictureSupported } from './VideoView';
3
3
  export { useVideoPlayer } from './VideoPlayer';
4
4
  export { Video };
5
+ export * from './VideoView.types';
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,CAAC","sourcesContent":["import Video from './NativeVideoModule';\n\nexport { VideoView, isPictureInPictureSupported } from './VideoView';\nexport { useVideoPlayer } from './VideoPlayer';\nexport { Video };\nexport {\n VideoSource,\n VideoPlayerEvents,\n VideoPlayerStatus,\n VideoContentFit,\n} from './VideoView.types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,qBAAqB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,cAAc,mBAAmB,CAAC","sourcesContent":["import Video from './NativeVideoModule';\n\nexport { VideoView, isPictureInPictureSupported } from './VideoView';\nexport { useVideoPlayer } from './VideoPlayer';\nexport { Video };\nexport * from './VideoView.types';\n"]}
@@ -50,17 +50,42 @@ class VideoManager {
50
50
 
51
51
  // MARK: - Audio Session Management
52
52
 
53
- private func switchToActiveAudioSession() throws {
53
+ internal func setAppropriateAudioSessionOrWarn() {
54
54
  let audioSession = AVAudioSession.sharedInstance()
55
- try audioSession.setCategory(.playback, mode: .moviePlayback)
56
- try audioSession.setActive(true)
57
- }
55
+ var audioSessionCategoryOptions: AVAudioSession.CategoryOptions = []
56
+
57
+ let isAnyPlayerPlaying = videoPlayers.allObjects.contains { player in
58
+ player.isPlaying
59
+ }
60
+ let areAllPlayersMuted = videoPlayers.allObjects.allSatisfy { player in
61
+ player.isMuted
62
+ }
63
+ let needsPiPSupport = videoViews.allObjects.contains { view in
64
+ view.allowPictureInPicture
65
+ }
66
+ let shouldAllowMixing = !isAnyPlayerPlaying || areAllPlayersMuted
67
+ let isOutputtingAudio = !areAllPlayersMuted && isAnyPlayerPlaying
68
+ let shouldUpdateToAllowMixing = !audioSession.categoryOptions.contains(.mixWithOthers) && shouldAllowMixing
58
69
 
59
- internal func switchToActiveAudioSessionOrWarn(warning: String) {
60
- do {
61
- try switchToActiveAudioSession()
62
- } catch {
63
- log.warn("\(warning). \(error.localizedDescription)")
70
+ if shouldAllowMixing {
71
+ audioSessionCategoryOptions.insert(.mixWithOthers)
72
+ }
73
+
74
+ if isOutputtingAudio || needsPiPSupport || shouldUpdateToAllowMixing {
75
+ do {
76
+ try audioSession.setCategory(.playback, mode: .moviePlayback, options: audioSessionCategoryOptions)
77
+ } catch {
78
+ log.warn("Failed to set audio session category. This might cause issues with audio playback and Picture in Picture. \(error.localizedDescription)")
79
+ }
80
+ }
81
+
82
+ // Make sure audio session is active if any video is playing
83
+ if isAnyPlayerPlaying {
84
+ do {
85
+ try audioSession.setActive(true)
86
+ } catch {
87
+ log.warn("Failed to activate the audio session. This might cause issues with audio playback. \(error.localizedDescription)")
88
+ }
64
89
  }
65
90
  }
66
91
  }
@@ -26,9 +26,7 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
26
26
  var staysActiveInBackground = false {
27
27
  didSet {
28
28
  if staysActiveInBackground {
29
- VideoManager.shared.switchToActiveAudioSessionOrWarn(
30
- warning: "Failed to set the audio session category. This might affect background playback functionality"
31
- )
29
+ VideoManager.shared.setAppropriateAudioSessionOrWarn()
32
30
  }
33
31
  }
34
32
  }
@@ -60,6 +58,7 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
60
58
  self.emit(event: "volumeChange", arguments: newVolumeEvent.isMuted, oldVolumeEvent.isMuted)
61
59
  }
62
60
  pointer.isMuted = isMuted
61
+ VideoManager.shared.setAppropriateAudioSessionOrWarn()
63
62
  }
64
63
  }
65
64
 
@@ -125,6 +124,8 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
125
124
  func onIsPlayingChanged(player: AVPlayer, oldIsPlaying: Bool?, newIsPlaying: Bool) {
126
125
  self.emit(event: "playingChange", arguments: newIsPlaying, oldIsPlaying)
127
126
  isPlaying = newIsPlaying
127
+
128
+ VideoManager.shared.setAppropriateAudioSessionOrWarn()
128
129
  }
129
130
 
130
131
  func onRateChanged(player: AVPlayer, oldRate: Float?, newRate: Float) {
@@ -6,7 +6,7 @@ import ExpoModulesCore
6
6
  public final class VideoView: ExpoView, AVPlayerViewControllerDelegate {
7
7
  lazy var playerViewController = AVPlayerViewController()
8
8
 
9
- var player: VideoPlayer? {
9
+ weak var player: VideoPlayer? {
10
10
  didSet {
11
11
  playerViewController.player = player?.pointer
12
12
  }
@@ -24,13 +24,8 @@ public final class VideoView: ExpoView, AVPlayerViewControllerDelegate {
24
24
 
25
25
  var allowPictureInPicture: Bool = false {
26
26
  didSet {
27
- if allowPictureInPicture {
28
- // We need to set the audio session when the prop first changes to allow, because the PiP button in the native
29
- // controls shows up automatically only when a correct audioSession category is set.
30
- VideoManager.shared.switchToActiveAudioSessionOrWarn(
31
- warning: "Failed to set the audio session category. This might break Picture in Picture functionality"
32
- )
33
- }
27
+ // PiP requires `.playback` audio session category in `.moviePlayback` mode
28
+ VideoManager.shared.setAppropriateAudioSessionOrWarn()
34
29
  playerViewController.allowsPictureInPicturePlayback = allowPictureInPicture
35
30
  }
36
31
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-video",
3
3
  "title": "Expo Video",
4
- "version": "1.1.2",
4
+ "version": "1.1.4",
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",
@@ -36,5 +36,5 @@
36
36
  "peerDependencies": {
37
37
  "expo": "*"
38
38
  },
39
- "gitHead": "f8f9d041c6467f325b58c7913e0f5ed1af102e11"
39
+ "gitHead": "f47e3af17a790a34b95fe10dda8383389e7d74e2"
40
40
  }
@@ -1,3 +1,6 @@
1
1
  import { requireNativeModule } from 'expo-modules-core';
2
2
 
3
+ /**
4
+ * @hidden
5
+ */
3
6
  export default requireNativeModule('ExpoVideo');
package/src/index.ts CHANGED
@@ -3,9 +3,4 @@ import Video from './NativeVideoModule';
3
3
  export { VideoView, isPictureInPictureSupported } from './VideoView';
4
4
  export { useVideoPlayer } from './VideoPlayer';
5
5
  export { Video };
6
- export {
7
- VideoSource,
8
- VideoPlayerEvents,
9
- VideoPlayerStatus,
10
- VideoContentFit,
11
- } from './VideoView.types';
6
+ export * from './VideoView.types';