Fix webcam size after minimize the presentation #7570
This commit is contained in:
parent
7b59f1d309
commit
0c81eda94e
@ -425,7 +425,20 @@ export default class WebcamDraggableOverlay extends Component {
|
|||||||
hideOverlay,
|
hideOverlay,
|
||||||
disableVideo,
|
disableVideo,
|
||||||
audioModalIsOpen,
|
audioModalIsOpen,
|
||||||
|
refMediaContainer,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const { current: mediaContainer } = refMediaContainer;
|
||||||
|
|
||||||
|
let mediaContainerRect;
|
||||||
|
let mediaHeight;
|
||||||
|
if (mediaContainer) {
|
||||||
|
mediaContainerRect = mediaContainer.getBoundingClientRect();
|
||||||
|
const {
|
||||||
|
height,
|
||||||
|
} = mediaContainerRect;
|
||||||
|
mediaHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
dragging,
|
dragging,
|
||||||
@ -441,6 +454,14 @@ export default class WebcamDraggableOverlay extends Component {
|
|||||||
isMinWidth,
|
isMinWidth,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'%c swapLayout %s',
|
||||||
|
'background:black;color:#fff;',
|
||||||
|
swapLayout,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
const webcamBySelectorCount = WebcamDraggableOverlay.getWebcamBySelectorCount();
|
const webcamBySelectorCount = WebcamDraggableOverlay.getWebcamBySelectorCount();
|
||||||
|
|
||||||
const contentClassName = cx({
|
const contentClassName = cx({
|
||||||
@ -523,6 +544,8 @@ export default class WebcamDraggableOverlay extends Component {
|
|||||||
? (
|
? (
|
||||||
<VideoProviderContainer
|
<VideoProviderContainer
|
||||||
cursor={cursor()}
|
cursor={cursor()}
|
||||||
|
swapLayout={swapLayout}
|
||||||
|
mediaHeight={mediaHeight}
|
||||||
onMount={this.videoMounted}
|
onMount={this.videoMounted}
|
||||||
onUpdate={this.videoUpdated}
|
onUpdate={this.videoUpdated}
|
||||||
/>
|
/>
|
||||||
|
@ -190,9 +190,13 @@ class VideoProvider extends Component {
|
|||||||
&& peer.peerConnection.getRemoteStreams().length > 0;
|
&& peer.peerConnection.getRemoteStreams().length > 0;
|
||||||
|
|
||||||
if (hasLocalStream) {
|
if (hasLocalStream) {
|
||||||
this.customGetStats(peer.peerConnection, peer.peerConnection.getLocalStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)), true);
|
this.customGetStats(peer.peerConnection,
|
||||||
|
peer.peerConnection.getLocalStreams()[0].getVideoTracks()[0],
|
||||||
|
(stats => updateWebcamStats(id, stats)), true);
|
||||||
} else if (hasRemoteStream) {
|
} else if (hasRemoteStream) {
|
||||||
this.customGetStats(peer.peerConnection, peer.peerConnection.getRemoteStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)), true);
|
this.customGetStats(peer.peerConnection,
|
||||||
|
peer.peerConnection.getRemoteStreams()[0].getVideoTracks()[0],
|
||||||
|
(stats => updateWebcamStats(id, stats)), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
@ -833,9 +837,9 @@ class VideoProvider extends Component {
|
|||||||
|
|
||||||
let videoBitrate;
|
let videoBitrate;
|
||||||
if (videoStats.packetsReceived > 0) { // Remote video
|
if (videoStats.packetsReceived > 0) { // Remote video
|
||||||
videoLostPercentage = ((videoStats
|
videoLostPercentage = ((videoStats.packetsLost / (
|
||||||
.packetsLost / ((videoStats
|
(videoStats.packetsLost + videoStats.packetsReceived) * 100
|
||||||
.packetsLost + videoStats.packetsReceived) * 100)) || 0).toFixed(1);
|
)) || 0).toFixed(1);
|
||||||
videoBitrate = Math.floor(videoKbitsReceivedPerSecond || 0);
|
videoBitrate = Math.floor(videoKbitsReceivedPerSecond || 0);
|
||||||
videoLostRecentPercentage = ((videoIntervalPacketsLost / ((videoIntervalPacketsLost
|
videoLostRecentPercentage = ((videoIntervalPacketsLost / ((videoIntervalPacketsLost
|
||||||
+ videoIntervalPacketsReceived) * 100)) || 0).toFixed(1);
|
+ videoIntervalPacketsReceived) * 100)) || 0).toFixed(1);
|
||||||
@ -1005,10 +1009,18 @@ class VideoProvider extends Component {
|
|||||||
const { socketOpen } = this.state;
|
const { socketOpen } = this.state;
|
||||||
if (!socketOpen) return null;
|
if (!socketOpen) return null;
|
||||||
|
|
||||||
const { users, enableVideoStats, cursor } = this.props;
|
const {
|
||||||
|
users,
|
||||||
|
enableVideoStats,
|
||||||
|
cursor,
|
||||||
|
swapLayout,
|
||||||
|
mediaHeight,
|
||||||
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<VideoList
|
<VideoList
|
||||||
cursor={cursor}
|
cursor={cursor}
|
||||||
|
swapLayout={swapLayout}
|
||||||
|
mediaHeight={mediaHeight}
|
||||||
users={users}
|
users={users}
|
||||||
onMount={this.createVideoTag}
|
onMount={this.createVideoTag}
|
||||||
getStats={this.getStats}
|
getStats={this.getStats}
|
||||||
|
@ -11,6 +11,8 @@ const VideoProviderContainer = ({ children, ...props }) => {
|
|||||||
|
|
||||||
export default withTracker(props => ({
|
export default withTracker(props => ({
|
||||||
cursor: props.cursor,
|
cursor: props.cursor,
|
||||||
|
swapLayout: props.swapLayout,
|
||||||
|
mediaHeight: props.mediaHeight,
|
||||||
meetingId: VideoService.meetingId(),
|
meetingId: VideoService.meetingId(),
|
||||||
users: VideoService.getAllUsersVideo(),
|
users: VideoService.getAllUsersVideo(),
|
||||||
userId: VideoService.userId(),
|
userId: VideoService.userId(),
|
||||||
|
@ -52,7 +52,15 @@ class VideoList extends Component {
|
|||||||
|
|
||||||
renderVideoList() {
|
renderVideoList() {
|
||||||
const {
|
const {
|
||||||
intl, users, onMount, getStats, stopGettingStats, enableVideoStats, cursor,
|
intl,
|
||||||
|
users,
|
||||||
|
onMount,
|
||||||
|
getStats,
|
||||||
|
stopGettingStats,
|
||||||
|
enableVideoStats,
|
||||||
|
cursor,
|
||||||
|
swapLayout,
|
||||||
|
mediaHeight,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { focusedId } = this.state;
|
const { focusedId } = this.state;
|
||||||
|
|
||||||
@ -73,7 +81,8 @@ class VideoList extends Component {
|
|||||||
<div
|
<div
|
||||||
key={user.id}
|
key={user.id}
|
||||||
className={cx({
|
className={cx({
|
||||||
[styles.videoListItem]: true,
|
[styles.videoListItem]: !swapLayout,
|
||||||
|
[styles.videoListItemSwapLayout]: swapLayout,
|
||||||
[styles.focused]: focusedId === user.id && users.length > 2,
|
[styles.focused]: focusedId === user.id && users.length > 2,
|
||||||
})}
|
})}
|
||||||
style={{
|
style={{
|
||||||
@ -88,6 +97,8 @@ class VideoList extends Component {
|
|||||||
getStats={(videoRef, callback) => getStats(user.id, videoRef, callback)}
|
getStats={(videoRef, callback) => getStats(user.id, videoRef, callback)}
|
||||||
stopGettingStats={() => stopGettingStats(user.id)}
|
stopGettingStats={() => stopGettingStats(user.id)}
|
||||||
enableVideoStats={enableVideoStats}
|
enableVideoStats={enableVideoStats}
|
||||||
|
swapLayout={swapLayout}
|
||||||
|
mediaHeight={mediaHeight}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -100,6 +111,8 @@ class VideoList extends Component {
|
|||||||
<div
|
<div
|
||||||
ref={(ref) => { this.canvas = ref; }}
|
ref={(ref) => { this.canvas = ref; }}
|
||||||
className={styles.videoCanvas}
|
className={styles.videoCanvas}
|
||||||
|
|
||||||
|
// TODO adicionar videoCanvasSwapLayout quando for swaplayout
|
||||||
>
|
>
|
||||||
{!users.length ? null : (
|
{!users.length ? null : (
|
||||||
<div
|
<div
|
||||||
|
@ -11,13 +11,29 @@
|
|||||||
--audio-indicator-fs: 75%;
|
--audio-indicator-fs: 75%;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||||
|
height: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.videoCanvasSwapLayout {
|
||||||
|
--cam-dropdown-width: 70%;
|
||||||
|
--audio-indicator-width: 1.12rem;
|
||||||
|
--audio-indicator-fs: 75%;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.videoList {
|
.videoList {
|
||||||
@ -41,6 +57,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.videoListSwapLayout {
|
||||||
|
display: grid;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(var(--video-width), 1fr));
|
||||||
|
grid-auto-columns: minmax(var(--video-width), 1fr);
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
grid-gap: 5px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
grid-auto-flow: column dense;
|
||||||
|
|
||||||
|
@include mq($medium-up) {
|
||||||
|
grid-gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.videoListItem {
|
.videoListItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: fit-content;
|
max-width: fit-content;
|
||||||
@ -62,6 +96,25 @@
|
|||||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.videoListItemSwapLayout {
|
||||||
|
display: flex;
|
||||||
|
max-width: -moz-fit-content;
|
||||||
|
max-height: -moz-fit-content;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&.focused {
|
||||||
|
grid-column: 1 / span 2;
|
||||||
|
grid-row: 1 / span 2;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
@ -107,6 +160,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contentSwapLayout {
|
||||||
|
position: relative;
|
||||||
|
min-width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
background-color: var(--color-gray);
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
border: 5px solid var(--color-white-with-transparency);
|
||||||
|
border-radius: 5px;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
:global(.animationsEnabled) & {
|
||||||
|
transition: opacity .1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.talking::after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.focused & {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.contentLoading {
|
.contentLoading {
|
||||||
width: var(--video-width);
|
width: var(--video-width);
|
||||||
min-width: var(--video-width);
|
min-width: var(--video-width);
|
||||||
@ -114,8 +209,12 @@
|
|||||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||||
}
|
}
|
||||||
|
|
||||||
%media-area {
|
.contentLoadingSwapLayout {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
%media-area {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -129,7 +129,9 @@ class VideoListItem extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { showStats, stats, videoIsReady } = this.state;
|
const { showStats, stats, videoIsReady } = this.state;
|
||||||
const { user, numOfUsers } = this.props;
|
const {
|
||||||
|
user, numOfUsers, swapLayout, mediaHeight,
|
||||||
|
} = this.props;
|
||||||
const availableActions = this.getAvailableActions();
|
const availableActions = this.getAvailableActions();
|
||||||
const enableVideoMenu = Meteor.settings.public.kurento.enableVideoMenu || false;
|
const enableVideoMenu = Meteor.settings.public.kurento.enableVideoMenu || false;
|
||||||
|
|
||||||
@ -138,13 +140,18 @@ class VideoListItem extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx({
|
<div className={cx({
|
||||||
[styles.content]: true,
|
[styles.content]: !swapLayout,
|
||||||
|
[styles.contentSwapLayout]: swapLayout,
|
||||||
[styles.talking]: user.isTalking,
|
[styles.talking]: user.isTalking,
|
||||||
[styles.contentLoading]: !videoIsReady,
|
[styles.contentLoading]: !videoIsReady && !swapLayout,
|
||||||
|
[styles.contentLoadingSwapLayout]: !videoIsReady && swapLayout,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{!videoIsReady && <div className={styles.connecting} />}
|
{!videoIsReady && <div className={styles.connecting} />}
|
||||||
<video
|
<video
|
||||||
|
style={{
|
||||||
|
maxHeight: mediaHeight,
|
||||||
|
}}
|
||||||
muted
|
muted
|
||||||
className={cx({
|
className={cx({
|
||||||
[styles.media]: true,
|
[styles.media]: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user