@livekit/react-native 2.2.0 → 2.3.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.
Files changed (104) hide show
  1. package/README.md +14 -5
  2. package/android/build.gradle +1 -1
  3. package/android/gradle/wrapper/gradle-wrapper.properties +3 -1
  4. package/android/gradlew +29 -14
  5. package/android/gradlew.bat +19 -16
  6. package/android/src/main/java/com/livekit/reactnative/video/SimulcastVideoEncoderFactoryWrapper.kt +2 -2
  7. package/lib/commonjs/audio/AudioManager.js +4 -27
  8. package/lib/commonjs/audio/AudioManager.js.map +1 -1
  9. package/lib/commonjs/audio/AudioSession.js +55 -21
  10. package/lib/commonjs/audio/AudioSession.js.map +1 -1
  11. package/lib/commonjs/components/LiveKitRoom.js +3 -6
  12. package/lib/commonjs/components/LiveKitRoom.js.map +1 -1
  13. package/lib/commonjs/components/VideoTrack.js +30 -66
  14. package/lib/commonjs/components/VideoTrack.js.map +1 -1
  15. package/lib/commonjs/components/VideoView.js +32 -63
  16. package/lib/commonjs/components/VideoView.js.map +1 -1
  17. package/lib/commonjs/components/ViewPortDetector.js +15 -62
  18. package/lib/commonjs/components/ViewPortDetector.js.map +1 -1
  19. package/lib/commonjs/hooks.js +0 -63
  20. package/lib/commonjs/hooks.js.map +1 -1
  21. package/lib/commonjs/index.js +9 -84
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/commonjs/logger.js +4 -14
  24. package/lib/commonjs/logger.js.map +1 -1
  25. package/lib/commonjs/polyfills/EncoderDecoderTogether.min.js +16 -42
  26. package/lib/commonjs/polyfills/EncoderDecoderTogether.min.js.map +1 -1
  27. package/lib/commonjs/useParticipant.js +5 -13
  28. package/lib/commonjs/useParticipant.js.map +1 -1
  29. package/lib/commonjs/useRoom.js +17 -33
  30. package/lib/commonjs/useRoom.js.map +1 -1
  31. package/lib/module/audio/AudioManager.js +3 -17
  32. package/lib/module/audio/AudioManager.js.map +1 -1
  33. package/lib/module/audio/AudioSession.js +54 -14
  34. package/lib/module/audio/AudioSession.js.map +1 -1
  35. package/lib/module/components/LiveKitRoom.js +1 -0
  36. package/lib/module/components/LiveKitRoom.js.map +1 -1
  37. package/lib/module/components/VideoTrack.js +18 -44
  38. package/lib/module/components/VideoTrack.js.map +1 -1
  39. package/lib/module/components/VideoView.js +18 -42
  40. package/lib/module/components/VideoView.js.map +1 -1
  41. package/lib/module/components/ViewPortDetector.js +13 -54
  42. package/lib/module/components/ViewPortDetector.js.map +1 -1
  43. package/lib/module/hooks.js +1 -2
  44. package/lib/module/hooks.js.map +1 -1
  45. package/lib/module/index.js +5 -23
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/logger.js +2 -6
  48. package/lib/module/logger.js.map +1 -1
  49. package/lib/module/polyfills/EncoderDecoderTogether.min.js +16 -42
  50. package/lib/module/polyfills/EncoderDecoderTogether.min.js.map +1 -1
  51. package/lib/module/useParticipant.js +5 -11
  52. package/lib/module/useParticipant.js.map +1 -1
  53. package/lib/module/useRoom.js +17 -30
  54. package/lib/module/useRoom.js.map +1 -1
  55. package/lib/typescript/babel.config.d.ts +1 -0
  56. package/lib/typescript/docs/assets/icons.d.ts +0 -0
  57. package/lib/typescript/docs/assets/main.d.ts +0 -0
  58. package/lib/typescript/docs/assets/navigation.d.ts +0 -0
  59. package/lib/typescript/docs/assets/search.d.ts +0 -0
  60. package/lib/typescript/lib/commonjs/audio/AudioManager.d.ts +10 -0
  61. package/lib/typescript/lib/commonjs/audio/AudioSession.d.ts +33 -0
  62. package/lib/typescript/lib/commonjs/components/LiveKitRoom.d.ts +20 -0
  63. package/lib/typescript/lib/commonjs/components/VideoTrack.d.ts +8 -0
  64. package/lib/typescript/lib/commonjs/components/VideoView.d.ts +14 -0
  65. package/lib/typescript/lib/commonjs/components/ViewPortDetector.d.ts +30 -0
  66. package/lib/typescript/lib/commonjs/hooks.d.ts +29 -0
  67. package/lib/typescript/lib/commonjs/index.d.ts +10 -0
  68. package/lib/typescript/lib/commonjs/logger.d.ts +8 -0
  69. package/lib/typescript/lib/commonjs/useParticipant.d.ts +14 -0
  70. package/lib/typescript/lib/commonjs/useRoom.d.ts +16 -0
  71. package/lib/typescript/lib/module/audio/AudioManager.d.ts +9 -0
  72. package/lib/typescript/lib/module/audio/AudioSession.d.ts +31 -0
  73. package/lib/typescript/lib/module/components/LiveKitRoom.d.ts +22 -0
  74. package/lib/typescript/lib/module/components/VideoTrack.d.ts +9 -0
  75. package/lib/typescript/lib/module/components/VideoView.d.ts +9 -0
  76. package/lib/typescript/lib/module/components/ViewPortDetector.d.ts +29 -0
  77. package/lib/typescript/lib/module/hooks.d.ts +1 -0
  78. package/lib/typescript/lib/module/index.d.ts +18 -0
  79. package/lib/typescript/lib/module/logger.d.ts +8 -0
  80. package/lib/typescript/lib/module/polyfills/EncoderDecoderTogether.min.d.ts +0 -0
  81. package/lib/typescript/lib/module/useParticipant.d.ts +13 -0
  82. package/lib/typescript/lib/module/useRoom.d.ts +15 -0
  83. package/lib/typescript/scripts/bootstrap.d.ts +1 -0
  84. package/lib/typescript/{audio → src/audio}/AudioSession.d.ts +7 -7
  85. package/lib/typescript/{components → src/components}/LiveKitRoom.d.ts +1 -1
  86. package/lib/typescript/{components → src/components}/VideoTrack.d.ts +2 -2
  87. package/lib/typescript/{components → src/components}/VideoView.d.ts +3 -3
  88. package/lib/typescript/{components → src/components}/ViewPortDetector.d.ts +3 -3
  89. package/lib/typescript/src/hooks.d.ts +3 -0
  90. package/lib/typescript/{index.d.ts → src/index.d.ts} +3 -2
  91. package/lib/typescript/{logger.d.ts → src/logger.d.ts} +2 -2
  92. package/lib/typescript/src/polyfills/EncoderDecoderTogether.min.d.ts +0 -0
  93. package/lib/typescript/{useRoom.d.ts → src/useRoom.d.ts} +1 -1
  94. package/package.json +23 -19
  95. package/src/components/LiveKitRoom.tsx +1 -1
  96. package/src/components/VideoTrack.tsx +7 -2
  97. package/src/components/VideoView.tsx +8 -3
  98. package/src/components/ViewPortDetector.tsx +4 -4
  99. package/src/hooks.ts +11 -9
  100. package/src/index.tsx +10 -8
  101. package/src/useRoom.ts +1 -1
  102. package/lib/typescript/hooks.d.ts +0 -2
  103. /package/lib/typescript/{audio → src/audio}/AudioManager.d.ts +0 -0
  104. /package/lib/typescript/{useParticipant.d.ts → src/useParticipant.d.ts} +0 -0
@@ -3,6 +3,7 @@ import { Platform } from 'react-native';
3
3
  import { RoomEvent } from 'livekit-client';
4
4
  import AudioSession, { getDefaultAppleAudioConfigurationForMode } from './AudioSession';
5
5
  import { log } from '..';
6
+
6
7
  /**
7
8
  * Handles setting the appropriate AVAudioSession options automatically
8
9
  * depending on the audio track states of the Room.
@@ -11,10 +12,7 @@ import { log } from '..';
11
12
  * @param preferSpeakerOutput
12
13
  * @param onConfigureNativeAudio A custom method for determining options used.
13
14
  */
