Change video orientation on react-web and android sdk

I have deployed the zoom video sdk samples on both android and react-web apps.

The video preview on the react-web app is showing in portrait. But the remote side video on the android (Which is sent from react-web version) is showing in landscape.

I would like to see the video in full screen on android device.

How To Reproduce
Steps to reproduce the behavior including:
*1. Use the zoom video sdk sample apps on android and react-web app on 2 different phones and be in the same session.
*2. Observe the self video on the react-web version, it is in portait. But the remote side video on the android version is in landscape.

Expected Result:
The remote side video on the android app side must be in portrait and in full screen.

1 Like

Hi Balaji, you can change how the video is rendered on Android modifying the aspect parameter passed to your VideoView. I understand you’d like to crop the landscape video coming from Web to portrait layout on Android. You can use the ZoomVideoSDKVideoAspect_PanAndScan aspect to crop the video to fit your layout.

Here’s a Kotlin snippet:

val videoView: ZoomVideoSDKVideoView = findViewById(R.id.video_view)
canvas.subscribe(videoView, ZoomVideoSDKVideoAspect.ZoomVideoSDKVideoAspect_PanAndScan)

Let me know if that answers your question. :slight_smile:

First of all, thanks for the response and wish you a happy new year.

I tried the solution you mentioned. and it is showing a much more zoomed version of the video on android side compared to the preview shown on the react version. Attaching the screenshots.

The above one is from react-web version. Please check the preview version of it.

The below one is from Android where the remote side view is zoomed significantly around 5x.


Happy new year!

There’s a couple ways to render the video, ZoomVideoSDKVideoAspect_PanAndScan crops the video to fit the view, if you’d like to render the video in the portrait view but not zoom in you’ll encounter black borders in your view (letterboxing). To achieve that you can use the ZoomVideoSDKVideoAspect_LetterBox aspect parameter. Alternatively, you can stretch the video to fill the view.

Here’s a quick reference:

Type Description
ZoomVideoSDKVideoAspect_Original Display video without any modifications.
ZoomVideoSDKVideoAspect_Full_Filled Stretches video to fill the canvas.
ZoomVideoSDKVideoAspect_LetterBox For video with a 16:9 aspect ratio shown on a 4:3 screen, black bars will be added to the top & bottom to fit the canvas For video with a 4:3 aspect ratio shown on a 16:9 screen, black bars will be added to the left and right to fit the canvas.
ZoomVideoSDKVideoAspect_PanAndScan For video with a 16:9 aspect ratio shown on a 4:3 screen, the left & right will be cropped to fit the canvas For video with a 4:3 aspect ratio shown on a 16:9 screen, the top & bottom will be cropped to fit the canvas.

You can read more in the docs.

Thanks for your reply… when i used the LetterBox resolution, Here is what i am seeing. There is significant amount of cropping done for the view on android when compared to what the user is able to see in the preview of react-web session.
I am assuming the preview side of the caller must be the exact area shown in the remote side. It is working from android to react-web version perfectly. what i see in the preview on android side is exactly shown on the remote side of react-web. But not vice versa.


If I stretch the video, the aspect ratio will break I believe… Please correct me if I am wrong…
I believe the video captured on the react-web itself is in landscape resolution. Hence it is coming as the landscape video and when it is centre cropped, it is zoomed a lot to fit in full screen…
Can I change the size of the video on the capturing side itself.? on react-web version?

Hi @ekaansh.zoom. Gentle reminder on the queries i added.

In Video SDK Web the video will be cropped into a 16/9 ratio by default, if you want to use the original ratio, pass the originalRatio when invoking the startVideo method. You can also pass in custom values for captureWidth and captureHeight to set it to a specific resolution.

If i pass ‘originalRatio’ as the parameter, i am seeing the landscape video on android view. Even though if the size of the video depends on the device orientation on react-web side, the device is in portrait orientation only and also the preview on react is being shown in portrait orientation. it is weird to see the same as the landscape video on android side.

