Display portrait video correctly

This commit is contained in:
David Halls
2021-07-17 08:44:02 +01:00
parent 2479db5401
commit 2767c05572
5 changed files with 34 additions and 17 deletions

7
site/example.css Normal file
View File

@@ -0,0 +1,7 @@
.portrait {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%) rotate(-90deg);
width: unset !important;
}

View File

@@ -2,6 +2,7 @@
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
<link href="./example.css" rel="stylesheet">
<script type="module" src="./example.js"></script>
</head>
<body>
@@ -31,7 +32,7 @@
<strong>An error occurred!</strong> See the Developer Console for details.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<div class="position-relative">
<div class="position-relative h-100">
<canvas id="canvas" class="w-100" playsinline></canvas>
<div class="position-fixed top-50 start-50 translate-middle">
<div id="waiting" class="text-primary spinner-border d-none" role="status">

View File

@@ -44,11 +44,11 @@ async function start() {
go_live_el.disabled = true;
waiting_el.classList.remove('d-none');
const parent_el = canvas_el.parentNode;
parent_el.removeChild(canvas_el);
const canvas_el_parent = canvas_el.parentNode;
canvas_el_parent.removeChild(canvas_el);
canvas_el = canvas_proto.cloneNode();
canvas_el.classList.add('invisible');
parent_el.appendChild(canvas_el);
canvas_el_parent.appendChild(canvas_el);
if (error_alert_el.parentNode) {
error_alert_el_parent.removeChild(error_alert_el);
@@ -146,13 +146,16 @@ async function start() {
video_el.addEventListener('loadeddata', async function () {
try {
// make canvas same size as native video dimensions so every pixel is seen
if (this.videoWidth > this.videoHeight) {
canvas_el.width = this.videoWidth;
canvas_el.height = this.videoHeight;
} else {
const portrait = this.videoHeight > this.videoWidth;
if (portrait) {
canvas_el.width = this.videoHeight;
canvas_el.height = this.videoWidth;
canvas_el.classList.add('portrait');
} else {
canvas_el.width = this.videoWidth;
canvas_el.height = this.videoHeight;
}
gl_canvas.setUniform('u_portrait', portrait);
// start the camera video
this.play();
@@ -169,6 +172,13 @@ async function start() {
canvas_stream.addTrack(audio_tracks[0]);
}
function update() {
// update the canvas
if (gl_canvas.onLoop() && portrait) {
canvas_el.style.height = canvas_el_parent.clientWidth;
}
}
// start HLS from the canvas stream to the ingestion URL
hls = new HLS(canvas_stream, ingestion_url, ffmpeg_lib_url, frame_rate);
hls.addEventListener('run', () => console.log('HLS running'));
@@ -186,11 +196,9 @@ async function start() {
waiting_el.classList.add('d-none');
canvas_el.classList.remove('invisible');
go_live_el.disabled = false;
gl_canvas.onLoop();
});
hls.addEventListener('update', () => {
gl_canvas.onLoop();
update();
});
hls.addEventListener('update', update);
await hls.start();
} catch (ex) {
cleanup(ex);

View File

@@ -42,7 +42,9 @@ export class GlCanvas extends Canvas {
// Better to "support" only hardware rendering (or very fast CPUs!), where
// time to render each frame is only 1ms max.
this.update_limiter.threshold = (Date.now() - now) * 2;
return true;
}
return false;
}
// Prevent errors after destruction
destroy() {

View File

@@ -4,17 +4,16 @@ precision highp float;
uniform sampler2D u_texture;
uniform vec2 u_resolution;
uniform bool u_portrait;
out vec4 colour;
void main() {
vec2 coord;
// TODO: we should pass in whether to invert
ivec2 size = textureSize(u_texture, 0);
if (size.x > size.y) {
coord = gl_FragCoord.xy / u_resolution.xy;
} else {
if (u_portrait) {
coord = gl_FragCoord.yx / u_resolution.yx;
} else {
coord = gl_FragCoord.xy / u_resolution.xy;
}
vec3 color = texture(u_texture, coord).rgb;
float grey = dot(color, vec3(0.299, 0.587, 0.114));