Skip to content

Commit

Permalink
Calculate <video> size not in fullscreen
Browse files Browse the repository at this point in the history
  • Loading branch information
sergystepanov committed Mar 5, 2024
1 parent da39a61 commit 95ac257
Showing 1 changed file with 35 additions and 23 deletions.
58 changes: 35 additions & 23 deletions web/js/stream/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const stream = (() => {
},
state = {
screen: screen,
fullscreen: false,
timerId: null,
w: 0,
h: 0,
Expand All @@ -27,11 +28,7 @@ const stream = (() => {
screen.play()
.then(() => log.info('Media can autoplay'))
.catch(error => {
// Usually error happens when we autoplay unmuted video, browser requires manual play.
// We already muted video and use separate audio encoding so it's fine now
log.error('Media Failed to autoplay');
log.error(error)
// TODO: Consider workaround
log.error('Media failed to play', error);
});
}

Expand All @@ -49,6 +46,23 @@ const stream = (() => {

const getVideoEl = () => screen

const getActualVideoSize = () => {
if (state.fullscreen) {
// we can't get real <video> size without black bars, so we're trying to
// derive its dimensions from the known width or height
// and by calculating unknown dimension from the aspect ratio
const horizontal = screen.videoWidth > screen.videoHeight;
return {
w: horizontal ? screen.offsetHeight * state.aspect : screen.offsetWidth,
h: horizontal ? screen.offsetHeight : screen.offsetWidth * state.aspect
}
}

const size = screen.getBoundingClientRect()

return {w: size.width, h: size.height}
}

screen.onerror = (e) => {
// video playback failed - show a message saying why
switch (e.target.error.code) {
Expand Down Expand Up @@ -155,16 +169,16 @@ const stream = (() => {
let pointerLocked = false;

event.sub(FULLSCREEN_CHANGE, async (fullscreenEl) => {
state.fullscreen = !!fullscreenEl;

const w = window.screen.width ?? window.innerWidth;
const h = window.screen.height ?? window.innerHeight;

const ww = document.documentElement.innerWidth;
const hh = document.documentElement.innerHeight;

const fullscreen = !!fullscreenEl;

screen.style.padding = '0'
if (fullscreen) {
if (state.fullscreen) {
const dw = (w - ww * state.aspect) / 2
screen.style.padding = `0 ${dw}px`
// chrome bug
Expand All @@ -173,31 +187,29 @@ const stream = (() => {
screen.style.padding = `0 ${dw}px`
}, 1)
}
makeFullscreen(fullscreen);
makeFullscreen(state.fullscreen);

screen.blur();

if (fullscreen && !pointerLocked) {
if (state.fullscreen && !pointerLocked) {
// event.pub(POINTER_LOCK_CHANGE, screen);
await screen.requestPointerLock(
// { unadjustedMovement: true,}
// { unadjustedMovement: true,}
);
}

screen.onpointerdown = fullscreen ? handlePointerDown : null;
screen.onpointerup = fullscreen ? handlePointerUp : null;
screen.onpointerdown = state.fullscreen ? handlePointerDown : null;
screen.onpointerup = state.fullscreen ? handlePointerUp : null;

// !to flipped
})

let ex = 0, ey = 0;
const scaleCursorPos = (x, y) => {
const horizontal = screen.videoWidth > screen.videoHeight;
const {w, h} = getActualVideoSize();

const arW = horizontal ? screen.offsetHeight * state.aspect : screen.offsetHeight;
const arH = horizontal ? screen.offsetHeight : screen.offsetWidth * state.aspect;
const sw = arW / screen.videoWidth;
const sh = arH / screen.videoHeight;
const sw = w / screen.videoWidth;
const sh = h / screen.videoHeight;

const rez = {
dx: x / sw + ex,
Expand All @@ -214,8 +226,8 @@ const stream = (() => {
}

const handlePointerMove = (e) => {
const delta = scaleCursorPos(e.movementX, e.movementY);
event.pub(MOUSE_MOVED, delta);
// !to fix ff https://github.com/w3c/pointerlock/issues/42
event.pub(MOUSE_MOVED, scaleCursorPos(e.movementX, e.movementY));
}

event.sub(POINTER_LOCK_CHANGE, (lockedEl) => {
Expand All @@ -240,9 +252,9 @@ const stream = (() => {
state.screen.style['object-fit'] = a.toFixed(6) !== a2.toFixed(6) ? 'fill' : fit
state.h = hh
state.w = Math.floor(hh * a)
state.screen.setAttribute('width', ww)
state.screen.setAttribute('height', hh)
state.screen.style.aspectRatio = state.aspect
state.screen.setAttribute('width', '' + ww)
state.screen.setAttribute('height', '' + hh)
state.screen.style.aspectRatio = '' + state.aspect
})

return {
Expand Down

0 comments on commit 95ac257

Please sign in to comment.