14
-
15
- export function useIOSAudioManagement(room) {
16
- let preferSpeakerOutput = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
17
- let onConfigureNativeAudio = arguments.length > 2 ? arguments[2] : undefined;
15
+ export function useIOSAudioManagement(room, preferSpeakerOutput = true, onConfigureNativeAudio) {
18
16
  const [localTrackCount, setLocalTrackCount] = useState(0);
19
17
  const [remoteTrackCount, setRemoteTrackCount] = useState(0);
20
18
  const trackState = useMemo(() => computeAudioTrackState(localTrackCount, remoteTrackCount), [localTrackCount, remoteTrackCount]);
@@ -23,7 +21,6 @@ export function useIOSAudioManagement(room) {
23
21
  setLocalTrackCount(getLocalAudioTrackCount(room));
24
22
  setRemoteTrackCount(getRemoteAudioTrackCount(room));
25
23
  };
26
-
27
24
  recalculateTrackCounts();
28
25
  room.on(RoomEvent.Connected, recalculateTrackCounts);
29
26
  return () => {
@@ -34,31 +31,24 @@ export function useIOSAudioManagement(room) {
34
31
  if (Platform.OS !== 'ios') {
35
32
  return () => {};
36
33
  }
37
-
38
34
  let onLocalPublished = () => {
39
35
  setLocalTrackCount(localTrackCount + 1);
40
36
  };
41
-
42
37
  let onLocalUnpublished = () => {
43
38
  if (localTrackCount - 1 < 0) {
44
39
  log.warn('mismatched local audio track count! attempted to reduce track count below zero.');
45
40
  }
46
-
47
41
  setLocalTrackCount(Math.max(localTrackCount - 1, 0));
48
42
  };
49
-
50
43
  let onRemotePublished = () => {
51
44
  setRemoteTrackCount(remoteTrackCount + 1);
52
45
  };
53
-
54
46
  let onRemoteUnpublished = () => {
55
47
  if (remoteTrackCount - 1 < 0) {
56
48
  log.warn('mismatched remote audio track count! attempted to reduce track count below zero.');
57
49
  }
58
-
59
50
  setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));
60
51
  };
61
-
62
52
  room.on(RoomEvent.LocalTrackPublished, onLocalPublished).on(RoomEvent.LocalTrackUnpublished, onLocalUnpublished).on(RoomEvent.TrackPublished, onRemotePublished).on(RoomEvent.TrackUnpublished, onRemoteUnpublished);
63
53
  return () => {
64
54
  room.off(RoomEvent.LocalTrackPublished, onLocalPublished).off(RoomEvent.LocalTrackUnpublished, onLocalUnpublished).off(RoomEvent.TrackPublished, onRemotePublished).off(RoomEvent.TrackUnpublished, onRemoteUnpublished);
@@ -68,13 +58,11 @@ export function useIOSAudioManagement(room) {
68
58
  if (Platform.OS !== 'ios') {
69
59
  return;
70
60
  }
71
-
72
- let configFunc = onConfigureNativeAudio !== null && onConfigureNativeAudio !== void 0 ? onConfigureNativeAudio : getDefaultAppleAudioConfigurationForMode;
61
+ let configFunc = onConfigureNativeAudio ?? getDefaultAppleAudioConfigurationForMode;
73
62
  let audioConfig = configFunc(trackState, preferSpeakerOutput);
74
63
  AudioSession.setAppleAudioConfiguration(audioConfig);
75
64
  }, [trackState, onConfigureNativeAudio, preferSpeakerOutput]);
76
65
  }
77
-
78
66
  function computeAudioTrackState(localTracks, remoteTracks) {
79
67
  if (localTracks > 0 && remoteTracks > 0) {
80
68
  return 'localAndRemote';
@@ -86,11 +74,9 @@ function computeAudioTrackState(localTracks, remoteTracks) {
86
74
  return 'none';
87
75
  }
88
76
  }
89
-
90
77
  function getLocalAudioTrackCount(room) {
91
78
  return room.localParticipant.audioTrackPublications.size;
92
79
  }
93
-
94
80
  function getRemoteAudioTrackCount(room) {
95
81
  var audioTracks = 0;
96
82
  room.remoteParticipants.forEach(participant => {
@@ -1 +1 @@
1
- {"version":3,"sources":["AudioManager.ts"],"names":["useState","useEffect","useMemo","Platform","RoomEvent","AudioSession","getDefaultAppleAudioConfigurationForMode","log","useIOSAudioManagement","room","preferSpeakerOutput","onConfigureNativeAudio","localTrackCount","setLocalTrackCount","remoteTrackCount","setRemoteTrackCount","trackState","computeAudioTrackState","recalculateTrackCounts","getLocalAudioTrackCount","getRemoteAudioTrackCount","on","Connected","off","OS","onLocalPublished","onLocalUnpublished","warn","Math","max","onRemotePublished","onRemoteUnpublished","LocalTrackPublished","LocalTrackUnpublished","TrackPublished","TrackUnpublished","configFunc","audioConfig","setAppleAudioConfiguration","localTracks","remoteTracks","localParticipant","audioTrackPublications","size","audioTracks","remoteParticipants","forEach","participant"],"mappings":"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","sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { Platform } from 'react-native';\nimport { RoomEvent, Room } from 'livekit-client';\nimport AudioSession, {\n getDefaultAppleAudioConfigurationForMode,\n type AppleAudioConfiguration,\n type AudioTrackState,\n} from './AudioSession';\nimport { log } from '..';\n\n/**\n * Handles setting the appropriate AVAudioSession options automatically\n * depending on the audio track states of the Room.\n *\n * @param room\n * @param preferSpeakerOutput\n * @param onConfigureNativeAudio A custom method for determining options used.\n */\nexport function useIOSAudioManagement(\n room: Room,\n preferSpeakerOutput: boolean = true,\n onConfigureNativeAudio?: (\n trackState: AudioTrackState,\n preferSpeakerOutput: boolean\n ) => AppleAudioConfiguration\n) {\n const [localTrackCount, setLocalTrackCount] = useState(0);\n const [remoteTrackCount, setRemoteTrackCount] = useState(0);\n const trackState = useMemo(\n () => computeAudioTrackState(localTrackCount, remoteTrackCount),\n [localTrackCount, remoteTrackCount]\n );\n\n useEffect(() => {\n let recalculateTrackCounts = () => {\n setLocalTrackCount(getLocalAudioTrackCount(room));\n setRemoteTrackCount(getRemoteAudioTrackCount(room));\n };\n\n recalculateTrackCounts();\n\n room.on(RoomEvent.Connected, recalculateTrackCounts);\n\n return () => {\n room.off(RoomEvent.Connected, recalculateTrackCounts);\n };\n }, [room]);\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return () => {};\n }\n\n let onLocalPublished = () => {\n setLocalTrackCount(localTrackCount + 1);\n };\n let onLocalUnpublished = () => {\n if (localTrackCount - 1 < 0) {\n log.warn(\n 'mismatched local audio track count! attempted to reduce track count below zero.'\n );\n }\n setLocalTrackCount(Math.max(localTrackCount - 1, 0));\n };\n let onRemotePublished = () => {\n setRemoteTrackCount(remoteTrackCount + 1);\n };\n let onRemoteUnpublished = () => {\n if (remoteTrackCount - 1 < 0) {\n log.warn(\n 'mismatched remote audio track count! attempted to reduce track count below zero.'\n );\n }\n setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));\n };\n\n room\n .on(RoomEvent.LocalTrackPublished, onLocalPublished)\n .on(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .on(RoomEvent.TrackPublished, onRemotePublished)\n .on(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n\n return () => {\n room\n .off(RoomEvent.LocalTrackPublished, onLocalPublished)\n .off(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .off(RoomEvent.TrackPublished, onRemotePublished)\n .off(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n };\n }, [room, localTrackCount, remoteTrackCount]);\n\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return;\n }\n\n let configFunc =\n onConfigureNativeAudio ?? getDefaultAppleAudioConfigurationForMode;\n let audioConfig = configFunc(trackState, preferSpeakerOutput);\n AudioSession.setAppleAudioConfiguration(audioConfig);\n }, [trackState, onConfigureNativeAudio, preferSpeakerOutput]);\n}\n\nfunction computeAudioTrackState(\n localTracks: number,\n remoteTracks: number\n): AudioTrackState {\n if (localTracks > 0 && remoteTracks > 0) {\n return 'localAndRemote';\n } else if (localTracks > 0 && remoteTracks === 0) {\n return 'localOnly';\n } else if (localTracks === 0 && remoteTracks > 0) {\n return 'remoteOnly';\n } else {\n return 'none';\n }\n}\n\nfunction getLocalAudioTrackCount(room: Room): number {\n return room.localParticipant.audioTrackPublications.size;\n}\n\nfunction getRemoteAudioTrackCount(room: Room): number {\n var audioTracks = 0;\n room.remoteParticipants.forEach((participant) => {\n audioTracks += participant.audioTrackPublications.size;\n });\n\n return audioTracks;\n}\n"]}
1
+ {"version":3,"names":["useState","useEffect","useMemo","Platform","RoomEvent","AudioSession","getDefaultAppleAudioConfigurationForMode","log","useIOSAudioManagement","room","preferSpeakerOutput","onConfigureNativeAudio","localTrackCount","setLocalTrackCount","remoteTrackCount","setRemoteTrackCount","trackState","computeAudioTrackState","recalculateTrackCounts","getLocalAudioTrackCount","getRemoteAudioTrackCount","on","Connected","off","OS","onLocalPublished","onLocalUnpublished","warn","Math","max","onRemotePublished","onRemoteUnpublished","LocalTrackPublished","LocalTrackUnpublished","TrackPublished","TrackUnpublished","configFunc","audioConfig","setAppleAudioConfiguration","localTracks","remoteTracks","localParticipant","audioTrackPublications","size","audioTracks","remoteParticipants","forEach","participant"],"sources":["AudioManager.ts"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { Platform } from 'react-native';\nimport { RoomEvent, Room } from 'livekit-client';\nimport AudioSession, {\n getDefaultAppleAudioConfigurationForMode,\n type AppleAudioConfiguration,\n type AudioTrackState,\n} from './AudioSession';\nimport { log } from '..';\n\n/**\n * Handles setting the appropriate AVAudioSession options automatically\n * depending on the audio track states of the Room.\n *\n * @param room\n * @param preferSpeakerOutput\n * @param onConfigureNativeAudio A custom method for determining options used.\n */\nexport function useIOSAudioManagement(\n room: Room,\n preferSpeakerOutput: boolean = true,\n onConfigureNativeAudio?: (\n trackState: AudioTrackState,\n preferSpeakerOutput: boolean\n ) => AppleAudioConfiguration\n) {\n const [localTrackCount, setLocalTrackCount] = useState(0);\n const [remoteTrackCount, setRemoteTrackCount] = useState(0);\n const trackState = useMemo(\n () => computeAudioTrackState(localTrackCount, remoteTrackCount),\n [localTrackCount, remoteTrackCount]\n );\n\n useEffect(() => {\n let recalculateTrackCounts = () => {\n setLocalTrackCount(getLocalAudioTrackCount(room));\n setRemoteTrackCount(getRemoteAudioTrackCount(room));\n };\n\n recalculateTrackCounts();\n\n room.on(RoomEvent.Connected, recalculateTrackCounts);\n\n return () => {\n room.off(RoomEvent.Connected, recalculateTrackCounts);\n };\n }, [room]);\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return () => {};\n }\n\n let onLocalPublished = () => {\n setLocalTrackCount(localTrackCount + 1);\n };\n let onLocalUnpublished = () => {\n if (localTrackCount - 1 < 0) {\n log.warn(\n 'mismatched local audio track count! attempted to reduce track count below zero.'\n );\n }\n setLocalTrackCount(Math.max(localTrackCount - 1, 0));\n };\n let onRemotePublished = () => {\n setRemoteTrackCount(remoteTrackCount + 1);\n };\n let onRemoteUnpublished = () => {\n if (remoteTrackCount - 1 < 0) {\n log.warn(\n 'mismatched remote audio track count! attempted to reduce track count below zero.'\n );\n }\n setRemoteTrackCount(Math.max(remoteTrackCount - 1, 0));\n };\n\n room\n .on(RoomEvent.LocalTrackPublished, onLocalPublished)\n .on(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .on(RoomEvent.TrackPublished, onRemotePublished)\n .on(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n\n return () => {\n room\n .off(RoomEvent.LocalTrackPublished, onLocalPublished)\n .off(RoomEvent.LocalTrackUnpublished, onLocalUnpublished)\n .off(RoomEvent.TrackPublished, onRemotePublished)\n .off(RoomEvent.TrackUnpublished, onRemoteUnpublished);\n };\n }, [room, localTrackCount, remoteTrackCount]);\n\n useEffect(() => {\n if (Platform.OS !== 'ios') {\n return;\n }\n\n let configFunc =\n onConfigureNativeAudio ?? getDefaultAppleAudioConfigurationForMode;\n let audioConfig = configFunc(trackState, preferSpeakerOutput);\n AudioSession.setAppleAudioConfiguration(audioConfig);\n }, [trackState, onConfigureNativeAudio, preferSpeakerOutput]);\n}\n\nfunction computeAudioTrackState(\n localTracks: number,\n remoteTracks: number\n): AudioTrackState {\n if (localTracks > 0 && remoteTracks > 0) {\n return 'localAndRemote';\n } else if (localTracks > 0 && remoteTracks === 0) {\n return 'localOnly';\n } else if (localTracks === 0 && remoteTracks > 0) {\n return 'remoteOnly';\n } else {\n return 'none';\n }\n}\n\nfunction getLocalAudioTrackCount(room: Room): number {\n return room.localParticipant.audioTrackPublications.size;\n}\n\nfunction getRemoteAudioTrackCount(room: Room): number {\n var audioTracks = 0;\n room.remoteParticipants.forEach((participant) => {\n audioTracks += participant.audioTrackPublications.size;\n });\n\n return audioTracks;\n}\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,SAAS,EAAEC,OAAO,QAAQ,OAAO;AACpD,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,SAAS,QAAc,gBAAgB;AAChD,OAAOC,YAAY,IACjBC,wCAAwC,QAGnC,gBAAgB;AACvB,SAASC,GAAG,QAAQ,IAAI;;AAExB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CACnCC,IAAU,EACVC,mBAA4B,GAAG,IAAI,EACnCC,sBAG4B,EAC5B;EACA,MAAM,CAACC,eAAe,EAAEC,kBAAkB,CAAC,GAAGb,QAAQ,CAAC,CAAC,CAAC;EACzD,MAAM,CAACc,gBAAgB,EAAEC,mBAAmB,CAAC,GAAGf,QAAQ,CAAC,CAAC,CAAC;EAC3D,MAAMgB,UAAU,GAAGd,OAAO,CACxB,MAAMe,sBAAsB,CAACL,eAAe,EAAEE,gBAAgB,CAAC,EAC/D,CAACF,eAAe,EAAEE,gBAAgB,CACpC,CAAC;EAEDb,SAAS,CAAC,MAAM;IACd,IAAIiB,sBAAsB,GAAGA,CAAA,KAAM;MACjCL,kBAAkB,CAACM,uBAAuB,CAACV,IAAI,CAAC,CAAC;MACjDM,mBAAmB,CAACK,wBAAwB,CAACX,IAAI,CAAC,CAAC;IACrD,CAAC;IAEDS,sBAAsB,CAAC,CAAC;IAExBT,IAAI,CAACY,EAAE,CAACjB,SAAS,CAACkB,SAAS,EAAEJ,sBAAsB,CAAC;IAEpD,OAAO,MAAM;MACXT,IAAI,CAACc,GAAG,CAACnB,SAAS,CAACkB,SAAS,EAAEJ,sBAAsB,CAAC;IACvD,CAAC;EACH,CAAC,EAAE,CAACT,IAAI,CAAC,CAAC;EACVR,SAAS,CAAC,MAAM;IACd,IAAIE,QAAQ,CAACqB,EAAE,KAAK,KAAK,EAAE;MACzB,OAAO,MAAM,CAAC,CAAC;IACjB;IAEA,IAAIC,gBAAgB,GAAGA,CAAA,KAAM;MAC3BZ,kBAAkB,CAACD,eAAe,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,IAAIc,kBAAkB,GAAGA,CAAA,KAAM;MAC7B,IAAId,eAAe,GAAG,CAAC,GAAG,CAAC,EAAE;QAC3BL,GAAG,CAACoB,IAAI,CACN,iFACF,CAAC;MACH;MACAd,kBAAkB,CAACe,IAAI,CAACC,GAAG,CAACjB,eAAe,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,IAAIkB,iBAAiB,GAAGA,CAAA,KAAM;MAC5Bf,mBAAmB,CAACD,gBAAgB,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,IAAIiB,mBAAmB,GAAGA,CAAA,KAAM;MAC9B,IAAIjB,gBAAgB,GAAG,CAAC,GAAG,CAAC,EAAE;QAC5BP,GAAG,CAACoB,IAAI,CACN,kFACF,CAAC;MACH;MACAZ,mBAAmB,CAACa,IAAI,CAACC,GAAG,CAACf,gBAAgB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAEDL,IAAI,CACDY,EAAE,CAACjB,SAAS,CAAC4B,mBAAmB,EAAEP,gBAAgB,CAAC,CACnDJ,EAAE,CAACjB,SAAS,CAAC6B,qBAAqB,EAAEP,kBAAkB,CAAC,CACvDL,EAAE,CAACjB,SAAS,CAAC8B,cAAc,EAAEJ,iBAAiB,CAAC,CAC/CT,EAAE,CAACjB,SAAS,CAAC+B,gBAAgB,EAAEJ,mBAAmB,CAAC;IAEtD,OAAO,MAAM;MACXtB,IAAI,CACDc,GAAG,CAACnB,SAAS,CAAC4B,mBAAmB,EAAEP,gBAAgB,CAAC,CACpDF,GAAG,CAACnB,SAAS,CAAC6B,qBAAqB,EAAEP,kBAAkB,CAAC,CACxDH,GAAG,CAACnB,SAAS,CAAC8B,cAAc,EAAEJ,iBAAiB,CAAC,CAChDP,GAAG,CAACnB,SAAS,CAAC+B,gBAAgB,EAAEJ,mBAAmB,CAAC;IACzD,CAAC;EACH,CAAC,EAAE,CAACtB,IAAI,EAAEG,eAAe,EAAEE,gBAAgB,CAAC,CAAC;EAE7Cb,SAAS,CAAC,MAAM;IACd,IAAIE,QAAQ,CAACqB,EAAE,KAAK,KAAK,EAAE;MACzB;IACF;IAEA,IAAIY,UAAU,GACZzB,sBAAsB,IAAIL,wCAAwC;IACpE,IAAI+B,WAAW,GAAGD,UAAU,CAACpB,UAAU,EAAEN,mBAAmB,CAAC;IAC7DL,YAAY,CAACiC,0BAA0B,CAACD,WAAW,CAAC;EACtD,CAAC,EAAE,CAACrB,UAAU,EAAEL,sBAAsB,EAAED,mBAAmB,CAAC,CAAC;AAC/D;AAEA,SAASO,sBAAsBA,CAC7BsB,WAAmB,EACnBC,YAAoB,EACH;EACjB,IAAID,WAAW,GAAG,CAAC,IAAIC,YAAY,GAAG,CAAC,EAAE;IACvC,OAAO,gBAAgB;EACzB,CAAC,MAAM,IAAID,WAAW,GAAG,CAAC,IAAIC,YAAY,KAAK,CAAC,EAAE;IAChD,OAAO,WAAW;EACpB,CAAC,MAAM,IAAID,WAAW,KAAK,CAAC,IAAIC,YAAY,GAAG,CAAC,EAAE;IAChD,OAAO,YAAY;EACrB,CAAC,MAAM;IACL,OAAO,MAAM;EACf;AACF;AAEA,SAASrB,uBAAuBA,CAACV,IAAU,EAAU;EACnD,OAAOA,IAAI,CAACgC,gBAAgB,CAACC,sBAAsB,CAACC,IAAI;AAC1D;AAEA,SAASvB,wBAAwBA,CAACX,IAAU,EAAU;EACpD,IAAImC,WAAW,GAAG,CAAC;EACnBnC,IAAI,CAACoC,kBAAkB,CAACC,OAAO,CAAEC,WAAW,IAAK;IAC/CH,WAAW,IAAIG,WAAW,CAACL,sBAAsB,CAACC,IAAI;EACxD,CAAC,CAAC;EAEF,OAAOC,WAAW;AACpB","ignoreList":[]}
@@ -1,5 +1,6 @@
1
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
-
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
3
4
  import { NativeModules, Platform } from 'react-native';
4
5
  const LINKING_ERROR = `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
5
6
  ios: "- You have run 'pod install'\n",
@@ -9,8 +10,8 @@ const LivekitReactNative = NativeModules.LivekitReactNative ? NativeModules.Live
9
10
  get() {
10
11
  throw new Error(LINKING_ERROR);
11
12
  }
12
-
13
13
  });
14
+
14
15
  /**
15
16
  * Configuration for the underlying AudioSession.
16
17
  *
@@ -57,9 +58,7 @@ export const AndroidAudioTypePresets = {
57
58
  audioAttributesContentType: 'unknown'
58
59
  }
59
60
  };
60
- export function getDefaultAppleAudioConfigurationForMode(mode) {
61
- let preferSpeakerOutput = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
62
-
61
+ export function getDefaultAppleAudioConfigurationForMode(mode, preferSpeakerOutput = true) {
63
62
  if (mode === 'remoteOnly') {
64
63
  return {
65
64
  audioCategory: 'playback',
@@ -73,7 +72,6 @@ export function getDefaultAppleAudioConfigurationForMode(mode) {
73
72
  audioMode: preferSpeakerOutput ? 'videoChat' : 'voiceChat'
74
73
  };
75
74
  }
76
-
77
75
  return {
78
76
  audioCategory: 'soloAmbient',
79
77
  audioCategoryOptions: [],
@@ -81,19 +79,52 @@ export function getDefaultAppleAudioConfigurationForMode(mode) {
81
79
  };
82
80
  }
83
81
  export default class AudioSession {}
84
-
82
+ /**
83
+ * Applies the provided audio configuration to the underlying AudioSession.
84
+ *
85
+ * Must be called prior to connecting to a Room for the configuration to apply correctly.
86
+ *
87
+ * See also useIOSAudioManagement for automatic configuration of iOS audio options.
88
+ */
85
89
  _defineProperty(AudioSession, "configureAudio", async config => {
86
90
  await LivekitReactNative.configureAudio(config);
87
91
  });
88
-
92
+ /**
93
+ * Starts an AudioSession.
94
+ */
89
95
  _defineProperty(AudioSession, "startAudioSession", async () => {
90
96
  await LivekitReactNative.startAudioSession();
91
97
  });
92
-
98
+ /**
99
+ * Stops the existing AudioSession.
100
+ */
93
101
  _defineProperty(AudioSession, "stopAudioSession", async () => {
94
102
  await LivekitReactNative.stopAudioSession();
95
103
  });
96
-
104
+ /**
105
+ * Gets the available audio outputs for use with {@link selectAudioOutput}.
106
+ *
107
+ * {@link startAudioSession} must be called prior to using this method.
108
+ *
109
+ * For Android, will return if available:
110
+ * * "speaker"
111
+ * * "earpiece"
112
+ * * "headset"
113
+ * * "bluetooth"
114
+ *
115
+ * ----
116
+ *
117
+ * For iOS, due to OS limitations, the only available types are:
118
+ * * "default" - Use default iOS audio routing
119
+ * * "force_speaker" - Force audio output through speaker
120
+ *
121
+ * See also {@link showAudioRoutePicker} to display a route picker that
122
+ * can choose between other audio devices (i.e. headset/bluetooth/airplay),
123
+ * or use a library like `react-native-avroutepicker` for a native platform
124
+ * control.
125
+ *
126
+ * @returns the available audio output types
127
+ */
97
128
  _defineProperty(AudioSession, "getAudioOutputs", async () => {
98
129
  if (Platform.OS === 'ios') {
99
130
  return ['default', 'force_speaker'];
@@ -103,17 +134,26 @@ _defineProperty(AudioSession, "getAudioOutputs", async () => {
103
134
  return [];
104
135
  }
105
136
  });
106
-
137
+ /**
138
+ * Select the provided audio output if available.
139
+ *
140
+ * {@link startAudioSession} must be called prior to using this method.
141
+ *
142
+ * @param deviceId A deviceId retrieved from {@link getAudioOutputs}
143
+ */
107
144
  _defineProperty(AudioSession, "selectAudioOutput", async deviceId => {
108
145
  await LivekitReactNative.selectAudioOutput(deviceId);
109
146
  });
110
-
147
+ /**
148
+ * iOS only, requires iOS 11+.
149
+ *
150
+ * Displays an AVRoutePickerView for the user to choose their audio output.
151
+ */
111
152
  _defineProperty(AudioSession, "showAudioRoutePicker", async () => {
112
153
  if (Platform.OS === 'ios') {
113
154
  await LivekitReactNative.showAudioRoutePicker();
114
155
  }
115
156
  });
116
-
117
157
  _defineProperty(AudioSession, "setAppleAudioConfiguration", async config => {
118
158
  if (Platform.OS === 'ios') {
119
159
  await LivekitReactNative.setAppleAudioConfiguration(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["AudioSession.ts"],"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","LivekitReactNative","Proxy","get","Error","AndroidAudioTypePresets","communication","manageAudioFocus","audioMode","audioFocusMode","audioStreamType","audioAttributesUsageType","audioAttributesContentType","media","getDefaultAppleAudioConfigurationForMode","mode","preferSpeakerOutput","audioCategory","audioCategoryOptions","AudioSession","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker","setAppleAudioConfiguration"],"mappings":"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","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"bluetooth\"\n * 2. `\"headset\"``\n * 3. `\"speaker\"`\n * 4. `\"earpiece\"`\n *\n * * audioTypeOptions - An {@link AndroidAudioTypeOptions} object which provides the\n * audio options to use on Android.\n *\n * See {@link AndroidAudioTypePresets} for pre-configured values.\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android?: {\n preferredOutputList?: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n audioTypeOptions: AndroidAudioTypeOptions;\n };\n ios?: {\n defaultOutput?: 'speaker' | 'earpiece';\n };\n};\n\nexport type AndroidAudioTypeOptions = {\n /**\n * Whether LiveKit should handle managing the audio focus or not.\n *\n * Defaults to true.\n */\n manageAudioFocus?: boolean;\n\n /**\n * Corresponds to {@link https://developer.android.com/reference/android/media/AudioManager#setMode(int)}\n *\n * Defaults to 'inCommunication'.\n */\n audioMode?:\n | 'normal'\n | 'callScreening'\n | 'inCall'\n | 'inCommunication'\n | 'ringtone';\n\n /**\n * Corresponds to the duration hint when requesting audio focus.\n *\n * Defaults to 'gain'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#AUDIOFOCUS_GAIN}\n */\n audioFocusMode?:\n | 'gain'\n | 'gainTransient'\n | 'gainTransientExclusive'\n | 'gainTransientMayDuck';\n\n /**\n * Corresponds to Android's AudioAttributes usage type.\n *\n * Defaults to 'voiceCommunication'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesUsageType?:\n | 'alarm'\n | 'assistanceAccessibility'\n | 'assistanceNavigationGuidance'\n | 'assistanceSonification'\n | 'assistant'\n | 'game'\n | 'media'\n | 'notification'\n | 'notificationEvent'\n | 'notificationRingtone'\n | 'unknown'\n | 'voiceCommunication'\n | 'voiceCommunicationSignalling';\n\n /**\n * Corresponds to Android's AndroidAttributes content type.\n *\n * Defaults to 'speech'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesContentType?:\n | 'movie'\n | 'music'\n | 'sonification'\n | 'speech'\n | 'unknown';\n\n /**\n * Corresponds to the stream type when requesting audio focus. Used on pre-O devices.\n *\n * Defaults to 'voiceCall'\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#STREAM_VOICE_CALL}\n */\n audioStreamType?:\n | 'accessibility'\n | 'alarm'\n | 'dtmf'\n | 'music'\n | 'notification'\n | 'ring'\n | 'system'\n | 'voiceCall';\n\n /**\n * On certain Android devices, audio routing does not function properly and\n * bluetooth microphones will not work unless audio mode is set to\n * `inCommunication` or `inCall`. Audio routing is turned off those cases.\n *\n * If this set to true, will attempt to do audio routing regardless of audio mode.\n *\n * Defaults to false.\n */\n forceHandleAudioRouting?: boolean;\n};\n\nexport const AndroidAudioTypePresets: {\n /**\n * A pre-configured AndroidAudioConfiguration for voice communication.\n */\n communication: AndroidAudioTypeOptions;\n /**\n * A pre-configured AndroidAudioConfiguration for media playback.\n */\n media: AndroidAudioTypeOptions;\n} = {\n communication: {\n manageAudioFocus: true,\n audioMode: 'inCommunication',\n audioFocusMode: 'gain',\n audioStreamType: 'voiceCall',\n audioAttributesUsageType: 'voiceCommunication',\n audioAttributesContentType: 'speech',\n },\n media: {\n manageAudioFocus: true,\n audioMode: 'normal',\n audioFocusMode: 'gain',\n audioStreamType: 'music',\n audioAttributesUsageType: 'media',\n audioAttributesContentType: 'unknown',\n },\n} as const;\n\nexport type AppleAudioMode =\n | 'default'\n | 'gameChat'\n | 'measurement'\n | 'moviePlayback'\n | 'spokenAudio'\n | 'videoChat'\n | 'videoRecording'\n | 'voiceChat'\n | 'voicePrompt';\n\nexport type AppleAudioCategory =\n | 'soloAmbient'\n | 'playback'\n | 'record'\n | 'playAndRecord'\n | 'multiRoute';\n\nexport type AppleAudioCategoryOption =\n | 'mixWithOthers'\n | 'duckOthers'\n | 'interruptSpokenAudioAndMixWithOthers'\n | 'allowBluetooth'\n | 'allowBluetoothA2DP'\n | 'allowAirPlay'\n | 'defaultToSpeaker';\n\nexport type AppleAudioConfiguration = {\n audioCategory?: AppleAudioCategory;\n audioCategoryOptions?: AppleAudioCategoryOption[];\n audioMode?: AppleAudioMode;\n};\n\nexport type AudioTrackState =\n | 'none'\n | 'remoteOnly'\n | 'localOnly'\n | 'localAndRemote';\n\nexport function getDefaultAppleAudioConfigurationForMode(\n mode: AudioTrackState,\n preferSpeakerOutput: boolean = true\n): AppleAudioConfiguration {\n if (mode === 'remoteOnly') {\n return {\n audioCategory: 'playback',\n audioCategoryOptions: ['mixWithOthers'],\n audioMode: 'spokenAudio',\n };\n } else if (mode === 'localAndRemote' || mode === 'localOnly') {\n return {\n audioCategory: 'playAndRecord',\n audioCategoryOptions: ['allowBluetooth', 'mixWithOthers'],\n audioMode: preferSpeakerOutput ? 'videoChat' : 'voiceChat',\n };\n }\n\n return {\n audioCategory: 'soloAmbient',\n audioCategoryOptions: [],\n audioMode: 'default',\n };\n}\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n *\n * See also useIOSAudioManagement for automatic configuration of iOS audio options.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n\n static setAppleAudioConfiguration = async (\n config: AppleAudioConfiguration\n ) => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.setAppleAudioConfiguration(config);\n }\n };\n}\n"]}
1
+ {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","LivekitReactNative","Proxy","get","Error","AndroidAudioTypePresets","communication","manageAudioFocus","audioMode","audioFocusMode","audioStreamType","audioAttributesUsageType","audioAttributesContentType","media","getDefaultAppleAudioConfigurationForMode","mode","preferSpeakerOutput","audioCategory","audioCategoryOptions","AudioSession","_defineProperty","config","configureAudio","startAudioSession","stopAudioSession","OS","getAudioOutputs","deviceId","selectAudioOutput","showAudioRoutePicker","setAppleAudioConfiguration"],"sources":["AudioSession.ts"],"sourcesContent":["import { NativeModules, Platform } from 'react-native';\nconst LINKING_ERROR =\n `The package '@livekit/react-native' doesn't seem to be linked. Make sure: \\n\\n` +\n Platform.select({ ios: \"- You have run 'pod install'\\n\", default: '' }) +\n '- You rebuilt the app after installing the package\\n' +\n '- You are not using Expo managed workflow\\n';\n\nconst LivekitReactNative = NativeModules.LivekitReactNative\n ? NativeModules.LivekitReactNative\n : new Proxy(\n {},\n {\n get() {\n throw new Error(LINKING_ERROR);\n },\n }\n );\n\n/**\n * Configuration for the underlying AudioSession.\n *\n * ----\n * Android specific options:\n *\n * * preferredOutputList - The preferred order in which to automatically select an audio output.\n * This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.\n *\n * By default, the order is set to:\n * 1. `\"bluetooth\"\n * 2. `\"headset\"``\n * 3. `\"speaker\"`\n * 4. `\"earpiece\"`\n *\n * * audioTypeOptions - An {@link AndroidAudioTypeOptions} object which provides the\n * audio options to use on Android.\n *\n * See {@link AndroidAudioTypePresets} for pre-configured values.\n *\n * ----\n * iOS\n *\n * * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.\n *\n * By default, this is set to `\"speaker\"`\n */\nexport type AudioConfiguration = {\n android?: {\n preferredOutputList?: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];\n audioTypeOptions: AndroidAudioTypeOptions;\n };\n ios?: {\n defaultOutput?: 'speaker' | 'earpiece';\n };\n};\n\nexport type AndroidAudioTypeOptions = {\n /**\n * Whether LiveKit should handle managing the audio focus or not.\n *\n * Defaults to true.\n */\n manageAudioFocus?: boolean;\n\n /**\n * Corresponds to {@link https://developer.android.com/reference/android/media/AudioManager#setMode(int)}\n *\n * Defaults to 'inCommunication'.\n */\n audioMode?:\n | 'normal'\n | 'callScreening'\n | 'inCall'\n | 'inCommunication'\n | 'ringtone';\n\n /**\n * Corresponds to the duration hint when requesting audio focus.\n *\n * Defaults to 'gain'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#AUDIOFOCUS_GAIN}\n */\n audioFocusMode?:\n | 'gain'\n | 'gainTransient'\n | 'gainTransientExclusive'\n | 'gainTransientMayDuck';\n\n /**\n * Corresponds to Android's AudioAttributes usage type.\n *\n * Defaults to 'voiceCommunication'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesUsageType?:\n | 'alarm'\n | 'assistanceAccessibility'\n | 'assistanceNavigationGuidance'\n | 'assistanceSonification'\n | 'assistant'\n | 'game'\n | 'media'\n | 'notification'\n | 'notificationEvent'\n | 'notificationRingtone'\n | 'unknown'\n | 'voiceCommunication'\n | 'voiceCommunicationSignalling';\n\n /**\n * Corresponds to Android's AndroidAttributes content type.\n *\n * Defaults to 'speech'.\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioAttributes}\n */\n audioAttributesContentType?:\n | 'movie'\n | 'music'\n | 'sonification'\n | 'speech'\n | 'unknown';\n\n /**\n * Corresponds to the stream type when requesting audio focus. Used on pre-O devices.\n *\n * Defaults to 'voiceCall'\n *\n * See also {@link https://developer.android.com/reference/android/media/AudioManager#STREAM_VOICE_CALL}\n */\n audioStreamType?:\n | 'accessibility'\n | 'alarm'\n | 'dtmf'\n | 'music'\n | 'notification'\n | 'ring'\n | 'system'\n | 'voiceCall';\n\n /**\n * On certain Android devices, audio routing does not function properly and\n * bluetooth microphones will not work unless audio mode is set to\n * `inCommunication` or `inCall`. Audio routing is turned off those cases.\n *\n * If this set to true, will attempt to do audio routing regardless of audio mode.\n *\n * Defaults to false.\n */\n forceHandleAudioRouting?: boolean;\n};\n\nexport const AndroidAudioTypePresets: {\n /**\n * A pre-configured AndroidAudioConfiguration for voice communication.\n */\n communication: AndroidAudioTypeOptions;\n /**\n * A pre-configured AndroidAudioConfiguration for media playback.\n */\n media: AndroidAudioTypeOptions;\n} = {\n communication: {\n manageAudioFocus: true,\n audioMode: 'inCommunication',\n audioFocusMode: 'gain',\n audioStreamType: 'voiceCall',\n audioAttributesUsageType: 'voiceCommunication',\n audioAttributesContentType: 'speech',\n },\n media: {\n manageAudioFocus: true,\n audioMode: 'normal',\n audioFocusMode: 'gain',\n audioStreamType: 'music',\n audioAttributesUsageType: 'media',\n audioAttributesContentType: 'unknown',\n },\n} as const;\n\nexport type AppleAudioMode =\n | 'default'\n | 'gameChat'\n | 'measurement'\n | 'moviePlayback'\n | 'spokenAudio'\n | 'videoChat'\n | 'videoRecording'\n | 'voiceChat'\n | 'voicePrompt';\n\nexport type AppleAudioCategory =\n | 'soloAmbient'\n | 'playback'\n | 'record'\n | 'playAndRecord'\n | 'multiRoute';\n\nexport type AppleAudioCategoryOption =\n | 'mixWithOthers'\n | 'duckOthers'\n | 'interruptSpokenAudioAndMixWithOthers'\n | 'allowBluetooth'\n | 'allowBluetoothA2DP'\n | 'allowAirPlay'\n | 'defaultToSpeaker';\n\nexport type AppleAudioConfiguration = {\n audioCategory?: AppleAudioCategory;\n audioCategoryOptions?: AppleAudioCategoryOption[];\n audioMode?: AppleAudioMode;\n};\n\nexport type AudioTrackState =\n | 'none'\n | 'remoteOnly'\n | 'localOnly'\n | 'localAndRemote';\n\nexport function getDefaultAppleAudioConfigurationForMode(\n mode: AudioTrackState,\n preferSpeakerOutput: boolean = true\n): AppleAudioConfiguration {\n if (mode === 'remoteOnly') {\n return {\n audioCategory: 'playback',\n audioCategoryOptions: ['mixWithOthers'],\n audioMode: 'spokenAudio',\n };\n } else if (mode === 'localAndRemote' || mode === 'localOnly') {\n return {\n audioCategory: 'playAndRecord',\n audioCategoryOptions: ['allowBluetooth', 'mixWithOthers'],\n audioMode: preferSpeakerOutput ? 'videoChat' : 'voiceChat',\n };\n }\n\n return {\n audioCategory: 'soloAmbient',\n audioCategoryOptions: [],\n audioMode: 'default',\n };\n}\n\nexport default class AudioSession {\n /**\n * Applies the provided audio configuration to the underlying AudioSession.\n *\n * Must be called prior to connecting to a Room for the configuration to apply correctly.\n *\n * See also useIOSAudioManagement for automatic configuration of iOS audio options.\n */\n static configureAudio = async (config: AudioConfiguration) => {\n await LivekitReactNative.configureAudio(config);\n };\n\n /**\n * Starts an AudioSession.\n */\n static startAudioSession = async () => {\n await LivekitReactNative.startAudioSession();\n };\n\n /**\n * Stops the existing AudioSession.\n */\n static stopAudioSession = async () => {\n await LivekitReactNative.stopAudioSession();\n };\n\n /**\n * Gets the available audio outputs for use with {@link selectAudioOutput}.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * For Android, will return if available:\n * * \"speaker\"\n * * \"earpiece\"\n * * \"headset\"\n * * \"bluetooth\"\n *\n * ----\n *\n * For iOS, due to OS limitations, the only available types are:\n * * \"default\" - Use default iOS audio routing\n * * \"force_speaker\" - Force audio output through speaker\n *\n * See also {@link showAudioRoutePicker} to display a route picker that\n * can choose between other audio devices (i.e. headset/bluetooth/airplay),\n * or use a library like `react-native-avroutepicker` for a native platform\n * control.\n *\n * @returns the available audio output types\n */\n static getAudioOutputs = async (): Promise<string[]> => {\n if (Platform.OS === 'ios') {\n return ['default', 'force_speaker'];\n } else if (Platform.OS === 'android') {\n return (await LivekitReactNative.getAudioOutputs()) as string[];\n } else {\n return [];\n }\n };\n\n /**\n * Select the provided audio output if available.\n *\n * {@link startAudioSession} must be called prior to using this method.\n *\n * @param deviceId A deviceId retrieved from {@link getAudioOutputs}\n */\n static selectAudioOutput = async (deviceId: string) => {\n await LivekitReactNative.selectAudioOutput(deviceId);\n };\n\n /**\n * iOS only, requires iOS 11+.\n *\n * Displays an AVRoutePickerView for the user to choose their audio output.\n */\n static showAudioRoutePicker = async () => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.showAudioRoutePicker();\n }\n };\n\n static setAppleAudioConfiguration = async (\n config: AppleAudioConfiguration\n ) => {\n if (Platform.OS === 'ios') {\n await LivekitReactNative.setAppleAudioConfiguration(config);\n }\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,6 @@
1
1
  import { LKFeatureContext, RoomContext, useLiveKitRoom } from '@livekit/components-react';
2
2
  import * as React from 'react';
3
+
3
4
  /** @public */
4
5
 
5
6
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["LiveKitRoom.tsx"],"names":["LKFeatureContext","RoomContext","useLiveKitRoom","React","LiveKitRoom","props","room","featureFlags","children"],"mappings":"AAAA,SAEEA,gBAFF,EAGEC,WAHF,EAIEC,cAJF,QAKO,2BALP;AAcA,OAAO,KAAKC,KAAZ,MAAuB,OAAvB;AAEA;;AAuEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAT,CAAqBC,KAArB,EAAuE;AAC5E,QAAM;AAAEC,IAAAA;AAAF,MAAWJ,cAAc,CAACG,KAAD,CAA/B;AACA,sBACE,0CACGC,IAAI,iBACH,oBAAC,WAAD,CAAa,QAAb;AAAsB,IAAA,KAAK,EAAEA;AAA7B,kBACE,oBAAC,gBAAD,CAAkB,QAAlB;AAA2B,IAAA,KAAK,EAAED,KAAK,CAACE;AAAxC,KACGF,KAAK,CAACG,QADT,CADF,CAFJ,CADF;AAWD","sourcesContent":["import {\n FeatureFlags,\n LKFeatureContext,\n RoomContext,\n useLiveKitRoom,\n} from '@livekit/components-react';\nimport type {\n AudioCaptureOptions,\n RoomConnectOptions,\n RoomOptions,\n ScreenShareCaptureOptions,\n VideoCaptureOptions,\n} from 'livekit-client';\nimport type { MediaDeviceFailure, Room } from 'livekit-client';\nimport * as React from 'react';\n\n/** @public */\nexport interface LiveKitRoomProps {\n /**\n * URL to the LiveKit server.\n * For example: `wss://<domain>.livekit.cloud`\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string url can the connection be established.\n */\n serverUrl: string | undefined;\n /**\n * A user specific access token for a client to authenticate to the room.\n * This token is necessary to establish a connection to the room.\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string token can the connection be established.\n *\n * @see https://docs.livekit.io/cloud/project-management/keys-and-tokens/#generating-access-tokens\n */\n token: string | undefined;\n /**\n * Publish audio immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/AudioCaptureOptions.html\n */\n audio?: AudioCaptureOptions | boolean;\n /**\n * Publish video immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/VideoCaptureOptions.html\n */\n video?: VideoCaptureOptions | boolean;\n /**\n * Publish screen share immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/ScreenShareCaptureOptions.html\n */\n screen?: ScreenShareCaptureOptions | boolean;\n /**\n * If set to true a connection to LiveKit room is initiated.\n * @defaultValue `false`\n */\n connect?: boolean;\n /**\n * Options for when creating a new room.\n * When you pass your own room instance to this component, these options have no effect.\n * Instead, set the options directly in the room instance.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomOptions.html\n */\n options?: RoomOptions;\n /**\n * Define options how to connect to the LiveKit server.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomConnectOptions.html\n */\n connectOptions?: RoomConnectOptions;\n onConnected?: () => void;\n onDisconnected?: () => void;\n onError?: (error: Error) => void;\n onMediaDeviceFailure?: (failure?: MediaDeviceFailure) => void;\n onEncryptionError?: (error: Error) => void;\n /**\n * Optional room instance.\n * By passing your own room instance you overwrite the `options` parameter,\n * make sure to set the options directly on the room instance itself.\n */\n room?: Room;\n\n simulateParticipants?: number | undefined;\n\n /** @experimental */\n featureFlags?: FeatureFlags | undefined;\n}\n\n/**\n * The `LiveKitRoom` component provides the room context to all its child components.\n * It is generally the starting point of your LiveKit app and the root of the LiveKit component tree.\n * It provides the room state as a React context to all child components, so you don't have to pass it yourself.\n *\n * @example\n * ```tsx\n * <LiveKitRoom\n * token='<livekit-token>'\n * serverUrl='<url-to-livekit-server>'\n * connect={true}\n * >\n * ...\n * </LiveKitRoom>\n * ```\n * @public\n */\nexport function LiveKitRoom(props: React.PropsWithChildren<LiveKitRoomProps>) {\n const { room } = useLiveKitRoom(props);\n return (\n <>\n {room && (\n <RoomContext.Provider value={room}>\n <LKFeatureContext.Provider value={props.featureFlags}>\n {props.children}\n </LKFeatureContext.Provider>\n </RoomContext.Provider>\n )}\n </>\n );\n}\n"]}
1
+ {"version":3,"names":["LKFeatureContext","RoomContext","useLiveKitRoom","React","LiveKitRoom","props","room","createElement","Fragment","Provider","value","featureFlags","children"],"sources":["LiveKitRoom.tsx"],"sourcesContent":["import {\n type FeatureFlags,\n LKFeatureContext,\n RoomContext,\n useLiveKitRoom,\n} from '@livekit/components-react';\nimport type {\n AudioCaptureOptions,\n RoomConnectOptions,\n RoomOptions,\n ScreenShareCaptureOptions,\n VideoCaptureOptions,\n} from 'livekit-client';\nimport type { MediaDeviceFailure, Room } from 'livekit-client';\nimport * as React from 'react';\n\n/** @public */\nexport interface LiveKitRoomProps {\n /**\n * URL to the LiveKit server.\n * For example: `wss://<domain>.livekit.cloud`\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string url can the connection be established.\n */\n serverUrl: string | undefined;\n /**\n * A user specific access token for a client to authenticate to the room.\n * This token is necessary to establish a connection to the room.\n * To simplify the implementation, `undefined` is also accepted as an intermediate value, but only with a valid string token can the connection be established.\n *\n * @see https://docs.livekit.io/cloud/project-management/keys-and-tokens/#generating-access-tokens\n */\n token: string | undefined;\n /**\n * Publish audio immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/AudioCaptureOptions.html\n */\n audio?: AudioCaptureOptions | boolean;\n /**\n * Publish video immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/VideoCaptureOptions.html\n */\n video?: VideoCaptureOptions | boolean;\n /**\n * Publish screen share immediately after connecting to your LiveKit room.\n * @defaultValue `false`\n * @see https://docs.livekit.io/client-sdk-js/interfaces/ScreenShareCaptureOptions.html\n */\n screen?: ScreenShareCaptureOptions | boolean;\n /**\n * If set to true a connection to LiveKit room is initiated.\n * @defaultValue `false`\n */\n connect?: boolean;\n /**\n * Options for when creating a new room.\n * When you pass your own room instance to this component, these options have no effect.\n * Instead, set the options directly in the room instance.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomOptions.html\n */\n options?: RoomOptions;\n /**\n * Define options how to connect to the LiveKit server.\n *\n * @see https://docs.livekit.io/client-sdk-js/interfaces/RoomConnectOptions.html\n */\n connectOptions?: RoomConnectOptions;\n onConnected?: () => void;\n onDisconnected?: () => void;\n onError?: (error: Error) => void;\n onMediaDeviceFailure?: (failure?: MediaDeviceFailure) => void;\n onEncryptionError?: (error: Error) => void;\n /**\n * Optional room instance.\n * By passing your own room instance you overwrite the `options` parameter,\n * make sure to set the options directly on the room instance itself.\n */\n room?: Room;\n\n simulateParticipants?: number | undefined;\n\n /** @experimental */\n featureFlags?: FeatureFlags | undefined;\n}\n\n/**\n * The `LiveKitRoom` component provides the room context to all its child components.\n * It is generally the starting point of your LiveKit app and the root of the LiveKit component tree.\n * It provides the room state as a React context to all child components, so you don't have to pass it yourself.\n *\n * @example\n * ```tsx\n * <LiveKitRoom\n * token='<livekit-token>'\n * serverUrl='<url-to-livekit-server>'\n * connect={true}\n * >\n * ...\n * </LiveKitRoom>\n * ```\n * @public\n */\nexport function LiveKitRoom(props: React.PropsWithChildren<LiveKitRoomProps>) {\n const { room } = useLiveKitRoom(props);\n return (\n <>\n {room && (\n <RoomContext.Provider value={room}>\n <LKFeatureContext.Provider value={props.featureFlags}>\n {props.children}\n </LKFeatureContext.Provider>\n </RoomContext.Provider>\n )}\n </>\n );\n}\n"],"mappings":"AAAA,SAEEA,gBAAgB,EAChBC,WAAW,EACXC,cAAc,QACT,2BAA2B;AASlC,OAAO,KAAKC,KAAK,MAAM,OAAO;;AAE9B;;AAuEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CAACC,KAAgD,EAAE;EAC5E,MAAM;IAAEC;EAAK,CAAC,GAAGJ,cAAc,CAACG,KAAK,CAAC;EACtC,oBACEF,KAAA,CAAAI,aAAA,CAAAJ,KAAA,CAAAK,QAAA,QACGF,IAAI,iBACHH,KAAA,CAAAI,aAAA,CAACN,WAAW,CAACQ,QAAQ;IAACC,KAAK,EAAEJ;EAAK,gBAChCH,KAAA,CAAAI,aAAA,CAACP,gBAAgB,CAACS,QAAQ;IAACC,KAAK,EAAEL,KAAK,CAACM;EAAa,GAClDN,KAAK,CAACO,QACkB,CACP,CAExB,CAAC;AAEP","ignoreList":[]}
@@ -1,5 +1,6 @@
1
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
-
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
3
4
  import * as React from 'react';
4
5
  import { StyleSheet, View } from 'react-native';
5
6
  import { LocalVideoTrack, TrackEvent } from 'livekit-client';
@@ -7,21 +8,17 @@ import { RTCView } from '@livekit/react-native-webrtc';
7
8
  import { useCallback, useEffect, useMemo, useState } from 'react';
8
9
  import { RemoteVideoTrack } from 'livekit-client';
9
10
  import ViewPortDetector from './ViewPortDetector';
10
- export const VideoTrack = _ref => {
11
- var _mediaStream$toURL;
12
-
13
- let {
14
- style = {},
15
- trackRef,
16
- objectFit = 'cover',
17
- zOrder,
18
- mirror
19
- } = _ref;
11
+ export const VideoTrack = ({
12
+ style = {},
13
+ trackRef,
14
+ objectFit = 'cover',
15
+ zOrder,
16
+ mirror
17
+ }) => {
20
18
  const [elementInfo] = useState(() => {
21
19
  var _trackRef$publication;
22
-
23
20
  let info = new VideoTrackElementInfo();
24
- info.id = trackRef === null || trackRef === void 0 ? void 0 : (_trackRef$publication = trackRef.publication) === null || _trackRef$publication === void 0 ? void 0 : _trackRef$publication.trackSid;
21
+ info.id = trackRef === null || trackRef === void 0 || (_trackRef$publication = trackRef.publication) === null || _trackRef$publication === void 0 ? void 0 : _trackRef$publication.trackSid;
25
22
  return info;
26
23
  });
27
24
  const layoutOnChange = useCallback(event => elementInfo.onLayout(event), [elementInfo]);
@@ -33,12 +30,10 @@ export const VideoTrack = _ref => {
33
30
  const [mediaStream, setMediaStream] = useState(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
34
31
  useEffect(() => {
35
32
  setMediaStream(videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.mediaStream);
36
-
37
33
  if (videoTrack instanceof LocalVideoTrack) {
38
34
  const onRestarted = track => {
39
35
  setMediaStream(track === null || track === void 0 ? void 0 : track.mediaStream);
40
36
  };
41
-
42
37
  videoTrack.on(TrackEvent.Restarted, onRestarted);
43
38
  return () => {
44
39
  videoTrack.off(TrackEvent.Restarted, onRestarted);
@@ -49,16 +44,17 @@ export const VideoTrack = _ref => {
49
44
  }, [videoTrack]);
50
45
  useEffect(() => {
51
46
  if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {
52
- videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.observeElementInfo(elementInfo);
47
+ videoTrack === null || videoTrack === void 0 || videoTrack.observeElementInfo(elementInfo);
53
48
  return () => {
54
- videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.stopObservingElementInfo(elementInfo);
49
+ videoTrack === null || videoTrack === void 0 || videoTrack.stopObservingElementInfo(elementInfo);
55
50
  };
56
51
  } else {
57
52
  return () => {};
58
53
  }
59
54
  }, [videoTrack, elementInfo]);
60
55
  return /*#__PURE__*/React.createElement(View, {
61
- style: { ...style,
56
+ style: {
57
+ ...style,
62
58
  ...styles.container
63
59
  },
64
60
  onLayout: layoutOnChange
@@ -69,7 +65,7 @@ export const VideoTrack = _ref => {
69
65
  propKey: videoTrack
70
66
  }, /*#__PURE__*/React.createElement(RTCView, {
71
67
  style: styles.videoTrack,
72
- streamURL: (_mediaStream$toURL = mediaStream === null || mediaStream === void 0 ? void 0 : mediaStream.toURL()) !== null && _mediaStream$toURL !== void 0 ? _mediaStream$toURL : '',
68
+ streamURL: (mediaStream === null || mediaStream === void 0 ? void 0 : mediaStream.toURL()) ?? '',
73
69
  objectFit: objectFit,
74
70
  zOrder: zOrder,
75
71
  mirror: mirror
@@ -82,44 +78,28 @@ const styles = StyleSheet.create({
82
78
  width: '100%'
83
79
  }
84
80
  });
85
-
86
81
  class VideoTrackElementInfo {
87
82
  constructor() {
88
83
  _defineProperty(this, "element", {});
89
-
90
84
  _defineProperty(this, "something", void 0);
91
-
92
85
  _defineProperty(this, "id", void 0);
93
-
94
86
  _defineProperty(this, "_width", 0);
95
-
96
87
  _defineProperty(this, "_height", 0);
97
-
98
88
  _defineProperty(this, "_observing", false);
99
-
100
89
  _defineProperty(this, "visible", true);
101
-
102
90
  _defineProperty(this, "visibilityChangedAt", void 0);
103
-
104
91
  _defineProperty(this, "pictureInPicture", false);
105
-
106
92
  _defineProperty(this, "handleResize", void 0);
107
-
108
93
  _defineProperty(this, "handleVisibilityChanged", void 0);
109
-
110
94
  _defineProperty(this, "width", () => this._width);
111
-
112
95
  _defineProperty(this, "height", () => this._height);
113
96
  }
114
-
115
97
  observe() {
116
98
  this._observing = true;
117
99
  }
118
-
119
100
  stopObserving() {
120
101
  this._observing = false;
121
102
  }
122
-
123
103
  onLayout(event) {
124
104
  let {
125
105
  width,
@@ -127,26 +107,20 @@ class VideoTrackElementInfo {
127
107
  } = event.nativeEvent.layout;
128
108
  this._width = width;
129
109
  this._height = height;
130
-
131
110
  if (this._observing) {
132
111
  var _this$handleResize;
133
-
134
- (_this$handleResize = this.handleResize) === null || _this$handleResize === void 0 ? void 0 : _this$handleResize.call(this);
112
+ (_this$handleResize = this.handleResize) === null || _this$handleResize === void 0 || _this$handleResize.call(this);
135
113
  }
136
114
  }
137
-
138
115
  onVisibility(isVisible) {
139
116
  if (this.visible !== isVisible) {
140
117
  this.visible = isVisible;
141
118
  this.visibilityChangedAt = Date.now();
142
-
143
119
  if (this._observing) {
144
120
  var _this$handleVisibilit;
145
-
146
- (_this$handleVisibilit = this.handleVisibilityChanged) === null || _this$handleVisibilit === void 0 ? void 0 : _this$handleVisibilit.call(this);
121
+ (_this$handleVisibilit = this.handleVisibilityChanged) === null || _this$handleVisibilit === void 0 || _this$handleVisibilit.call(this);
147
122
  }
148
123
  }
149
124
  }
150
-
151
125
  }
152
126
  //# sourceMappingURL=VideoTrack.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["VideoTrack.tsx"],"names":["React","StyleSheet","View","LocalVideoTrack","TrackEvent","RTCView","useCallback","useEffect","useMemo","useState","RemoteVideoTrack","ViewPortDetector","VideoTrack","style","trackRef","objectFit","zOrder","mirror","elementInfo","info","VideoTrackElementInfo","id","publication","trackSid","layoutOnChange","event","onLayout","visibilityOnChange","isVisible","onVisibility","videoTrack","track","shouldObserveVisibility","isAdaptiveStream","mediaStream","setMediaStream","onRestarted","on","Restarted","off","observeElementInfo","stopObservingElementInfo","styles","container","toURL","create","flex","width","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","handleResize","visible","visibilityChangedAt","Date","now","handleVisibilityChanged"],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport { LayoutChangeEvent, StyleSheet, View, ViewStyle } from 'react-native';\nimport {\n ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n} from 'livekit-client';\nimport { RTCView } from '@livekit/react-native-webrtc';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\nimport type { TrackReference } from '@livekit/components-react';\n\nexport type VideoTrackProps = {\n trackRef: TrackReference | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoTrack = ({\n style = {},\n trackRef,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: VideoTrackProps) => {\n const [elementInfo] = useState(() => {\n let info = new VideoTrackElementInfo();\n info.id = trackRef?.publication?.trackSid;\n return info;\n });\n\n const layoutOnChange = useCallback(\n (event: LayoutChangeEvent) => elementInfo.onLayout(event),\n [elementInfo]\n );\n const visibilityOnChange = useCallback(\n (isVisible: boolean) => elementInfo.onVisibility(isVisible),\n [elementInfo]\n );\n\n const videoTrack = trackRef?.publication.track;\n\n const shouldObserveVisibility = useMemo(() => {\n return (\n videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream\n );\n }, [videoTrack]);\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View style={{ ...style, ...styles.container }} onLayout={layoutOnChange}>\n <ViewPortDetector\n onChange={visibilityOnChange}\n style={styles.videoTrack}\n disabled={!shouldObserveVisibility}\n propKey={videoTrack}\n >\n <RTCView\n style={styles.videoTrack}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoTrack: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoTrackElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n pictureInPicture = false;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n this._width = width;\n this._height = height;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"]}
1
+ {"version":3,"names":["React","StyleSheet","View","LocalVideoTrack","TrackEvent","RTCView","useCallback","useEffect","useMemo","useState","RemoteVideoTrack","ViewPortDetector","VideoTrack","style","trackRef","objectFit","zOrder","mirror","elementInfo","_trackRef$publication","info","VideoTrackElementInfo","id","publication","trackSid","layoutOnChange","event","onLayout","visibilityOnChange","isVisible","onVisibility","videoTrack","track","shouldObserveVisibility","isAdaptiveStream","mediaStream","setMediaStream","onRestarted","on","Restarted","off","observeElementInfo","stopObservingElementInfo","createElement","styles","container","onChange","disabled","propKey","streamURL","toURL","create","flex","width","constructor","_defineProperty","_width","_height","observe","_observing","stopObserving","height","nativeEvent","layout","_this$handleResize","handleResize","call","visible","visibilityChangedAt","Date","now","_this$handleVisibilit","handleVisibilityChanged"],"sources":["VideoTrack.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n type LayoutChangeEvent,\n StyleSheet,\n View,\n type ViewStyle,\n} from 'react-native';\nimport {\n type ElementInfo,\n LocalVideoTrack,\n Track,\n TrackEvent,\n} from 'livekit-client';\nimport { RTCView } from '@livekit/react-native-webrtc';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { RemoteVideoTrack } from 'livekit-client';\nimport ViewPortDetector from './ViewPortDetector';\nimport type { TrackReference } from '@livekit/components-react';\n\nexport type VideoTrackProps = {\n trackRef: TrackReference | undefined;\n style?: ViewStyle;\n objectFit?: 'cover' | 'contain' | undefined;\n mirror?: boolean;\n zOrder?: number;\n};\n\nexport const VideoTrack = ({\n style = {},\n trackRef,\n objectFit = 'cover',\n zOrder,\n mirror,\n}: VideoTrackProps) => {\n const [elementInfo] = useState(() => {\n let info = new VideoTrackElementInfo();\n info.id = trackRef?.publication?.trackSid;\n return info;\n });\n\n const layoutOnChange = useCallback(\n (event: LayoutChangeEvent) => elementInfo.onLayout(event),\n [elementInfo]\n );\n const visibilityOnChange = useCallback(\n (isVisible: boolean) => elementInfo.onVisibility(isVisible),\n [elementInfo]\n );\n\n const videoTrack = trackRef?.publication.track;\n\n const shouldObserveVisibility = useMemo(() => {\n return (\n videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream\n );\n }, [videoTrack]);\n\n const [mediaStream, setMediaStream] = useState(videoTrack?.mediaStream);\n useEffect(() => {\n setMediaStream(videoTrack?.mediaStream);\n if (videoTrack instanceof LocalVideoTrack) {\n const onRestarted = (track: Track | null) => {\n setMediaStream(track?.mediaStream);\n };\n videoTrack.on(TrackEvent.Restarted, onRestarted);\n\n return () => {\n videoTrack.off(TrackEvent.Restarted, onRestarted);\n };\n } else {\n return () => {};\n }\n }, [videoTrack]);\n\n useEffect(() => {\n if (videoTrack instanceof RemoteVideoTrack && videoTrack.isAdaptiveStream) {\n videoTrack?.observeElementInfo(elementInfo);\n return () => {\n videoTrack?.stopObservingElementInfo(elementInfo);\n };\n } else {\n return () => {};\n }\n }, [videoTrack, elementInfo]);\n\n return (\n <View style={{ ...style, ...styles.container }} onLayout={layoutOnChange}>\n <ViewPortDetector\n onChange={visibilityOnChange}\n style={styles.videoTrack}\n disabled={!shouldObserveVisibility}\n propKey={videoTrack}\n >\n <RTCView\n style={styles.videoTrack}\n streamURL={mediaStream?.toURL() ?? ''}\n objectFit={objectFit}\n zOrder={zOrder}\n mirror={mirror}\n />\n </ViewPortDetector>\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {},\n videoTrack: {\n flex: 1,\n width: '100%',\n },\n});\n\nclass VideoTrackElementInfo implements ElementInfo {\n element: object = {};\n something?: any;\n id?: string;\n _width = 0;\n _height = 0;\n _observing = false;\n visible: boolean = true;\n visibilityChangedAt: number | undefined;\n pictureInPicture = false;\n handleResize?: (() => void) | undefined;\n handleVisibilityChanged?: (() => void) | undefined;\n width = () => this._width;\n height = () => this._height;\n\n observe(): void {\n this._observing = true;\n }\n stopObserving(): void {\n this._observing = false;\n }\n\n onLayout(event: LayoutChangeEvent) {\n let { width, height } = event.nativeEvent.layout;\n this._width = width;\n this._height = height;\n\n if (this._observing) {\n this.handleResize?.();\n }\n }\n onVisibility(isVisible: boolean) {\n if (this.visible !== isVisible) {\n this.visible = isVisible;\n this.visibilityChangedAt = Date.now();\n if (this._observing) {\n this.handleVisibilityChanged?.();\n }\n }\n }\n}\n"],"mappings":";;;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAEEC,UAAU,EACVC,IAAI,QAEC,cAAc;AACrB,SAEEC,eAAe,EAEfC,UAAU,QACL,gBAAgB;AACvB,SAASC,OAAO,QAAQ,8BAA8B;AACtD,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AACjE,SAASC,gBAAgB,QAAQ,gBAAgB;AACjD,OAAOC,gBAAgB,MAAM,oBAAoB;AAWjD,OAAO,MAAMC,UAAU,GAAGA,CAAC;EACzBC,KAAK,GAAG,CAAC,CAAC;EACVC,QAAQ;EACRC,SAAS,GAAG,OAAO;EACnBC,MAAM;EACNC;AACe,CAAC,KAAK;EACrB,MAAM,CAACC,WAAW,CAAC,GAAGT,QAAQ,CAAC,MAAM;IAAA,IAAAU,qBAAA;IACnC,IAAIC,IAAI,GAAG,IAAIC,qBAAqB,CAAC,CAAC;IACtCD,IAAI,CAACE,EAAE,GAAGR,QAAQ,aAARA,QAAQ,gBAAAK,qBAAA,GAARL,QAAQ,CAAES,WAAW,cAAAJ,qBAAA,uBAArBA,qBAAA,CAAuBK,QAAQ;IACzC,OAAOJ,IAAI;EACb,CAAC,CAAC;EAEF,MAAMK,cAAc,GAAGnB,WAAW,CAC/BoB,KAAwB,IAAKR,WAAW,CAACS,QAAQ,CAACD,KAAK,CAAC,EACzD,CAACR,WAAW,CACd,CAAC;EACD,MAAMU,kBAAkB,GAAGtB,WAAW,CACnCuB,SAAkB,IAAKX,WAAW,CAACY,YAAY,CAACD,SAAS,CAAC,EAC3D,CAACX,WAAW,CACd,CAAC;EAED,MAAMa,UAAU,GAAGjB,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAES,WAAW,CAACS,KAAK;EAE9C,MAAMC,uBAAuB,GAAGzB,OAAO,CAAC,MAAM;IAC5C,OACEuB,UAAU,YAAYrB,gBAAgB,IAAIqB,UAAU,CAACG,gBAAgB;EAEzE,CAAC,EAAE,CAACH,UAAU,CAAC,CAAC;EAEhB,MAAM,CAACI,WAAW,EAAEC,cAAc,CAAC,GAAG3B,QAAQ,CAACsB,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAEI,WAAW,CAAC;EACvE5B,SAAS,CAAC,MAAM;IACd6B,cAAc,CAACL,UAAU,aAAVA,UAAU,uBAAVA,UAAU,CAAEI,WAAW,CAAC;IACvC,IAAIJ,UAAU,YAAY5B,eAAe,EAAE;MACzC,MAAMkC,WAAW,GAAIL,KAAmB,IAAK;QAC3CI,cAAc,CAACJ,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEG,WAAW,CAAC;MACpC,CAAC;MACDJ,UAAU,CAACO,EAAE,CAAClC,UAAU,CAACmC,SAAS,EAAEF,WAAW,CAAC;MAEhD,OAAO,MAAM;QACXN,UAAU,CAACS,GAAG,CAACpC,UAAU,CAACmC,SAAS,EAAEF,WAAW,CAAC;MACnD,CAAC;IACH,CAAC,MAAM;MACL,OAAO,MAAM,CAAC,CAAC;IACjB;EACF,CAAC,EAAE,CAACN,UAAU,CAAC,CAAC;EAEhBxB,SAAS,CAAC,MAAM;IACd,IAAIwB,UAAU,YAAYrB,gBAAgB,IAAIqB,UAAU,CAACG,gBAAgB,EAAE;MACzEH,UAAU,aAAVA,UAAU,eAAVA,UAAU,CAAEU,kBAAkB,CAACvB,WAAW,CAAC;MAC3C,OAAO,MAAM;QACXa,UAAU,aAAVA,UAAU,eAAVA,UAAU,CAAEW,wBAAwB,CAACxB,WAAW,CAAC;MACnD,CAAC;IACH,CAAC,MAAM;MACL,OAAO,MAAM,CAAC,CAAC;IACjB;EACF,CAAC,EAAE,CAACa,UAAU,EAAEb,WAAW,CAAC,CAAC;EAE7B,oBACElB,KAAA,CAAA2C,aAAA,CAACzC,IAAI;IAACW,KAAK,EAAE;MAAE,GAAGA,KAAK;MAAE,GAAG+B,MAAM,CAACC;IAAU,CAAE;IAAClB,QAAQ,EAAEF;EAAe,gBACvEzB,KAAA,CAAA2C,aAAA,CAAChC,gBAAgB;IACfmC,QAAQ,EAAElB,kBAAmB;IAC7Bf,KAAK,EAAE+B,MAAM,CAACb,UAAW;IACzBgB,QAAQ,EAAE,CAACd,uBAAwB;IACnCe,OAAO,EAAEjB;EAAW,gBAEpB/B,KAAA,CAAA2C,aAAA,CAACtC,OAAO;IACNQ,KAAK,EAAE+B,MAAM,CAACb,UAAW;IACzBkB,SAAS,EAAE,CAAAd,WAAW,aAAXA,WAAW,uBAAXA,WAAW,CAAEe,KAAK,CAAC,CAAC,KAAI,EAAG;IACtCnC,SAAS,EAAEA,SAAU;IACrBC,MAAM,EAAEA,MAAO;IACfC,MAAM,EAAEA;EAAO,CAChB,CACe,CACd,CAAC;AAEX,CAAC;AAED,MAAM2B,MAAM,GAAG3C,UAAU,CAACkD,MAAM,CAAC;EAC/BN,SAAS,EAAE,CAAC,CAAC;EACbd,UAAU,EAAE;IACVqB,IAAI,EAAE,CAAC;IACPC,KAAK,EAAE;EACT;AACF,CAAC,CAAC;AAEF,MAAMhC,qBAAqB,CAAwB;EAAAiC,YAAA;IAAAC,eAAA,kBAC/B,CAAC,CAAC;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA,iBAGX,CAAC;IAAAA,eAAA,kBACA,CAAC;IAAAA,eAAA,qBACE,KAAK;IAAAA,eAAA,kBACC,IAAI;IAAAA,eAAA;IAAAA,eAAA,2BAEJ,KAAK;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA,gBAGhB,MAAM,IAAI,CAACC,MAAM;IAAAD,eAAA,iBAChB,MAAM,IAAI,CAACE,OAAO;EAAA;EAE3BC,OAAOA,CAAA,EAAS;IACd,IAAI,CAACC,UAAU,GAAG,IAAI;EACxB;EACAC,aAAaA,CAAA,EAAS;IACpB,IAAI,CAACD,UAAU,GAAG,KAAK;EACzB;EAEAhC,QAAQA,CAACD,KAAwB,EAAE;IACjC,IAAI;MAAE2B,KAAK;MAAEQ;IAAO,CAAC,GAAGnC,KAAK,CAACoC,WAAW,CAACC,MAAM;IAChD,IAAI,CAACP,MAAM,GAAGH,KAAK;IACnB,IAAI,CAACI,OAAO,GAAGI,MAAM;IAErB,IAAI,IAAI,CAACF,UAAU,EAAE;MAAA,IAAAK,kBAAA;MACnB,CAAAA,kBAAA,OAAI,CAACC,YAAY,cAAAD,kBAAA,eAAjBA,kBAAA,CAAAE,IAAA,KAAoB,CAAC;IACvB;EACF;EACApC,YAAYA,CAACD,SAAkB,EAAE;IAC/B,IAAI,IAAI,CAACsC,OAAO,KAAKtC,SAAS,EAAE;MAC9B,IAAI,CAACsC,OAAO,GAAGtC,SAAS;MACxB,IAAI,CAACuC,mBAAmB,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;MACrC,IAAI,IAAI,CAACX,UAAU,EAAE;QAAA,IAAAY,qBAAA;QACnB,CAAAA,qBAAA,OAAI,CAACC,uBAAuB,cAAAD,qBAAA,eAA5BA,qBAAA,CAAAL,IAAA,KAA+B,CAAC;MAClC;IACF;EACF;AACF","ignoreList":[]}