private void setScalingType(ScalingType scalingType) { SurfaceViewRenderer surfaceViewRenderer; synchronized (layoutSyncRoot) { if (this.scalingType == scalingType) { return; } this.scalingType = scalingType; surfaceViewRenderer = getSurfaceViewRenderer(); surfaceViewRenderer.setScalingType(scalingType); } // Both this instance ant its SurfaceViewRenderer take the value of // their scalingType properties into account upon their layouts. requestSurfaceViewRendererLayout(); }
private void updateVideoView() { remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT); remoteRenderScreen.setScalingType(scalingType); remoteRenderScreen.setMirror(false); if (iceConnected) { localRenderLayout.setPosition( LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED); localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT); } else { localRenderLayout.setPosition( LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING); localRender.setScalingType(scalingType); } localRender.setMirror(true); localRender.requestLayout(); remoteRenderScreen.requestLayout(); }
private void updateVideoView() { remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT); remoteRender.setScalingType(scalingType); remoteRender.setMirror(false); if (iceConnected) { localRenderLayout.setPosition( LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED); localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT); } else { localRenderLayout.setPosition( LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING); localRender.setScalingType(scalingType); } localRender.setMirror(true); localRender.requestLayout(); remoteRender.requestLayout(); }
private void initializeVideo(boolean videoEnabled, PercentFrameLayout localRenderLayout, PercentFrameLayout remoteRenderLayout) { if (localRenderLayout == null ||remoteRenderLayout == null) { return; } scalingType = ScalingType.SCALE_ASPECT_FILL; this.localRenderLayout = localRenderLayout; this.remoteRenderLayout = remoteRenderLayout; localRender = (SurfaceViewRenderer)localRenderLayout.getChildAt(0); remoteRender = (SurfaceViewRenderer)remoteRenderLayout.getChildAt(0); localRender.init(peerConnectionClient.getRenderContext(), null); localRender.setZOrderMediaOverlay(true); remoteRender.init(peerConnectionClient.getRenderContext(), null); updateVideoView(VideoViewState.NONE); }
/** * {@inheritDoc} */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int height = b - t; int width = r - l; if (height == 0 || width == 0) { l = t = r = b = 0; } else { int frameHeight; int frameRotation; int frameWidth; ScalingType scalingType; synchronized (layoutSyncRoot) { frameHeight = this.frameHeight; frameRotation = this.frameRotation; frameWidth = this.frameWidth; scalingType = this.scalingType; } SurfaceViewRenderer surfaceViewRenderer = getSurfaceViewRenderer(); switch (scalingType) { case SCALE_ASPECT_FILL: // Fill this ViewGroup with surfaceViewRenderer and the latter // will take care of filling itself with the video similarly to // the cover value the CSS property object-fit. r = width; l = 0; b = height; t = 0; break; case SCALE_ASPECT_FIT: default: // Lay surfaceViewRenderer out inside this ViewGroup in accord // with the contain value of the CSS property object-fit. // SurfaceViewRenderer will fill itself with the video similarly // to the cover or contain value of the CSS property object-fit // (which will not matter, eventually). if (frameHeight == 0 || frameWidth == 0) { l = t = r = b = 0; } else { float frameAspectRatio = (frameRotation % 180 == 0) ? frameWidth / (float) frameHeight : frameHeight / (float) frameWidth; Point frameDisplaySize = RendererCommon.getDisplaySize( scalingType, frameAspectRatio, width, height); l = (width - frameDisplaySize.x) / 2; t = (height - frameDisplaySize.y) / 2; r = l + frameDisplaySize.x; b = t + frameDisplaySize.y; } break; } } surfaceViewRenderer.layout(l, t, r, b); }
@Override public void onVideoScalingSwitch(ScalingType scalingType) { fullscreenRenderer.setScalingType(scalingType); }
@Override public void onVideoScalingSwitch(ScalingType scalingType) { this.scalingType = scalingType; updateVideoView(); }
private void updateVideoView(VideoViewState state) { RCLogger.i(TAG, "updateVideoView(), state: " + state); // only if both local and remote views for video have been provided do we want to go ahead // and update the video views if (this.localRenderLayout == null && this.remoteRenderLayout == null) { return; } if (state == VideoViewState.NONE) { // when call starts both local and remote video views should be hidden localRender.setVisibility(View.INVISIBLE); remoteRender.setVisibility(View.INVISIBLE); } else if (state == VideoViewState.LOCAL_VIEW_RECEIVED) { // local video became available, which also means that local user has previously requested a video call, // hence we need to show local video view localRender.setVisibility(View.VISIBLE); localRenderLayout.setPosition( LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING); localRender.setScalingType(scalingType); localRender.setMirror(true); localRender.requestLayout(); } else if (state == VideoViewState.REMOTE_VIEW_RECEIVED) { // remote video became available, which also means that remote user has requested a video call, // hence we need to show remote video view //remoteRender.setVisibility(View.VISIBLE); } else if (state == VideoViewState.ICE_CONNECTED) { if (remoteVideoReceived && localMediaType == ConnectionMediaType.AUDIO_VIDEO) { remoteRender.setVisibility(View.VISIBLE); remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT); remoteRender.setScalingType(scalingType); remoteRender.setMirror(false); if (this.callParams.containsKey(ParameterKeys.CONNECTION_VIDEO_ENABLED) && ((Boolean) this.callParams.get(ParameterKeys.CONNECTION_VIDEO_ENABLED)) && localRender.getVisibility() != View.VISIBLE) { localRender.setVisibility(View.VISIBLE); } localRenderLayout.setPosition( LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED); localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT); localRender.setMirror(true); localRender.requestLayout(); remoteRender.requestLayout(); } } }
/** * In the fashion of * https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth * and https://www.w3.org/TR/html5/rendering.html#video-object-fit, * resembles the CSS style {@code object-fit}. * * @param objectFit For details, refer to the documentation of the * {@code objectFit} property of the JavaScript counterpart of * {@code WebRTCView} i.e. {@code RTCView}. */ public void setObjectFit(String objectFit) { ScalingType scalingType = "cover".equals(objectFit) ? ScalingType.SCALE_ASPECT_FILL : ScalingType.SCALE_ASPECT_FIT; setScalingType(scalingType); }
void onVideoScalingSwitch(ScalingType scalingType);
public void onVideoScalingSwitch(ScalingType scalingType);