Skip to content

Add Layer selection #141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"react-native-screen": "^1.0.1",
"react-native-screens": "^3.20.0",
"react-native-svg": "^12.3.0",
"react-native-webrtc": "github:montanaeli/react-native-webrtc#2c7b6e3",
"react-native-webrtc": "github:aravind-raveendran/react-native-webrtc#045ef81",
"react-redux": "^8.1.3",
"redux": "^4.2.1",
"redux-persist": "^6.0.0"
Expand Down
1 change: 1 addition & 0 deletions src/components/BottomBar/BottomBar.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const styles = AppStyleSheet.create({
alignItems: 'stretch',
justifyContent: 'space-between',
paddingHorizontal: 20,
width: '100%',
},
});
export default styles;
11 changes: 10 additions & 1 deletion src/components/BottomBar/BottomBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { View, TouchableOpacity, Platform } from 'react-native';

import styles from './BottomBar.style';

export const BottomBar = ({ displayStatsInformation, focus }) => {
export const BottomBar = ({ displayStatsInformation, displaySimulcastSelection, focus }) => {
const iconSize = Platform.OS === 'android' && Platform.isTV ? 's' : 'm';
return (
<View style={styles.wrapper}>
Expand All @@ -17,6 +17,15 @@ export const BottomBar = ({ displayStatsInformation, focus }) => {
>
<Icon testID="infoIcon" name="info" size={iconSize} />
</TouchableOpacity>
<TouchableOpacity
testID="settingsIconButton"
hasTVPreferredFocus={focus}
onPress={() => {
displaySimulcastSelection();
}}
>
<Icon testID="settingsIcon" name="settings" size={iconSize} />
</TouchableOpacity>
</View>
);
};
48 changes: 48 additions & 0 deletions src/components/SimulcastView/SimulcastView.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { AppStyleSheet as StyleSheet } from '@dolbyio/uikit-react-native';
import { Platform } from 'react-native';

const styles = StyleSheet.create({
outerContainer: {
flex: 1,
backgroundColor: '#292930E5',
marginTop: 100,
borderTopLeftRadius: 14,
borderTopRightRadius: 14,
},
simulcastCell: {
width: '100%',
height: 50,
flexDirection: 'row',
backgroundColor: '#34343B',
marginVertical: 5,
justifyContent: 'center',
alignContent: 'center',
},
outerContainerTV: {
height: '50%',
width: '20%',
position: 'absolute',
backgroundColor: '#292930',
bottom: 20,
left: '80%',
borderRadius: 14,
},
innerContainer: {
marginTop: 10,
flexDirection: 'column',
alignItems: 'stretch',
justifyContent: 'space-between',
paddingHorizontal: 0,
},
simulcastOptionsContainer: {
marginTop: Platform.isTV ? 10 : 60,
marginHorizontal: 16,
},
closeIcon: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 20,
paddingHorizontal: 20,
},
});
export default styles;
54 changes: 54 additions & 0 deletions src/components/SimulcastView/SimulcastView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { View, TouchableOpacity, FlatList, Platform } from 'react-native';

import Icon from '../../uikit/components/Icon/Icon';
import Text from '../text/Text';

import styles from './SimulcastView.style';

export const SimulcastView = ({ streamQualityList, selectedStreamQuality, onClose, onSelectStreamQuality }) => {
const isSelected = (streamQuality) => {
return selectedStreamQuality === streamQuality;
};
const renderItem = ({ item }) => (
<TouchableOpacity
onPress={() => {
onSelectStreamQuality(item);
}}
>
<View style={styles.simulcastCell}>
{isSelected(item.streamQuality) && <Icon testID="checkmarkIcon" name="checkmark" size="xs" />}
<Text style={{ alignSelf: 'center', height: '100%' }} type="bodyDefault">
{item.streamQuality}
</Text>
</View>
</TouchableOpacity>
);

return (
<View style={Platform.isTV ? styles.outerContainerTV : styles.outerContainer}>
<View style={styles.closeIcon}>
<TouchableOpacity testID="closeIconButton" hasTVPreferredFocus onPress={onClose}>
<Icon testID="closeIcon" name="close" size="s" />
</TouchableOpacity>
</View>
<View style={styles.innerContainer}>
<Text
testID="simulcastTitle"
id="simulcastTitle"
type="h2"
align={Platform.isTV ? 'left' : 'center'}
style={{ paddingTop: 16, paddingLeft: 16 }}
/>
<View style={styles.simulcastOptionsContainer}>
<FlatList
testID="simulcastList"
data={streamQualityList}
keyExtractor={(item) => item.streamQuality}
renderItem={renderItem}
/>
</View>
</View>
</View>
);
};
3 changes: 3 additions & 0 deletions src/components/SimulcastView/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { SimulcastView } from './SimulcastView';

export default SimulcastView;
1 change: 1 addition & 0 deletions src/components/StreamStats/StreamStats.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const styles = StyleSheet.create({
bottom: 20,
left: 20,
borderRadius: 14,
position: 'absolute',
},
innerContainer: {
marginTop: 10,
Expand Down
37 changes: 34 additions & 3 deletions src/screens/multiview/MultiView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
MediaTrackInfo,
ViewProjectSourceMapping,
MediaStreamSource,
MediaStreamLayers,
MediaLayer,

Check warning on line 9 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

'MediaLayer' is defined but never used
LayerInfo,

Check warning on line 10 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

'LayerInfo' is defined but never used
} from '@millicast/sdk';
import { useNetInfo } from '@react-native-community/netinfo';
import React, { useEffect, useRef, useState } from 'react';
Expand All @@ -25,7 +28,7 @@
import { RTCView } from 'react-native-webrtc';
import { useSelector, useDispatch } from 'react-redux';

import { RemoteTrackSource } from '../../types/RemoteTrackSource.types';
import { RemoteTrackSource, SimulcastQuality } from '../../types/RemoteTrackSource.types';
import { Routes } from '../../types/routes.types';

window.Logger = MillicastLogger;
Expand All @@ -42,6 +45,7 @@
const playing = useSelector((state) => state.viewerReducer.playing);
const error = useSelector((state) => state.viewerReducer.error);
const audioRemoteTrackSource = useSelector((state) => state.viewerReducer.audioRemoteTrackSource);

const dispatch = useDispatch();
const { routes, index } = navigation.getState();
const currentRoute = routes[index].name;
Expand All @@ -51,6 +55,7 @@
const sourceIdsRef = useRef([]);
const netInfo = useNetInfo();
const audioRemoteTrackSourceRef = useRef(null);

const [isReconnectionScheduled, setIsReconnectionScheduled] = useState<boolean>(false);

remoteTrackSourcesRef.current = remoteTrackSources;
Expand Down Expand Up @@ -144,6 +149,25 @@
}
};