@ekaansh.zoom Hello, You mentioned that " In Video SDK Web the video will be cropped into a 16/9 ratio by default" … Can i change it to 9/16? i think that will solve my problem. please confirm where can i change it.

You can also pass in custom values for captureWidth and captureHeight to set it to a specific resolution.

Like I mentioned you can call startVideo with capture parameters with custom values, for example to capture vertical 480p video:

await mediaStream.startVideo({ captureHeight: 640, captureWidth: 480 });

Hey @balajisunku

When using the stream.startVideo() method, you can pass the originalRatio option to capture the original aspect ratio.

On the receiving side, if the rendered aspect ratio is different from the original ratio, you will receive a video-aspect-ratio-change event. This event provides the original capture ratio from the sender, allowing you to adjust the rendering style accordingly.

Thanks
Vic

2 Likes

Hi @vic.yang … thank you so much for your response.

I am changing my code from

await mediaStream?.startVideo({ videoElement });
const startVideoOptions = { hd: true, ptz: mediaStream?.isBrowserSupportPTZ() };

To

await mediaStream?.startVideo({ videoElement, captureWidth: 360, captureHeight: 640 });
const startVideoOptions = { hd: true, ptz: mediaStream?.isBrowserSupportPTZ(), captureWidth: 360, captureHeight: 640 };

Where i reversed the resolution from 640x360 which is default to 360x640…

Still i am seeing the remote side video in landscape mode as shown in the above screenshots.

Since i am hardcoding these to single values, I believe i need not to handle the change in resolution event… am i correct?

Hey @balajisunku

Have you tried the originalRatio option when calling the stream.startVideo method? And have you listened to the video-aspect-ratio-change event on the rendering side?

Thanks
Vic

@vic.yang I had tried listening to the event you mentioned. But couldn’t figureout how to do that.
If possible, can you please give me the sender side changes in react-web and receiver side code in android?
Thanks in advance. it will be a great addon to my product if I can achieve this :slight_smile:

@ekaansh.zoom @vic.yang I am getting emails from other developers also who are waiting for the same resolution. The help from you resolves the problem for many products :slight_smile: Please help

2 Likes

Hey @balajisunku

We will soon update this usage method on the sample app on GitHub.

Thanks
Vic

@vic.yang that would be a great add-on to the sample app. But meanwhile, can you please guide me to fix it in my product? I am about to release my product to the production and this has become a blocker for me. I would be happy to connect on a call to discuss as well. Please feel free to mail me on balaji.march31@gmail.com for a faster communication

Hey @balajisunku

Sorry for late reply.

Here is a simple example I wrote based on your scenario:

/**
 * On Android browser, sending the video
 */

// Start video. Starting from 1.10.5, you no longer need to worry about whether to pass the videoElement
await stream.startVideo({ originalRatio: true });

// Render self view
const targetElement = stream.isRenderSelfViewWithVideoElement()
  ? document.querySelector("#self-video")
  : document.querySelector("#self-canvas");
await stream.renderVideo(
  targetElement,
  currentUserId,
  width,
  height,
  x,
  y,
  videoQuality
);

/**
 * On Desktop browser, receiving the video
 */

client.on("peer-video-state-change", (payload) => {
  const { action, userId } = payload;
  if (action === "Start") {
    await stream.renderVideo(
      document.querySelector("#participants-canvas"),
      userId,
      width,
      height,
      x,
      y,
      videoQuality
    );
  } else if (action === "Stop") {
    await stream.stopRenderVideo(
      document.querySelector("#participants-canvas"),
      userId
    );
  }
});
/**
 * Listen to the aspect ratio change event
 */
client.on("video-aspect-ratio-change", (payload) => {
  const { userId, aspectRatio } = payload;
  const height = width / aspectRatio;
  // resize the video
  await stream.adjustRenderedVideoPosition(
    document.querySelector("#participants-canvas"),
    userId,
    width,
    height,
    x,
    y
  );
});

Thanks
Vic