dkrivoruchko / ScreenStream

ScreenStream Android App
https://screenstream.io
MIT License
1.56k stars 319 forks source link

Web-browser is not not automatically upscaling the MJPEG stream to the full width/height of the web-browser's viewport #218

Open wqp53625 opened 1 year ago

wqp53625 commented 1 year ago

Hi @dkrivoruchko ,

Thanks a lot for this useful app.

There is an issue when displaying the MJPEG stream on monitors/TVs that have a higher resolution than the MJPEG stream.

When casting the screen of a 1080p device to a 720p monitor/TV for example, the web-browser on that 720p monitor/TV automatically downscales (resizes) the MJPEG stream so that it fits inside the 720p window (viewport).

But web-browsers are not doing it the other way around.

When casting the screen of a 1080p device to a 2160p (4K) monitor/TV for example, the displayed image only is a quarter of the size of the total size of the monitor/TV. Which means web-browsers do not automatically upscale the 1080p MJPEG stream to the full width/height of the 2160p window (viewport).

The workaround would be to use the web-browser's built-in zoom control, by pressing the CTRL+PLUS keyboard shortcut or using CTRL+MOUSEWHEEL_UP, until the MJPEG stream's image fills the entire width/height of the screen.

Having to zoom in every time is rather inconvenient though. And some web-browsers might not even offer zoom controls on all operating systems.

Using ScreenStream -> Settings -> Resize Image -> 150% would not be a viable solution, since it would unnecessarily increase the stream's bandwidth. And 150% would also not be enough to upscale a 1080p image to 2160p (4K).

Instead, the resizing (upscaling) should be done inside the web-browser.

It would be much appreciated if a feature could be added to ScreenStream which would automatically make the MJPEG stream take up the entire width/height of the web-browser's viewport (while preserving the source's aspect ratio, i.e. with letter- or pillarboxing where necessary).

Maybe this could be implemented as an option under ScreenStream -> Settings -> Image, ideally with the option being enabled by default.

Regards

dkrivoruchko commented 1 year ago

Thanks for idea. Will think about it.

wqp53625 commented 1 year ago

Hi @dkrivoruchko ,

Thanks a lot for the fast reply and for considering this, is it much appreciated.

It seems like this could be achieved with the CSS object-fit: contain; property:

?

Regards

jjsarton commented 1 year ago

I have just tested your very good application. I have modified the css values for the img element to

img {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  max-height: 100vh;
  max-width: 100vw;
  width: 100%;
  object-fit: contain;
}

With this, the image take the full size of the view windows.

dkrivoruchko commented 1 year ago

Well, thanks for proposal, but this css break the case when we're waiting for stream to start. The "Press START on device" image is stretched as well

jjsarton commented 1 year ago

Well, thanks for proposal, but this css break the case when we're waiting for stream to start. The "Press START on device" image is stretched as well

You are right the image telling us to start the server is scaled up. A solution will be to adding or removing to the img element according to the state of the server (streaming or not=. If the streaming is started we can add streaming="true" and set the "width: 100%" as follow:

img[streaming=true] { width:100%;}

so we will have

img {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  max-height: 100vh;
  max-width: 100vw;
  object-fit: contain;
}
img[streaming=true] {
 width:100%;
}
dkrivoruchko commented 1 year ago

Ok. How will browser know if app is streaming as it use MJPEG and starting image is a part of this MJPEG? From browser perspective, all it knows is MJPEG.

jjsarton commented 1 year ago

Ok. How will browser know if app is streaming as it use MJPEG and starting image is a part of this MJPEG? From browser perspective, all it knows is MJPEG.

I dont' know this exactly, but you should seen if the http server is streaming. You have 2 channels, http itself and the image stream which is periodically refreshed. The server can send it state via http. This may be done for example each second or minute via a POST request, which return "I am running" or "I am stopped".

dkrivoruchko commented 1 year ago

Ok. Will think