const buildQualityOptions = (active, layers) => {
const descendingLayers = active.sort((a, b) => b.height - a.height);

const qualityOptions: SimulcastQuality[] = descendingLayers.map((active) => ({
simulcastLayer: {
bitrate: active.bitrate,
encodingId: active.id,
simulcastIdx: active.simulcastIdx,
spatialLayerId: layers.find((layer) => layer.simulcastIdx === active.simulcastIdx)?.spatialLayerId,
temporalLayerId: layers.find((layer) => layer.simulcastIdx === active.simulcastIdx)?.temporalLayerId,
maxSpatialLayerId: layers.find((layer) => layer.simulcastIdx === active.simulcastIdx)?.maxSpatialLayerId,
maxTemporalLayerId: layers.find((layer) => layer.simulcastIdx === active.simulcastIdx)?.maxTemporalLayerId,
},
streamQuality: `${active.height}p`,
}));

return [{ streamQuality: 'Auto' } as SimulcastQuality, ...qualityOptions];
};

const subscribe = async () => {
if (millicastViewRef.current?.isActive()) {
return;
Expand Down Expand Up @@ -193,6 +217,7 @@
payload: newRemoteTrackSource,
});
}

await viewer.project(sourceId, mappingForProjection);
dispatch({
type: 'viewer/addRemoteTrackSource',
Expand Down Expand Up @@ -231,14 +256,20 @@
// A new source was multiplexed over the vad tracks
break;
case 'layers':
const { medias } = data;

Check failure on line 259 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected lexical declaration in case block
const mediaId = Object.keys(medias)[0];

Check failure on line 260 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected lexical declaration in case block
const { active, layers } = (data as MediaStreamLayers).medias[mediaId] ?? {};

Check failure on line 261 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected lexical declaration in case block
const streamQualities = buildQualityOptions(active, layers);

Check failure on line 262 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected lexical declaration in case block

console.log('---> data', data);

Check warning on line 264 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected console statement

dispatch({
type: 'viewer/setActiveLayers',
payload: data.medias?.['0']?.active,
payload: { mediaId, streamQualities },
});
// Updated layer information for each simulcast/svc video track
break;
default:
console.log('Unknown event', name);

Check warning on line 272 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected console statement
}
});

Expand Down Expand Up @@ -266,7 +297,7 @@

await millicastViewRef.current.unproject(listVideoMids.push(...listAudioMids));
} catch (error) {
console.log('unproject error', error);

Check warning on line 300 in src/screens/multiview/MultiView.tsx

View workflow job for this annotation

GitHub Actions / Run-Checks

Unexpected console statement
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/screens/singleStreamView/SingleStreamView.style.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AppStyleSheet as StyleSheet } from '@dolbyio/uikit-react-native';
import { Dimensions } from 'react-native';

const { width } = Dimensions.get('window');

Check warning on line 4 in src/screens/singleStreamView/SingleStreamView.style.ts

View workflow job for this annotation

GitHub Actions / Run-Checks

'width' is assigned a value but never used

const styles = () =>
StyleSheet.create({
Expand All @@ -13,7 +13,7 @@
...StyleSheet.absoluteFill,
},
bottomMultimediaContainer: {
width,
width: '100%',
alignItems: 'stretch',
justifyContent: 'space-between',
paddingVertical: 15,
Expand Down
Loading
Loading