Add ability to select encoder resolution

This commit is contained in:
David Halls
2021-08-17 09:20:28 +01:00
parent 6743fe3a1a
commit f687aabd41
5 changed files with 68 additions and 13 deletions

View File

@@ -44,6 +44,11 @@
<input id="zoom-portrait" class="form-check-input" type="checkbox">
<label for="zoom-portrait" class="form-check-label">Zoom portrait video</label>
</div>
<div class="pt-4">
<label for="resolution" class="form-label">Encoder resolution</label>
<select id="resolution" class="form-select">
</select>
</div>
</div>
<div id="error-alert" class="alert alert-danger alert-dismissible fade mb-0 flex-grow-0" role="alert">
<strong>An error occurred!</strong> See the Developer Console for details.

View File

@@ -1,6 +1,16 @@
import { GlCanvas } from './gl-canvas.js';
import { HLS } from './hls.js';
import {
HLS,
video_encoder_codec,
videoBitsPerSecond
} from './hls.js';
import shader from './greyscale-shader.js';
import {
supported_video_encoder_configs,
max_video_encoder_config,
min_camera_video_config,
max_camera_video_config
} from './resolution.js';
const ingestion_url_el = document.getElementById('ingestion-url');
ingestion_url_el.value = localStorage.getItem('streamana-example-ingestion-url');
@@ -58,6 +68,42 @@ document.body.addEventListener('click', function (ev) {
}
});
let preferred_resolution = localStorage.getItem('streamana-resolution');
if (preferred_resolution) {
preferred_resolution = JSON.parse(preferred_resolution);
} else {
preferred_resolution = {
width: 1280,
height: 720,
ratio: '16:9'
};
}
const resolution_el = document.getElementById('resolution');
let video_encoder_config = await max_video_encoder_config({
...preferred_resolution,
codec: video_encoder_codec,
bitrate: videoBitsPerSecond
});
const video_encoder_configs = new Map();
for (let config of await supported_video_encoder_configs({
codec: video_encoder_codec,
bitrate: videoBitsPerSecond
})) {
const option = document.createElement('option');
option.innerHTML = `${config.width}x${config.height} &mdash; ${config.label}`;
option.selected = config.label === video_encoder_config.label;
resolution_el.appendChild(option);
video_encoder_configs.set(option.innerText, config);
}
resolution_el.addEventListener('change', function (ev) {
video_encoder_config = video_encoder_configs.get(this.value);
localStorage.setItem('streamana-resolution', JSON.stringify({
width: video_encoder_config.width,
height: video_encoder_config.height,
ratio: video_encoder_config.ratio
}));
});
let hls;
async function start() {
@@ -150,29 +196,30 @@ async function start() {
await video_el.play();
// capture video from webcam
const video_constraints = {
//width: 4096,
//height: 2160,
width: 1280,
height: 720,
//width: 800,
//height: 600,
const camera_video_constraints = {
ratio: video_encoder_config.ratio,
width: video_encoder_config.width,
height: video_encoder_config.height,
frameRate: {
ideal: 30,
max: 30
}
};
const camera_video_config = await min_camera_video_config(camera_video_constraints) ||
await max_camera_video_config(camera_video_constraints);
try {
camera_stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: video_constraints
video: camera_video_config
});
} catch (ex) {
// retry in case audio isn't available
console.warn("Failed to get user media, retrying without audio");
camera_stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: video_constraints
video: camera_video_config
});
}

View File

@@ -2,9 +2,11 @@ import { UpdateLimiter } from './update-limiter.js';
import { MuxReceiver } from './mux-receiver.js';
const audioBitsPerSecond = 128 * 1000;
const videoBitsPerSecond = 2500 * 1000;
export const videoBitsPerSecond = 2500 * 1000;
const key_frame_interval = 3;
export const video_encoder_codec = 'avc1.42E01E' /*'avc1.42001E'*/;
export class HLS extends EventTarget {
constructor(stream, base_url, ffmpeg_lib_url, frame_rate, rotate) {
super();
@@ -54,7 +56,7 @@ export class HLS extends EventTarget {
console.warn(ex);
try {
// next try WebCodecs - this should work on Chrome including Android
this.webcodecs('avc1.42E01E' /*'avc1.42001E'*/,
this.webcodecs(video_encoder_codec,
'opus' /*'pcm'*/,
{ avc: { format: 'annexb' } });
console.log("Using WebCodecs");

1
site/resolution.js Symbolic link
View File

@@ -0,0 +1 @@
../webm-muxer.js/resolution.js