736 lines
25 KiB
JavaScript
736 lines
25 KiB
JavaScript
/*
|
|
Copyright (C) 2016 Borsato Ivano
|
|
|
|
The JavaScript code in this page is free software: you can
|
|
redistribute it and/or modify it under the terms of the GNU
|
|
General Public License (GNU GPL) as published by the Free Software
|
|
Foundation, either version 3 of the License, or (at your option)
|
|
any later version. The code is distributed WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import * as Lib from './convenience.js';
|
|
import * as Settings from './settings.js';
|
|
|
|
// CONST GSP - base
|
|
const SCREEN =
|
|
'_SCREENCAST_RES_ _ENCODER_VIDEO_ ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! _CONTAINER_';
|
|
|
|
// CONST GSP - base plus sound
|
|
const SCREEN_SOUND =
|
|
'queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! _SCREENCAST_RES_ _ENCODER_VIDEO_ ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! mux. pulsesrc ! audioconvert ! _ENCODER_AUDIO_ ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! mux. _CONTAINER_ name=mux ';
|
|
|
|
// CONST GSP - base plus webcam
|
|
const SCREEN_WEBCAM =
|
|
'queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! videomixer name=mix _WEBCAM_OPT_ ! videoconvert ! _SCREENCAST_RES_ _ENCODER_VIDEO_ ! mux. v4l2src _WEBCAM_DEV_ ! _WEBCAM_CAP_ ! videoscale ! video/x-raw, width=_WEBCAM_W_, height=_WEBCAM_H_, add-borders=false ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! mix. _CONTAINER_ name=mux';
|
|
|
|
// CONST GSP - base plus sound and webcam stream
|
|
const SCREEN_WEBCAM_SOUND =
|
|
'queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! videomixer name=mix _WEBCAM_OPT_ ! videoconvert ! _SCREENCAST_RES_ _ENCODER_VIDEO_ ! mux. v4l2src _WEBCAM_DEV_ ! _WEBCAM_CAP_ ! videoscale ! video/x-raw, width=_WEBCAM_W_, height=_WEBCAM_H_, add-borders=false ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! mix. pulsesrc ! audioconvert ! _ENCODER_AUDIO_ ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 ! mux. _CONTAINER_ name=mux';
|
|
|
|
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
// CONST CONTAINER - WebM
|
|
const webmVP8 = {
|
|
fileExt: '.webm',
|
|
nameGSP: 'webmmux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'vp8enc min_quantizer=13 max_quantizer=20 cpu-used=5 deadline=1000000 sharpness=2 target-bitrate=10000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 15 \nVideo -> VP8 Encoder:\n-min_quantizer=13\n-max_quantizer=20\n-cpu-used=5\n-deadline=1000000\n-sharpness=2\n-target-bitrate=10000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'vp8enc min_quantizer=4 max_quantizer=13 cpu-used=2 deadline=500000 sharpness=0 target-bitrate=15000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> VP8 Encoder:\n-min_quantizer=4\n-max_quantizer=13\n-cpu-used=2\n-deadline=500000\n-sharpness=0\n-target-bitrate=15000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'vp8enc min_quantizer=0 max_quantizer=7 cpu-used=1 deadline=500000 sharpness=0 target-bitrate=25000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> VP8 Encoder:\n-min_quantizer=0\n-max_quantizer=7\n-cpu-used=1\n-deadline=500000\n-sharpness=0\n-target-bitrate=25000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'vp8enc min_quantizer=0 max_quantizer=0 cpu-used=0 deadline=100000 sharpness=0 target-bitrate=40000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 60 \nVideo -> VP8 Encoder:\n-min_quantizer=0\n-max_quantizer=0\n-cpu-used=0\n-deadline=100000\n-sharpness=0\n-target-bitrate=40000\nAudio -> Vorbis Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
const webmVP9 = {
|
|
fileExt: '.webm',
|
|
nameGSP: 'webmmux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'vp9enc min_quantizer=13 max_quantizer=20 cpu-used=5 deadline=1000000 sharpness=2 target-bitrate=10000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 15 \nVideo -> VP9 Encoder:\n-min_quantizer=13\n-max_quantizer=20\n-cpu-used=5\n-deadline=1000000\n-sharpness=2\n-target-bitrate=10000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'vp9enc min_quantizer=4 max_quantizer=13 cpu-used=2 deadline=500000 sharpness=0 target-bitrate=15000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> VP9 Encoder:\n-min_quantizer=4\n-max_quantizer=13\n-cpu-used=2\n-deadline=500000\n-sharpness=0\n-target-bitrate=15000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'vp9enc min_quantizer=0 max_quantizer=7 cpu-used=1 deadline=500000 sharpness=0 target-bitrate=25000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> VP9 Encoder:\n-min_quantizer=0\n-max_quantizer=7\n-cpu-used=1\n-deadline=500000\n-sharpness=0\n-target-bitrate=25000\nAudio -> Vorbis Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'vp9enc min_quantizer=0 max_quantizer=0 cpu-used=0 deadline=100000 sharpness=0 target-bitrate=40000 threads=%T',
|
|
aq: 'vorbisenc',
|
|
descr:
|
|
'FPS: 60 \nVideo -> VP9 Encoder:\n-min_quantizer=0\n-max_quantizer=0\n-cpu-used=0\n-deadline=100000\n-sharpness=0\n-target-bitrate=40000\nAudio -> Vorbis Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
// CONST CONTAINER - Mp4
|
|
const mp4 = {
|
|
fileExt: '.mp4',
|
|
nameGSP: 'mp4mux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'x264enc psy-tune="none" speed-preset="superfast" subme=1 qp-min=28 qp-max=40 threads=%T',
|
|
aq: 'lamemp3enc',
|
|
descr:
|
|
'FPS: 15 \nVideo -> x264enc Encoder:\n-psy-tune="none"\n-speed-preset="superfast"\n-subme=1\n-qp-min=28\n-qp-max=40\nAudio -> Mp3 Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="fast" subme=5 qp-min=18 qp-max=28 threads=%T',
|
|
aq: 'lamemp3enc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="fast"\n-subme=5\n-qp-min=18\n-qp-max=28\nAudio -> Mp3 Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="medium" subme=8 qp-min=10 qp-max=18 threads=%T',
|
|
aq: 'lamemp3enc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="medium"\n-subme=8\n-qp-min=10\n-qp-max=18\nAudio -> Mp3 Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'x264enc psy-tune="film" speed-preset="slower" subme=10 qp-min=0 qp-max=10 threads=%T',
|
|
aq: 'lamemp3enc',
|
|
descr:
|
|
'FPS: 60 \nVideo -> x264enc Encoder:\n-psy-tune="film"\n-speed-preset="slower"\n-subme=10\n-qp-min=0\n-qp-max=10\nAudio -> Mp3 Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
const mp4Aac = {
|
|
fileExt: '.mp4',
|
|
nameGSP: 'mp4mux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'x264enc psy-tune="none" speed-preset="superfast" subme=1 qp-min=28 qp-max=40 threads=%T',
|
|
aq: 'avenc_aac',
|
|
descr:
|
|
'FPS: 15 \nVideo -> x264enc Encoder:\n-psy-tune="none"\n-speed-preset="superfast"\n-subme=1\n-qp-min=28\n-qp-max=40\nAudio -> AAC Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="fast" subme=5 qp-min=18 qp-max=28 threads=%T',
|
|
aq: 'avenc_aac',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="fast"\n-subme=5\n-qp-min=18\n-qp-max=28\nAudio -> AAC Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="medium" subme=8 qp-min=10 qp-max=18 threads=%T',
|
|
aq: 'avenc_aac',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="medium"\n-subme=8\n-qp-min=10\n-qp-max=18\nAudio -> AAC Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'x264enc psy-tune="film" speed-preset="slower" subme=10 qp-min=0 qp-max=10 threads=%T',
|
|
aq: 'avenc_aac',
|
|
descr:
|
|
'FPS: 60 \nVideo -> x264enc Encoder:\n-psy-tune="film"\n-speed-preset="slower"\n-subme=10\n-qp-min=0\n-qp-max=10\nAudio -> AAC Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
// CONST CONTAINER - Mkv
|
|
const mkv = {
|
|
fileExt: '.mkv',
|
|
nameGSP: 'matroskamux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'x264enc psy-tune="none" speed-preset="superfast" subme=1 qp-min=28 qp-max=40 threads=%T',
|
|
aq: 'flacenc',
|
|
descr:
|
|
'FPS: 15 \nVideo -> x264enc Encoder:\n-psy-tune="none"\n-speed-preset="superfast"\n-subme=1\n-qp-min=28\n-qp-max=40\nAudio -> Flac Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="fast" subme=5 qp-min=18 qp-max=28 threads=%T',
|
|
aq: 'flacenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="fast"\n-subme=5\n-qp-min=18\n-qp-max=28\nAudio -> Flac Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'x264enc psy-tune="animation" speed-preset="medium" subme=8 qp-min=10 qp-max=18 threads=%T',
|
|
aq: 'flacenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> x264enc Encoder:\n-psy-tune="animation"\n-speed-preset="medium"\n-subme=8\n-qp-min=10\n-qp-max=18\nAudio -> Flac Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'x264enc psy-tune="film" speed-preset="slower" subme=10 qp-min=0 qp-max=10 threads=%T',
|
|
aq: 'flacenc',
|
|
descr:
|
|
'FPS: 60 \nVideo -> x264enc Encoder:\n-psy-tune="film"\n-speed-preset="slower"\n-subme=10\n-qp-min=0\n-qp-max=10\nAudio -> Flac Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
// CONST CONTAINER - Ogg
|
|
const ogg = {
|
|
fileExt: '.ogg',
|
|
nameGSP: 'oggmux',
|
|
quality: [
|
|
{
|
|
// quality level 0
|
|
fps: 15,
|
|
vq:
|
|
'theoraenc speed-level=3 vp3-compatible=true quality=10 bitrate=10000',
|
|
aq: 'opusenc',
|
|
descr:
|
|
'FPS: 15 \nVideo -> Theora Encoder:\n-speed-level=3\n-vp3-compatible=true\n-quality=10\n-bitrate=10000\nAudio -> Opus Encoder',
|
|
},
|
|
{
|
|
// quality level 1
|
|
fps: 30,
|
|
vq:
|
|
'theoraenc speed-level=1 vp3-compatible=false quality=30 bitrate=25000',
|
|
aq: 'opusenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> Theora Encoder:\n-speed-level=1\n-vp3-compatible=false\n-quality=30\n-bitrate=25000\nAudio -> Opus Encoder',
|
|
},
|
|
{
|
|
// quality level 2
|
|
fps: 30,
|
|
vq:
|
|
'theoraenc speed-level=0 vp3-compatible=false quality=50 bitrate=50000',
|
|
aq: 'opusenc',
|
|
descr:
|
|
'FPS: 30 \nVideo -> Theora Encoder:\n-speed-level=0\n-vp3-compatible=false\n-quality=50\n-bitrate=50000\nAudio -> Opus Encoder',
|
|
},
|
|
{
|
|
// quality level 3
|
|
fps: 60,
|
|
vq:
|
|
'theoraenc speed-level=0 vp3-compatible=false quality=60 bitrate=100000',
|
|
aq: 'opusenc',
|
|
descr:
|
|
'FPS: 60 \nVideo -> Theora Encoder\n-speed-level=0\n-vp3-compatible=false\n-quality=60\n-bitrate=100000\nAudio -> Opus Encoder',
|
|
},
|
|
],
|
|
};
|
|
|
|
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
// CONST RESOLUTION
|
|
const RESOLUTION = [
|
|
// NATIVE SCREENCAST RESOLUTION
|
|
'',
|
|
// PRESET/CUSTOM SCREENCAST RESOLUTION
|
|
'videoscale ! video/x-raw, width=_RES_WIDTH_, height=_RES_HEIGHT_, add-borders=_RES_KAR_ ! ',
|
|
];
|
|
|
|
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
// VAR ARRAY CONTAINER
|
|
// see cbt_FileContainer in *.glade files for the combo box
|
|
const CONTAINER = [webmVP8, webmVP9, mp4, mkv, ogg, mp4Aac];
|
|
|
|
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
/**
|
|
* Compose GSP
|
|
*
|
|
* @param {EasyScreenCastSettings} settings the extension's settings
|
|
* @param {MixerAudio} mixer the mixer
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
export function composeGSP(settings, mixer) {
|
|
Lib.TalkativeLog('-§-COMPOSE GSP');
|
|
|
|
let tmpGSP = '';
|
|
|
|
// retrieve options
|
|
let deviceWebcam = settings.getOption('s', Settings.DEVICE_WEBCAM_SETTING_KEY);
|
|
let deviceAudio = settings.getOption('i', Settings.INPUT_AUDIO_SOURCE_SETTING_KEY);
|
|
let qualityGSP = settings.getOption('i', Settings.QUALITY_SETTING_KEY);
|
|
let qualityWebcam = settings.getOption('s', Settings.QUALITY_WEBCAM_SETTING_KEY);
|
|
let resolutionType = settings.getOption('i', Settings.FILE_RESOLUTION_TYPE_SETTING_KEY);
|
|
let resolutionKAR = settings.getOption('b', Settings.FILE_RESOLUTION_KAR_SETTING_KEY);
|
|
let resolutionHeight = settings.getOption('i', Settings.FILE_RESOLUTION_HEIGHT_SETTING_KEY);
|
|
let resolutionWidth = settings.getOption('i', Settings.FILE_RESOLUTION_WIDTH_SETTING_KEY);
|
|
let container = settings.getOption('i', Settings.FILE_CONTAINER_SETTING_KEY);
|
|
|
|
Lib.TalkativeLog(
|
|
`-§-get option||devW: ${deviceWebcam}||devA: ${deviceAudio}||Qgsp: ${qualityGSP}||Qwc: ${qualityWebcam}||Res: ${resolutionType}||Cont: ${container}`
|
|
);
|
|
|
|
if (deviceWebcam !== '') {
|
|
switch (deviceAudio) {
|
|
case 0:
|
|
Lib.TalkativeLog('-§- SCREEN-WEBCAM');
|
|
|
|
tmpGSP = SCREEN_WEBCAM;
|
|
|
|
// replace WEBCAM_DEVICE/WEBCAM_CAPS
|
|
tmpGSP = _replaceWebcam(
|
|
tmpGSP,
|
|
deviceWebcam,
|
|
qualityWebcam,
|
|
settings
|
|
);
|
|
|
|
break;
|
|
case 1:
|
|
Lib.TalkativeLog('-§-SCREEN-WEBCAM-AUDIO(d)');
|
|
|
|
tmpGSP = SCREEN_WEBCAM_SOUND;
|
|
|
|
// replace WEBCAM_DEVICE/WEBCAM_CAPS/ENCODER-AUDIO
|
|
tmpGSP = _replaceAudio(
|
|
_replaceWebcam(tmpGSP, deviceWebcam, qualityWebcam, settings),
|
|
true,
|
|
container,
|
|
qualityGSP,
|
|
mixer
|
|
);
|
|
|
|
break;
|
|
default:
|
|
Lib.TalkativeLog('-§-SCREEN-WEBCAM-AUDIO');
|
|
|
|
tmpGSP = SCREEN_WEBCAM_SOUND;
|
|
|
|
// replace WEBCAM_DEVICE/WEBCAM_CAPS/ENCODER-AUDIO/AUDIO_DEVICE
|
|
tmpGSP = _replaceAudio(
|
|
_replaceWebcam(tmpGSP, deviceWebcam, qualityWebcam, settings),
|
|
false,
|
|
container,
|
|
qualityGSP,
|
|
mixer
|
|
);
|
|
}
|
|
} else {
|
|
switch (deviceAudio) {
|
|
case 0:
|
|
Lib.TalkativeLog('-§-SCREEN');
|
|
|
|
tmpGSP = SCREEN;
|
|
|
|
break;
|
|
case 1:
|
|
Lib.TalkativeLog('-§-SCREEN-AUDIO(d)');
|
|
|
|
tmpGSP = SCREEN_SOUND;
|
|
|
|
// replace ENCODER-AUDIO
|
|
tmpGSP = _replaceAudio(
|
|
tmpGSP,
|
|
true,
|
|
container,
|
|
qualityGSP,
|
|
mixer
|
|
);
|
|
|
|
break;
|
|
default:
|
|
Lib.TalkativeLog('-§-SCREEN-AUDIO');
|
|
|
|
tmpGSP = SCREEN_SOUND;
|
|
|
|
// replace ENCODER-AUDIO/AUDIO_DEVICE
|
|
tmpGSP = _replaceAudio(
|
|
tmpGSP,
|
|
false,
|
|
container,
|
|
qualityGSP,
|
|
mixer
|
|
);
|
|
}
|
|
}
|
|
|
|
// compose resolution string
|
|
var resolution = _composeResolution(
|
|
resolutionType,
|
|
resolutionHeight,
|
|
resolutionWidth,
|
|
resolutionKAR
|
|
);
|
|
|
|
// replace RESOLUTION/ENCODER-VIDEO/CONTAINER
|
|
var mapObj = {
|
|
_SCREENCAST_RES_: resolution,
|
|
_ENCODER_VIDEO_: CONTAINER[container].quality[qualityGSP].vq,
|
|
_CONTAINER_: CONTAINER[container].nameGSP,
|
|
};
|
|
|
|
tmpGSP = tmpGSP.replace(
|
|
/_SCREENCAST_RES_|_ENCODER_VIDEO_|_CONTAINER_/gi,
|
|
match => {
|
|
return mapObj[match];
|
|
}
|
|
);
|
|
|
|
Lib.TalkativeLog(`-§-final GSP :${tmpGSP}`);
|
|
|
|
return tmpGSP;
|
|
}
|
|
|
|
/**
|
|
* replace audio
|
|
*
|
|
* @param {string} gspRA input pipeline to be modified
|
|
* @param {boolean} defaultAudio whether to use the default audio device
|
|
* @param {int} ConTMP selected output container. Used to determine correct audio encoder
|
|
* @param {int} QGSPtmp quality setting
|
|
* @param {MixerAudio} mixer audio mixer
|
|
* @returns {string} pipeline with audio
|
|
*/
|
|
function _replaceAudio(gspRA, defaultAudio, ConTMP, QGSPtmp, mixer) {
|
|
Lib.TalkativeLog(`-§-replace audio default->${defaultAudio}`);
|
|
// replace device/encoder
|
|
var aq = CONTAINER[ConTMP].quality[QGSPtmp].aq;
|
|
Lib.TalkativeLog(`-§-pipeline pre-audio:${gspRA} aq:${aq}`);
|
|
var audioPipeline;
|
|
|
|
if (defaultAudio) {
|
|
Lib.TalkativeLog('-§-default audio source');
|
|
audioPipeline = gspRA.replace(/_ENCODER_AUDIO_/gi, aq);
|
|
} else {
|
|
var audiosource = mixer.getAudioSource();
|
|
if (audiosource === undefined) {
|
|
Lib.TalkativeLog('-§-failure combination of array audio sources');
|
|
audioPipeline = gspRA.replace(/_ENCODER_AUDIO_/gi, aq);
|
|
} else {
|
|
Lib.TalkativeLog('-§-correct audio source assignment');
|
|
if (audiosource.indexOf('output') !== -1)
|
|
audiosource += '.monitor';
|
|
|
|
var reDev = `pulsesrc device="${audiosource}"`;
|
|
|
|
var mapObj = {
|
|
pulsesrc: reDev,
|
|
_ENCODER_AUDIO_: aq,
|
|
};
|
|
|
|
audioPipeline = gspRA.replace(
|
|
/pulsesrc|_ENCODER_AUDIO_/gi,
|
|
match => {
|
|
return mapObj[match];
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
Lib.TalkativeLog(`-§-pipeline post-audio:${audioPipeline}`);
|
|
|
|
return audioPipeline;
|
|
}
|
|
|
|
/**
|
|
* replace webcam
|
|
*
|
|
* @param {string} gspRW input pipeline to be modified
|
|
* @param {string} device webcam device file (e.g. /dev/video0)
|
|
* @param {string} caps quality options
|
|
* @param {EasyScreenCastSettings} settings the extension's settings
|
|
* @returns {string} pipeline with webcam settings
|
|
*/
|
|
function _replaceWebcam(gspRW, device, caps, settings) {
|
|
Lib.TalkativeLog(`-§-replace webcam -> ${device} caps: ${caps}`);
|
|
|
|
// replace device/caps
|
|
var reDev = `device=${device}`;
|
|
var reWCopt = _composeWebCamOption(settings);
|
|
var [reWCwidth, reWCheight] = _getWebCamDimension(settings);
|
|
|
|
Lib.TalkativeLog(`-§-pipeline pre-webcam:${gspRW}`);
|
|
|
|
var mapObj = {
|
|
_WEBCAM_DEV_: reDev,
|
|
_WEBCAM_CAP_: caps,
|
|
_WEBCAM_OPT_: reWCopt,
|
|
_WEBCAM_W_: reWCwidth,
|
|
_WEBCAM_H_: reWCheight,
|
|
};
|
|
|
|
var webcamPipeline = gspRW.replace(
|
|
/_WEBCAM_DEV_|_WEBCAM_CAP_|_WEBCAM_OPT_|_WEBCAM_W_|_WEBCAM_H_/gi,
|
|
match => {
|
|
return mapObj[match];
|
|
}
|
|
);
|
|
|
|
Lib.TalkativeLog(`-§-pipeline post-webcam:${webcamPipeline}`);
|
|
|
|
return webcamPipeline;
|
|
}
|
|
|
|
/**
|
|
* replace resolution
|
|
*
|
|
* @param {int} tmpRes resolution type: native/custom
|
|
* @param {int} h custom height
|
|
* @param {int} w custom width
|
|
* @param {boolean} kar whether to keep aspect ratio
|
|
* @returns {string} pipeline part for scaling resolution
|
|
*/
|
|
function _composeResolution(tmpRes, h, w, kar) {
|
|
Lib.TalkativeLog(`-§-resolution option: ${tmpRes}`);
|
|
var strRes = RESOLUTION[0];
|
|
var mapObj = {};
|
|
|
|
switch (tmpRes) {
|
|
case -1:
|
|
break;
|
|
case 999:
|
|
mapObj = {
|
|
_RES_KAR_: kar ? 'true' : 'false',
|
|
_RES_HEIGHT_: h,
|
|
_RES_WIDTH_: w,
|
|
};
|
|
|
|
strRes = RESOLUTION[1].replace(
|
|
/_RES_KAR_|_RES_HEIGHT_|_RES_WIDTH_/gi,
|
|
match => {
|
|
return mapObj[match];
|
|
}
|
|
);
|
|
break;
|
|
default:
|
|
mapObj = {
|
|
_RES_KAR_: 'true',
|
|
_RES_HEIGHT_: h,
|
|
_RES_WIDTH_: w,
|
|
};
|
|
|
|
strRes = RESOLUTION[1].replace(
|
|
/_RES_KAR_|_RES_WIDTH_|_RES_HEIGHT_/gi,
|
|
match => {
|
|
return mapObj[match];
|
|
}
|
|
);
|
|
}
|
|
|
|
Lib.TalkativeLog(`-§-compose resolution: ${strRes}`);
|
|
return strRes;
|
|
}
|
|
|
|
/**
|
|
* compose option webcam position
|
|
*
|
|
* @param {EasyScreenCastSettings} settings the extension's settings
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
function _composeWebCamOption(settings) {
|
|
Lib.TalkativeLog('-§-compose webcam option');
|
|
|
|
// retrieve option webcam
|
|
var webcamAlpha = settings.getOption('d', Settings.ALPHA_CHANNEL_WEBCAM_SETTING_KEY);
|
|
var webcamMarginX = settings.getOption('i', Settings.MARGIN_X_WEBCAM_SETTING_KEY);
|
|
var webcamMarginY = settings.getOption('i', Settings.MARGIN_Y_WEBCAM_SETTING_KEY);
|
|
var webcamCornerPosition = settings.getOption('i', Settings.CORNER_POSITION_WEBCAM_SETTING_KEY);
|
|
var [webcamWidth, webcamHeight, screenWidth, screenHeight] = _getWebCamDimension(settings);
|
|
|
|
var posX = 0;
|
|
var posY = 0;
|
|
|
|
Lib.TalkativeLog(
|
|
`-§-alpha=${webcamAlpha} |marX=${webcamMarginX} |marY=${webcamMarginY} |corner=${webcamCornerPosition}`
|
|
);
|
|
|
|
// corner top-left
|
|
posX = webcamMarginX;
|
|
posY = webcamMarginY;
|
|
|
|
switch (webcamCornerPosition) {
|
|
case 0:
|
|
// corner bottom-right
|
|
posX = Math.floor(screenWidth - (webcamWidth + webcamMarginX));
|
|
posY = Math.floor(screenHeight - (webcamHeight + webcamMarginY));
|
|
break;
|
|
case 1:
|
|
// corner bottom-left
|
|
posX = webcamMarginX;
|
|
posY = Math.floor(screenHeight - (webcamHeight + webcamMarginY));
|
|
break;
|
|
case 2:
|
|
// corner top-right
|
|
posX = Math.floor(screenWidth - (webcamWidth + webcamMarginX));
|
|
posY = webcamMarginY;
|
|
break;
|
|
default:
|
|
}
|
|
|
|
// check valid position
|
|
if ((posX < 0 || posX > screenWidth) && (posY < 0 || posY > screenHeight)) {
|
|
Lib.TalkativeLog('-§-NOT valid position');
|
|
posX = 0;
|
|
posY = 0;
|
|
}
|
|
|
|
var tmpWCopt =
|
|
`sink_0::alpha=1 sink_1::alpha=${
|
|
webcamAlpha
|
|
} sink_1::xpos=${
|
|
posX
|
|
} sink_1::ypos=${
|
|
posY
|
|
} `;
|
|
|
|
Lib.TalkativeLog(`-§-posX=${posX} |posY=${posY}`);
|
|
Lib.TalkativeLog(`-§-webcam option=${tmpWCopt}`);
|
|
|
|
return tmpWCopt;
|
|
}
|
|
|
|
/**
|
|
* retrieve dimension webcam
|
|
*
|
|
* @param {EasyScreenCastSettings} settings the extension's settings
|
|
*
|
|
* @returns {*[]} array with webcam width,height,screen-width,screen-height
|
|
*/
|
|
function _getWebCamDimension(settings) {
|
|
Lib.TalkativeLog('-§-get webcam dimension');
|
|
|
|
var webcamWidth = settings.getOption('i', Settings.WIDTH_WEBCAM_SETTING_KEY);
|
|
var webcamHeight = settings.getOption('i', Settings.HEIGHT_WEBCAM_SETTING_KEY);
|
|
var webcamUnit = settings.getOption('i', Settings.TYPE_UNIT_WEBCAM_SETTING_KEY);
|
|
var screenWidth = settings.getOption('i', Settings.WIDTH_SETTING_KEY);
|
|
var screenHeight = settings.getOption('i', Settings.HEIGHT_SETTING_KEY);
|
|
|
|
if (settings.getOption('i', Settings.AREA_SCREEN_SETTING_KEY) === 0) {
|
|
screenWidth = global.screen_width;
|
|
screenHeight = global.screen_height;
|
|
}
|
|
|
|
Lib.TalkativeLog(
|
|
`-§-WC w=${webcamWidth} WC h=${webcamHeight} WCtype=${webcamUnit} screen W=${screenWidth} screen H=${screenHeight}`
|
|
);
|
|
|
|
if (webcamUnit === 0) {
|
|
webcamWidth = Math.floor((screenWidth * webcamWidth) / 100);
|
|
webcamHeight = Math.floor((screenHeight * webcamHeight) / 100);
|
|
}
|
|
|
|
Lib.TalkativeLog(`-§-after percentage WCw=${webcamWidth} WCh=${webcamHeight}`);
|
|
|
|
return [webcamWidth, webcamHeight, screenWidth, screenHeight];
|
|
}
|
|
|
|
/**
|
|
* get description
|
|
*
|
|
* @param {int} quality selected quality
|
|
* @param {int} container selected container format
|
|
* @returns {string}
|
|
*/
|
|
export function getDescr(quality, container) {
|
|
Lib.TalkativeLog(`-§-get description Q-> ${quality} C-> ${container}`);
|
|
|
|
return CONTAINER[container].quality[quality].descr;
|
|
}
|
|
|
|
/**
|
|
* get fps
|
|
*
|
|
* @param {int} quality selected quality
|
|
* @param {int} container selected container format
|
|
* @returns {number}
|
|
*/
|
|
export function getFps(quality, container) {
|
|
Lib.TalkativeLog(`-§-get fps Q-> ${quality} C-> ${container}`);
|
|
|
|
return CONTAINER[container].quality[quality].fps;
|
|
}
|
|
|
|
/**
|
|
* get file extension
|
|
*
|
|
* @param {int} container selected container format
|
|
* @returns {string}
|
|
*/
|
|
export function getFileExtension(container) {
|
|
Lib.TalkativeLog(`-§-get file extension C-> ${container}`);
|
|
|
|
return CONTAINER[container].fileExt;
|
|
}
|