-
Notifications
You must be signed in to change notification settings - Fork 159
/
Copy pathOTSubscriber.js
137 lines (133 loc) · 5.85 KB
/
OTSubscriber.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import React, { Component } from 'react';
import { View, Platform } from 'react-native';
import PropTypes from 'prop-types';
import { isNull, isUndefined, each, isEqual, isEmpty } from 'underscore';
import { OT, nativeEvents, setNativeEvents, removeNativeEvents } from './OT';
import OTSubscriberView from './views/OTSubscriberView';
import { sanitizeSubscriberEvents, sanitizeProperties, sanitizeFrameRate, sanitizeResolution, sanitizeScaleBehavior } from './helpers/OTSubscriberHelper';
import { getOtrnErrorEventHandler, sanitizeBooleanProperty } from './helpers/OTHelper';
import OTContext from './contexts/OTContext';
export default class OTSubscriber extends Component {
constructor(props, context) {
super(props, context);
this.state = {
streams: [],
subscribeToSelf: props.subscribeToSelf || false
};
this.componentEvents = {
streamDestroyed: Platform.OS === 'android' ? 'session:onStreamDropped' : 'session:streamDestroyed',
streamCreated: Platform.OS === 'android' ? 'session:onStreamReceived' : 'session:streamCreated',
};
this.componentEventsArray = Object.values(this.componentEvents);
this.otrnEventHandler = getOtrnErrorEventHandler(this.props.eventHandlers);
this.initComponent();
}
initComponent = () => {
const { eventHandlers } = this.props;
const { sessionId } = this.context;
if (sessionId) {
this.streamCreated = nativeEvents.addListener(`${sessionId}:${this.componentEvents.streamCreated}`,
stream => this.streamCreatedHandler(stream));
this.streamDestroyed = nativeEvents.addListener(`${sessionId}:${this.componentEvents.streamDestroyed}`,
stream => this.streamDestroyedHandler(stream));
const subscriberEvents = sanitizeSubscriberEvents(eventHandlers);
OT.setJSComponentEvents(this.componentEventsArray);
setNativeEvents(subscriberEvents);
}
}
componentDidUpdate() {
const { streamProperties } = this.props;
if (!isEqual(this.state.streamProperties, streamProperties)) {
each(streamProperties, (individualStreamProperties, streamId) => {
const { scaleBehavior, subscribeToAudio, subscribeToVideo, preferredResolution, preferredFrameRate } = individualStreamProperties;
if (scaleBehavior !== undefined) {
OT.setSubscriberScaleBehavior(streamId, sanitizeScaleBehavior(scaleBehavior));
}
if (subscribeToAudio !== undefined) {
OT.subscribeToAudio(streamId, sanitizeBooleanProperty(subscribeToAudio));
}
if (subscribeToVideo !== undefined) {
OT.subscribeToVideo(streamId, sanitizeBooleanProperty(subscribeToVideo));
}
if (preferredResolution !== undefined) {
OT.setPreferredResolution(streamId, sanitizeResolution(preferredResolution));
}
if (preferredFrameRate !== undefined) {
OT.setPreferredFrameRate(streamId, sanitizeFrameRate(preferredFrameRate));
}
});
this.setState({ streamProperties });
}
}
componentWillUnmount() {
this.streamCreated.remove();
this.streamDestroyed.remove();
OT.removeJSComponentEvents(this.componentEventsArray);
const events = sanitizeSubscriberEvents(this.props.eventHandlers);
removeNativeEvents(events);
}
streamCreatedHandler = (stream) => {
const { subscribeToSelf } = this.state;
const { streamProperties, properties } = this.props;
const { sessionId, sessionInfo } = this.context;
const subscriberProperties = isNull(streamProperties[stream.streamId]) ?
sanitizeProperties(properties) : sanitizeProperties(streamProperties[stream.streamId]);
// Subscribe to streams. If subscribeToSelf is true, subscribe also to his own stream
const sessionInfoConnectionId = sessionInfo && sessionInfo.connection ? sessionInfo.connection.connectionId : null;
if (subscribeToSelf || (sessionInfoConnectionId !== stream.connectionId)) {
OT.subscribeToStream(stream.streamId, sessionId, subscriberProperties, (error) => {
if (error) {
this.otrnEventHandler(error);
} else {
this.setState({
streams: [...this.state.streams, stream.streamId],
});
}
});
}
}
streamDestroyedHandler = (stream) => {
OT.removeSubscriber(stream.streamId, (error) => {
if (error) {
this.otrnEventHandler(error);
} else {
const indexOfStream = this.state.streams.indexOf(stream.streamId);
const newState = this.state.streams.slice();
newState.splice(indexOfStream, 1);
this.setState({
streams: newState,
});
}
});
}
render() {
if (!this.props.children) {
const containerStyle = this.props.containerStyle;
const childrenWithStreams = this.state.streams.map((streamId) => {
const streamProperties = this.props.streamProperties[streamId];
const style = isEmpty(streamProperties) ? this.props.style : (isUndefined(streamProperties.style) || isNull(streamProperties.style)) ? this.props.style : streamProperties.style;
return <OTSubscriberView key={streamId} streamId={streamId} style={style} />
});
return <View style={containerStyle}>{childrenWithStreams}</View>;
}
return this.props.children(this.state.streams) || null;
}
}
const viewPropTypes = View.propTypes;
OTSubscriber.propTypes = {
...viewPropTypes,
children: PropTypes.func,
properties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
eventHandlers: PropTypes.object, // eslint-disable-line react/forbid-prop-types
streamProperties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
containerStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types
subscribeToSelf: PropTypes.bool
};
OTSubscriber.defaultProps = {
properties: {},
eventHandlers: {},
streamProperties: {},
containerStyle: {},
subscribeToSelf: false
};
OTSubscriber.contextType = OTContext;