5
5
MediaTrackInfo ,
6
6
ViewProjectSourceMapping ,
7
7
MediaStreamSource ,
8
+ MediaStreamLayers ,
9
+ MediaLayer ,
10
+ LayerInfo ,
8
11
} from '@millicast/sdk' ;
9
12
import { useNetInfo } from '@react-native-community/netinfo' ;
10
13
import React , { useEffect , useRef , useState } from 'react' ;
@@ -25,7 +28,7 @@ import {
25
28
import { RTCView } from 'react-native-webrtc' ;
26
29
import { useSelector , useDispatch } from 'react-redux' ;
27
30
28
- import { RemoteTrackSource } from '../../types/RemoteTrackSource.types' ;
31
+ import { RemoteTrackSource , SimulcastQuality } from '../../types/RemoteTrackSource.types' ;
29
32
import { Routes } from '../../types/routes.types' ;
30
33
31
34
window . Logger = MillicastLogger ;
@@ -42,6 +45,7 @@ export const MultiView = ({ navigation }) => {
42
45
const playing = useSelector ( ( state ) => state . viewerReducer . playing ) ;
43
46
const error = useSelector ( ( state ) => state . viewerReducer . error ) ;
44
47
const audioRemoteTrackSource = useSelector ( ( state ) => state . viewerReducer . audioRemoteTrackSource ) ;
48
+
45
49
const dispatch = useDispatch ( ) ;
46
50
const { routes, index } = navigation . getState ( ) ;
47
51
const currentRoute = routes [ index ] . name ;
@@ -51,6 +55,7 @@ export const MultiView = ({ navigation }) => {
51
55
const sourceIdsRef = useRef ( [ ] ) ;
52
56
const netInfo = useNetInfo ( ) ;
53
57
const audioRemoteTrackSourceRef = useRef ( null ) ;
58
+
54
59
const [ isReconnectionScheduled , setIsReconnectionScheduled ] = useState < boolean > ( false ) ;
55
60
56
61
remoteTrackSourcesRef . current = remoteTrackSources ;
@@ -144,6 +149,25 @@ export const MultiView = ({ navigation }) => {
144
149
}
145
150
} ;
146
151
152
+ const buildQualityOptions = ( active , layers ) => {
153
+ const descendingLayers = active . sort ( ( a , b ) => b . height - a . height ) ;
154
+
155
+ const qualityOptions : SimulcastQuality [ ] = descendingLayers . map ( ( active ) => ( {
156
+ simulcastLayer : {
157
+ bitrate : active . bitrate ,
158
+ encodingId : active . id ,
159
+ simulcastIdx : active . simulcastIdx ,
160
+ spatialLayerId : layers . find ( ( layer ) => layer . simulcastIdx === active . simulcastIdx ) ?. spatialLayerId ,
161
+ temporalLayerId : layers . find ( ( layer ) => layer . simulcastIdx === active . simulcastIdx ) ?. temporalLayerId ,
162
+ maxSpatialLayerId : layers . find ( ( layer ) => layer . simulcastIdx === active . simulcastIdx ) ?. maxSpatialLayerId ,
163
+ maxTemporalLayerId : layers . find ( ( layer ) => layer . simulcastIdx === active . simulcastIdx ) ?. maxTemporalLayerId ,
164
+ } ,
165
+ streamQuality : `${ active . height } p` ,
166
+ } ) ) ;
167
+
168
+ return [ { streamQuality : 'Auto' } as SimulcastQuality , ...qualityOptions ] ;
169
+ } ;
170
+
147
171
const subscribe = async ( ) => {
148
172
if ( millicastViewRef . current ?. isActive ( ) ) {
149
173
return ;
@@ -193,6 +217,7 @@ export const MultiView = ({ navigation }) => {
193
217
payload : newRemoteTrackSource ,
194
218
} ) ;
195
219
}
220
+
196
221
await viewer . project ( sourceId , mappingForProjection ) ;
197
222
dispatch ( {
198
223
type : 'viewer/addRemoteTrackSource' ,
@@ -231,11 +256,15 @@ export const MultiView = ({ navigation }) => {
231
256
// A new source was multiplexed over the vad tracks
232
257
break ;
233
258
case 'layers' :
259
+ const { medias } = data ;
260
+ const mediaId = Object . keys ( medias ) [ 0 ] ;
261
+ const { active, layers } = ( data as MediaStreamLayers ) . medias [ mediaId ] ?? { } ;
262
+ const streamQualities = buildQualityOptions ( active , layers ) ;
263
+
234
264
dispatch ( {
235
265
type : 'viewer/setActiveLayers' ,
236
- payload : data . medias ?. [ '0' ] ?. active ,
266
+ payload : { mediaId , streamQualities } ,
237
267
} ) ;
238
- // Updated layer information for each simulcast/svc video track
239
268
break ;
240
269
default :
241
270
console . log ( 'Unknown event' , name ) ;
0 commit comments