hark running now on producers and consumers directly instead on PeerView component, now we can send audiolevel events into more places ...
parent
977ffd9d24
commit
3ab603bbe7
|
|
@ -1,6 +1,7 @@
|
|||
import protooClient from 'protoo-client';
|
||||
import * as mediasoupClient from 'mediasoup-client';
|
||||
import Logger from './Logger';
|
||||
import hark from 'hark';
|
||||
import ScreenShare from './ScreenShare';
|
||||
import { getProtooUrl } from './urlFactory';
|
||||
import * as cookiesManager from './cookiesManager';
|
||||
|
|
@ -1380,7 +1381,33 @@ export default class RoomClient
|
|||
})
|
||||
.then(() =>
|
||||
{
|
||||
const stream = new MediaStream;
|
||||
|
||||
logger.debug('_setMicProducer() succeeded');
|
||||
stream.addTrack(producer.track);
|
||||
if (!stream.getAudioTracks()[0])
|
||||
throw new Error('_setMicProducer(): given stream has no audio track');
|
||||
producer.hark = hark(stream, { play: false });
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
producer.hark.on('volume_change', (dBs, threshold) =>
|
||||
{
|
||||
// The exact formula to convert from dBs (-100..0) to linear (0..1) is:
|
||||
// Math.pow(10, dBs / 20)
|
||||
// However it does not produce a visually useful output, so let exagerate
|
||||
// it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
|
||||
// minimize component renderings.
|
||||
let volume = Math.round(Math.pow(10, dBs / 85) * 10);
|
||||
|
||||
if (volume === 1)
|
||||
volume = 0;
|
||||
|
||||
if (volume !== producer.volume)
|
||||
{
|
||||
producer.volume = volume;
|
||||
this._dispatch(stateActions.setProducerVolume(producer.id, volume));
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
|
|
@ -1823,7 +1850,8 @@ export default class RoomClient
|
|||
track : null,
|
||||
codec : codec ? codec.name : null
|
||||
},
|
||||
consumer.peer.name));
|
||||
consumer.peer.name)
|
||||
);
|
||||
|
||||
consumer.on('close', (originator) =>
|
||||
{
|
||||
|
|
@ -1835,6 +1863,43 @@ export default class RoomClient
|
|||
consumer.id, consumer.peer.name));
|
||||
});
|
||||
|
||||
consumer.on('handled', (originator) =>
|
||||
{
|
||||
logger.debug(
|
||||
'consumer "handled" event [id:%s, originator:%s, consumer:%o]',
|
||||
consumer.id, originator, consumer);
|
||||
if (consumer.kind === 'audio')
|
||||
{
|
||||
const stream = new MediaStream;
|
||||
|
||||
stream.addTrack(consumer.track);
|
||||
if (!stream.getAudioTracks()[0])
|
||||
throw new Error('consumer.on("handled" | given stream has no audio track');
|
||||
|
||||
consumer.hark = hark(stream, { play: false });
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
consumer.hark.on('volume_change', (dBs, threshold) =>
|
||||
{
|
||||
// The exact formula to convert from dBs (-100..0) to linear (0..1) is:
|
||||
// Math.pow(10, dBs / 20)
|
||||
// However it does not produce a visually useful output, so let exagerate
|
||||
// it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
|
||||
// minimize component renderings.
|
||||
let volume = Math.round(Math.pow(10, dBs / 85) * 10);
|
||||
|
||||
if (volume === 1)
|
||||
volume = 0;
|
||||
|
||||
if (volume !== consumer.volume)
|
||||
{
|
||||
consumer.volume = volume;
|
||||
this._dispatch(stateActions.setConsumerVolume(consumer.id, volume));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
consumer.on('pause', (originator) =>
|
||||
{
|
||||
logger.debug(
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ class Me extends React.Component
|
|||
advancedMode={advancedMode}
|
||||
peer={me}
|
||||
audioTrack={micProducer ? micProducer.track : null}
|
||||
volume={micProducer ? micProducer.volume : null}
|
||||
videoTrack={webcamProducer ? webcamProducer.track : null}
|
||||
videoVisible={videoVisible}
|
||||
audioCodec={micProducer ? micProducer.codec : null}
|
||||
|
|
|
|||
|
|
@ -8,27 +8,27 @@ import * as stateActions from '../redux/stateActions';
|
|||
import PeerView from './PeerView';
|
||||
import ScreenView from './ScreenView';
|
||||
|
||||
class Peer extends Component
|
||||
class Peer extends Component
|
||||
{
|
||||
state = {
|
||||
controlsVisible : false
|
||||
};
|
||||
|
||||
handleMouseOver = () =>
|
||||
handleMouseOver = () =>
|
||||
{
|
||||
this.setState({
|
||||
controlsVisible : true
|
||||
});
|
||||
};
|
||||
|
||||
handleMouseOut = () =>
|
||||
handleMouseOut = () =>
|
||||
{
|
||||
this.setState({
|
||||
controlsVisible : false
|
||||
});
|
||||
};
|
||||
|
||||
render()
|
||||
render()
|
||||
{
|
||||
const {
|
||||
advancedMode,
|
||||
|
|
@ -45,35 +45,35 @@ class Peer extends Component
|
|||
toggleConsumerFullscreen,
|
||||
style
|
||||
} = this.props;
|
||||
|
||||
|
||||
const micEnabled = (
|
||||
Boolean(micConsumer) &&
|
||||
!micConsumer.locallyPaused &&
|
||||
!micConsumer.remotelyPaused
|
||||
);
|
||||
|
||||
|
||||
const videoVisible = (
|
||||
Boolean(webcamConsumer) &&
|
||||
!webcamConsumer.locallyPaused &&
|
||||
!webcamConsumer.remotelyPaused
|
||||
);
|
||||
|
||||
|
||||
const screenVisible = (
|
||||
Boolean(screenConsumer) &&
|
||||
!screenConsumer.locallyPaused &&
|
||||
!screenConsumer.remotelyPaused
|
||||
);
|
||||
|
||||
|
||||
let videoProfile;
|
||||
|
||||
|
||||
if (webcamConsumer)
|
||||
videoProfile = webcamConsumer.profile;
|
||||
|
||||
|
||||
let screenProfile;
|
||||
|
||||
|
||||
if (screenConsumer)
|
||||
screenProfile = screenConsumer.profile;
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
data-component='Peer'
|
||||
|
|
@ -89,7 +89,7 @@ class Peer extends Component
|
|||
</div>
|
||||
:null
|
||||
}
|
||||
|
||||
|
||||
<div className={classnames('view-container', 'webcam')} style={style}>
|
||||
<div
|
||||
className={classnames('controls', {
|
||||
|
|
@ -108,7 +108,7 @@ class Peer extends Component
|
|||
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
<div
|
||||
className={classnames('button', 'webcam', {
|
||||
on : videoVisible,
|
||||
|
|
@ -122,7 +122,7 @@ class Peer extends Component
|
|||
onDisableWebcam(peer.name) : onEnableWebcam(peer.name);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
<div
|
||||
className={classnames('button', 'fullscreen')}
|
||||
onClick={(e) =>
|
||||
|
|
@ -136,6 +136,7 @@ class Peer extends Component
|
|||
advancedMode={advancedMode}
|
||||
peer={peer}
|
||||
audioTrack={micConsumer ? micConsumer.track : null}
|
||||
volume={micConsumer ? micConsumer.volume : null}
|
||||
videoTrack={webcamConsumer ? webcamConsumer.track : null}
|
||||
videoVisible={videoVisible}
|
||||
videoProfile={videoProfile}
|
||||
|
|
@ -143,7 +144,7 @@ class Peer extends Component
|
|||
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
{screenConsumer ?
|
||||
<div className={classnames('view-container', 'screen')} style={style}>
|
||||
<div className='controls'>
|
||||
|
|
@ -160,7 +161,7 @@ class Peer extends Component
|
|||
onDisableScreen(peer.name) : onEnableScreen(peer.name);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
<div
|
||||
className={classnames('button', 'fullscreen')}
|
||||
onClick={(e) =>
|
||||
|
|
@ -236,7 +237,7 @@ const mapDispatchToProps = (dispatch) =>
|
|||
},
|
||||
onEnableWebcam : (peerName) =>
|
||||
{
|
||||
|
||||
|
||||
dispatch(requestActions.resumePeerVideo(peerName));
|
||||
},
|
||||
onDisableWebcam : (peerName) =>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import Spinner from 'react-spinner';
|
||||
import hark from 'hark';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import EditableInput from './EditableInput';
|
||||
|
||||
|
|
@ -27,10 +26,6 @@ export default class PeerView extends React.Component
|
|||
// @type {MediaStreamTrack}
|
||||
this._videoTrack = null;
|
||||
|
||||
// Hark instance.
|
||||
// @type {Object}
|
||||
this._hark = null;
|
||||
|
||||
// Periodic timer for showing video resolution.
|
||||
this._videoResolutionTimer = null;
|
||||
}
|
||||
|
|
@ -40,6 +35,7 @@ export default class PeerView extends React.Component
|
|||
const {
|
||||
isMe,
|
||||
peer,
|
||||
volume,
|
||||
advancedMode,
|
||||
videoVisible,
|
||||
videoProfile,
|
||||
|
|
@ -49,7 +45,6 @@ export default class PeerView extends React.Component
|
|||
} = this.props;
|
||||
|
||||
const {
|
||||
volume,
|
||||
videoWidth,
|
||||
videoHeight
|
||||
} = this.state;
|
||||
|
|
@ -149,9 +144,6 @@ export default class PeerView extends React.Component
|
|||
|
||||
componentWillUnmount()
|
||||
{
|
||||
if (this._hark)
|
||||
this._hark.stop();
|
||||
|
||||
clearInterval(this._videoResolutionTimer);
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +152,7 @@ export default class PeerView extends React.Component
|
|||
const { audioTrack, videoTrack } = nextProps;
|
||||
|
||||
this._setTracks(audioTrack, videoTrack);
|
||||
|
||||
}
|
||||
|
||||
_setTracks(audioTrack, videoTrack)
|
||||
|
|
@ -170,9 +163,6 @@ export default class PeerView extends React.Component
|
|||
this._audioTrack = audioTrack;
|
||||
this._videoTrack = videoTrack;
|
||||
|
||||
if (this._hark)
|
||||
this._hark.stop();
|
||||
|
||||
clearInterval(this._videoResolutionTimer);
|
||||
this._hideVideoResolution();
|
||||
|
||||
|
|
@ -190,9 +180,6 @@ export default class PeerView extends React.Component
|
|||
|
||||
video.srcObject = stream;
|
||||
|
||||
if (audioTrack)
|
||||
this._runHark(stream);
|
||||
|
||||
if (videoTrack)
|
||||
this._showVideoResolution();
|
||||
}
|
||||
|
|
@ -202,31 +189,6 @@ export default class PeerView extends React.Component
|
|||
}
|
||||
}
|
||||
|
||||
_runHark(stream)
|
||||
{
|
||||
if (!stream.getAudioTracks()[0])
|
||||
throw new Error('_runHark() | given stream has no audio track');
|
||||
|
||||
this._hark = hark(stream, { play: false });
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
this._hark.on('volume_change', (dBs, threshold) =>
|
||||
{
|
||||
// The exact formula to convert from dBs (-100..0) to linear (0..1) is:
|
||||
// Math.pow(10, dBs / 20)
|
||||
// However it does not produce a visually useful output, so let exagerate
|
||||
// it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
|
||||
// minimize component renderings.
|
||||
let volume = Math.round(Math.pow(10, dBs / 85) * 10);
|
||||
|
||||
if (volume === 1)
|
||||
volume = 0;
|
||||
|
||||
if (volume !== this.state.volume)
|
||||
this.setState({ volume: volume });
|
||||
});
|
||||
}
|
||||
|
||||
_showVideoResolution()
|
||||
{
|
||||
this._videoResolutionTimer = setInterval(() =>
|
||||
|
|
@ -259,6 +221,7 @@ PeerView.propTypes =
|
|||
[ appPropTypes.Me, appPropTypes.Peer ]).isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
audioTrack : PropTypes.any,
|
||||
volume : PropTypes.number,
|
||||
videoTrack : PropTypes.any,
|
||||
videoVisible : PropTypes.bool.isRequired,
|
||||
videoProfile : PropTypes.string,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,15 @@ const consumers = (state = initialState, action) =>
|
|||
return { ...state, [consumerId]: newConsumer };
|
||||
}
|
||||
|
||||
case 'SET_CONSUMER_VOLUME':
|
||||
{
|
||||
const { consumerId, volume } = action.payload;
|
||||
const consumer = state[consumerId];
|
||||
const newConsumer = { ...consumer, volume };
|
||||
|
||||
return { ...state, [consumerId]: newConsumer };
|
||||
}
|
||||
|
||||
case 'SET_CONSUMER_RESUMED':
|
||||
{
|
||||
const { consumerId, originator } = action.payload;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,15 @@ const producers = (state = initialState, action) =>
|
|||
return { ...state, [producerId]: newProducer };
|
||||
}
|
||||
|
||||
case 'SET_PRODUCER_VOLUME':
|
||||
{
|
||||
const { producerId, volume } = action.payload;
|
||||
const producer = state[producerId];
|
||||
const newProducer = { ...producer, volume };
|
||||
|
||||
return { ...state, [producerId]: newProducer };
|
||||
}
|
||||
|
||||
case 'SET_PRODUCER_RESUMED':
|
||||
{
|
||||
const { producerId, originator } = action.payload;
|
||||
|
|
|
|||
|
|
@ -331,6 +331,22 @@ export const setConsumerTrack = (consumerId, track) =>
|
|||
};
|
||||
};
|
||||
|
||||
export const setConsumerVolume = (consumerId, volume) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_CONSUMER_VOLUME',
|
||||
payload : { consumerId, volume }
|
||||
};
|
||||
};
|
||||
|
||||
export const setProducerVolume = (producerId, volume) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_PRODUCER_VOLUME',
|
||||
payload : { producerId, volume }
|
||||
};
|
||||
};
|
||||
|
||||
export const addNotification = (notification) =>
|
||||
{
|
||||
return {
|
||||
|
|
|
|||
Loading…
Reference in New Issue