@@ -35,11 +35,11 @@ export function Streamer() {
/************************************************************************/
var _ _janus _enabl ed = null ;
var _ _janus _import ed = null ;
var _ _streamer = null ;
var _ _state = null ;
var _ _resolution = { "width" : 640 , "height" : 480 } ;
var _ _res = { "width" : 640 , "height" : 480 } ;
var _ _init _ _ = function ( ) {
_ _streamer = new MjpegStreamer ( _ _setActive , _ _setInactive , _ _setInfo ) ;
@@ -47,22 +47,22 @@ export function Streamer() {
$ ( "stream-led" ) . title = "Stream inactive" ;
tools . slider . setParams ( $ ( "stream-quality-slider" ) , 5 , 100 , 5 , 80 , function ( value ) {
$ ( "stream-quality-value" ) . innerHTML = ` ${ value } % ` ;
$ ( "stream-quality-value" ) . innerText = ` ${ value } % ` ;
} ) ;
tools . slider . setOnUpDelayed ( $ ( "stream-quality-slider" ) , 1000 , ( value ) => _ _sendParam ( "quality" , value ) ) ;
tools . slider . setParams ( $ ( "stream-h264-bitrate-slider" ) , 25 , 20000 , 25 , 5000 , function ( value ) {
$ ( "stream-h264-bitrate-value" ) . innerHTML = value ;
$ ( "stream-h264-bitrate-value" ) . innerText = value ;
} ) ;
tools . slider . setOnUpDelayed ( $ ( "stream-h264-bitrate-slider" ) , 1000 , ( value ) => _ _sendParam ( "h264_bitrate" , value ) ) ;
tools . slider . setParams ( $ ( "stream-h264-gop-slider" ) , 0 , 60 , 1 , 30 , function ( value ) {
$ ( "stream-h264-gop-value" ) . innerHTML = value ;
$ ( "stream-h264-gop-value" ) . innerText = value ;
} ) ;
tools . slider . setOnUpDelayed ( $ ( "stream-h264-gop-slider" ) , 1000 , ( value ) => _ _sendParam ( "h264_gop" , value ) ) ;
tools . slider . setParams ( $ ( "stream-desired-fps-slider" ) , 0 , 120 , 1 , 0 , function ( value ) {
$ ( "stream-desired-fps-value" ) . innerHTML = ( value === 0 ? "Unlimited" : value ) ;
$ ( "stream-desired-fps-value" ) . innerText = ( value === 0 ? "Unlimited" : value ) ;
} ) ;
tools . slider . setOnUpDelayed ( $ ( "stream-desired-fps-slider" ) , 1000 , ( value ) => _ _sendParam ( "desired_fps" , value ) ) ;
@@ -86,7 +86,7 @@ export function Streamer() {
tools . slider . setParams ( $ ( "stream-audio-volume-slider" ) , 0 , 100 , 1 , 0 , function ( value ) {
$ ( "stream-video" ) . muted = ! value ;
$ ( "stream-video" ) . volume = value / 100 ;
$ ( "stream-audio-volume-value" ) . innerHTML = value + "%" ;
$ ( "stream-audio-volume-value" ) . innerText = value + "%" ;
if ( _ _streamer . getMode ( ) === "janus" ) {
let allow _audio = ! $ ( "stream-video" ) . muted ;
if ( _ _streamer . isAudioAllowed ( ) !== allow _audio ) {
@@ -104,6 +104,13 @@ export function Streamer() {
/************************************************************************/
self . ensureDeps = function ( callback ) {
JanusStreamer . ensure _janus ( function ( avail ) {
_ _janus _imported = avail ;
callback ( ) ;
} ) ;
} ;
self . getGeometry = function ( ) {
// Первоначально обновление геометрии считалось через ResizeObserver.
// Н о оно не ловило некоторые события, например в последовательности:
@@ -126,90 +133,106 @@ export function Streamer() {
} ;
} ;
self . setJanusEnabled = function ( enabled ) {
let has _webrtc = JanusStreamer . is _webrtc _available ( ) ;
let has _h264 = JanusStreamer . is _h264 _available ( ) ;
let set _enabled = function ( imported ) {
tools . hidden . setVisible ( $ ( "stream-message-no-webrtc" ) , enabled && ! has _webrtc ) ;
tools . hidden . setVisible ( $ ( "stream-message-no-h264" ) , enabled && ! has _h264 ) ;
_ _janus _enabled = ( enabled && has _webrtc && imported ) ; // Don't check has_h264 for sure
tools . feature . setEnabled ( $ ( "stream-mode" ) , _ _janus _enabled ) ;
tools . info (
` Stream: Janus WebRTC state: enabled= ${ enabled } , `
+ ` webrtc= ${ has _webrtc } , h264= ${ has _h264 } , imported= ${ imported } `
) ;
let mode = ( _ _janus _enabled ? tools . storage . get ( "stream.mode" , "janus" ) : "mjpeg" ) ;
tools . radio . clickValue ( "stream-mode-radio" , mode ) ;
if ( ! _ _janus _enabled ) {
tools . feature . setEnabled ( $ ( "stream-audio" ) , false ) ; // Enabling in stream_janus.js
}
self . setState ( _ _state ) ;
} ;
if ( enabled && has _webrtc ) {
JanusStreamer . ensure _janus ( set _enabled ) ;
} else {
set _enabled ( false ) ;
}
} ;
self . setState = function ( state ) {
_ _state = state ;
if ( _ _janus _enabled !== null ) {
_ _applyState ( wm . isWindowVisible ( $ ( "stream-window" ) ) ? _ _state : null ) ;
if ( state ) {
if ( ! __state ) {
_ _state = { } ;
}
if ( state . features ) {
_ _state . features = state . features ;
_ _state . limits = state . limits ; // Following together with features
}
if ( _ _state . features && state . streamer !== undefined ) {
_ _state . streamer = state . streamer ;
}
_ _setControlsEnabled ( ! ! state . streamer ) ;
} else {
_ _state = null ;
}
let visible = wm . isWindowVisible ( $ ( "stream-window" ) ) ;
_ _applyState ( ( visible && _ _state && _ _state . features ) ? state : null ) ;
} ;
var _ _applyState = function ( state ) {
if ( state ) {
tools . feature . setEnabled ( $ ( "stream-quality" ) , state . features . quality && ( state . streamer === null || state . streamer . encoder . quality > 0 ) ) ;
tools . feature . setEnabled ( $ ( "stream-h264-bitrate" ) , state . features . h264 && _ _janus _enabled ) ;
tools . feature . setEnabled ( $ ( "stream-h264-gop" ) , state . features . h264 && _ _janus _enabled ) ;
tools . feature . setEnabled ( $ ( "stream-resolution" ) , state . features . resolution ) ;
if ( _ _janus _imported === null ) {
alert ( "__janus_imported is null, please report" ) ;
return ;
}
if ( state . streamer ) {
tools . el . setEnabled ( $ ( "stream-quality-slider" ) , true ) ;
tools . slider . setValue ( $ ( "stream-quality-slider" ) , state . streamer . encoder . quality ) ;
if ( ! state ) {
_ _streamer . stopStream ( ) ;
return ;
}
if ( state . features . h264 && _ _janus _enabled ) {
_ _setLimitsAndValue ( $ ( "stream-h264-bitrate-slider" ) , state . limits . h264 _bitrate , state . streamer . h264 . bitrate ) ;
tools . el . setEnabled ( $ ( "stream-h264-bitrate-slider" ) , true ) ;
if ( state . features ) {
let f = state . features ;
let l = state . limits ;
let has _webrtc = JanusStreamer . is _webrtc _available ( ) ;
let has _h264 = JanusStreamer . is _h264 _available ( ) ;
let has _janus = ( _ _janus _imported && f . h264 && has _webrtc ) ; // Don't check has_h264 for sure
_ _setLimitsAndValue ( $ ( "stream-h264-gop-slider" ) , state . limits . h264 _gop , state . streamer . h264 . gop ) ;
tools . el . setEnabled ( $ ( "stream-h264-gop-slider" ) , true ) ;
tools . info (
` Stream: Janus WebRTC state: features.h264= ${ f . h264 } , `
+ ` webrtc= ${ has _webrtc } , h264= ${ has _h264 } , janus_imported= ${ _ _janus _imported } `
) ;
tools . hidden . setVisible ( $ ( "stream-message-no-webrtc" ) , _ _janus _imported && f . h264 && ! has _webrtc ) ;
tools . hidden . setVisible ( $ ( "stream-message-no-h264" ) , _ _janus _imported && f . h264 && ! has _h264 ) ;
tools . slider . setRange ( $ ( "stream-desired-fps-slider" ) , l . desired _fps . min , l . desired _fps . max ) ;
if ( f . resolution ) {
let el = $ ( "stream-resolution-selector" ) ;
el . options . length = 0 ;
for ( let res of l . available _resolutions ) {
tools . selector . addOption ( el , res , res ) ;
}
_ _setLimitsAndValue ( $ ( "stream-desired-fps-slider" ) , state . limits . desired _fps , state . streamer . source . desired _fps ) ;
tools . el . setEnabled ( $ ( "stream-desired-fps-slider" ) , true ) ;
let resolution _str = _ _makeStringResolution ( state . streamer . source . resolution ) ;
if ( _ _makeStringResolution ( _ _resolution ) !== resolution _str ) {
_ _resolution = state . streamer . source . resolution ;
}
if ( state . features . resolution ) {
let el = $ ( "stream-resolution-selector" ) ;
if ( ! state . limits . available _resolutions . includes ( resolution _str ) ) {
state . limits . available _resolutions . push ( resolution _str ) ;
}
tools . selector . setValues ( el , state . limits . available _resolutions ) ;
tools . selector . setSelectedValue ( el , resolution _str ) ;
tools . el . setEnabled ( el , true ) ;
}
} else {
tools . el . setEnabled ( $ ( "stream-quality-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-h264-bitrate-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-h264-gop-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-desired-fps -slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-resolution-selector" ) , false ) ;
$ ( "stream-resolution-selector" ) . options . length = 0 ;
}
if ( has _janus ) {
tools . slider . setRange ( $ ( "stream-h264-bitrate -slider" ) , l . h264 _bitrate . min , l . h264 _bitrate . max ) ;
tools . slider . setRange ( $ ( "stream-h264-gop-slider" ) , l . h264 _gop . min , l . h264 _gop . max ) ;
}
_ _streamer . ensureStream ( state . streamer ) ;
// tools.feature.setEnabled($("stream-quality"), f.quality); // Only on s.encoder.quality
tools . feature . setEnabled ( $ ( "stream-resolution" ) , f . resolution ) ;
tools . feature . setEnabled ( $ ( "stream-h264-bitrate" ) , has _janus ) ;
tools . feature . setEnabled ( $ ( "stream-h264-gop" ) , has _janus ) ;
tools . feature . setEnabled ( $ ( "stream-mode" ) , has _janus ) ;
if ( ! has _janus ) {
tools . feature . setEnabled ( $ ( "stream-audio" ) , false ) ;
}
} else {
_ _streamer . stopStream ( ) ;
let mode = ( has _janus ? tools . storage . get ( "stream.mode" , "janus" ) : "mjpeg" ) ;
tools . radio . clickValue ( "stream-mode-radio" , mode ) ;
}
if ( state . streamer !== undefined ) {
let ok = ( state . streamer !== null ) ;
if ( ok ) {
let s = state . streamer ;
_ _res = s . source . resolution ;
{
let res = ` ${ _ _res . width } x ${ _ _res . height } ` ;
let el = $ ( "stream-resolution-selector" ) ;
if ( ! tools . selector . hasValue ( el , res ) ) {
tools . selector . addOption ( el , res , res ) ;
}
el . value = res ;
}
tools . slider . setValue ( $ ( "stream-quality-slider" ) , Math . max ( s . encoder . quality , 1 ) ) ;
tools . slider . setValue ( $ ( "stream-desired-fps-slider" ) , s . source . desired _fps ) ;
if ( s . h264 && s . h264 . bitrate ) {
tools . slider . setValue ( $ ( "stream-h264-bitrate-slider" ) , s . h264 . bitrate ) ;
tools . slider . setValue ( $ ( "stream-h264-gop-slider" ) , s . h264 . gop ) ; // Following together with gop
}
tools . feature . setEnabled ( $ ( "stream-quality" ) , ( s . encoder . quality > 0 ) ) ;
_ _streamer . ensureStream ( s ) ;
}
_ _setControlsEnabled ( ok ) ;
}
} ;
@@ -223,16 +246,24 @@ export function Streamer() {
$ ( "stream-led" ) . title = "Stream inactive" ;
} ;
var _ _setControlsEnabled = function ( enabled ) {
tools . el . setEnabled ( $ ( "stream-quality-slider" ) , enabled ) ;
tools . el . setEnabled ( $ ( "stream-desired-fps-slider" ) , enabled ) ;
tools . el . setEnabled ( $ ( "stream-resolution-selector" ) , enabled ) ;
tools . el . setEnabled ( $ ( "stream-h264-bitrate-slider" ) , enabled ) ;
tools . el . setEnabled ( $ ( "stream-h264-gop-slider" ) , enabled ) ;
} ;
var _ _setInfo = function ( is _active , online , text ) {
$ ( "stream-box" ) . classList . toggle ( "stream-box-offline" , ! online ) ;
let el _grab = document . querySelector ( "#stream-window-header .window-grab" ) ;
let el _info = $ ( "stream-info" ) ;
let title = ` ${ _ _streamer . getName ( ) } – ` ;
let title = ` ${ _ _streamer . getName ( ) } - ` ;
if ( is _active ) {
if ( ! online ) {
title += "No signal / " ;
}
title += _ _makeStringResolution ( _ _resolution ) ;
title += ` ${ _ _res . width } x ${ _ _res . height } ` ;
if ( text . length > 0 ) {
title += " / " + text ;
}
@@ -243,12 +274,7 @@ export function Streamer() {
title += "Inactive" ;
}
}
el _grab . innerHTML = el _info . innerHTML = title ;
} ;
var _ _setLimitsAndValue = function ( el , limits , value ) {
tools . slider . setRange ( el , limits . min , limits . max ) ;
tools . slider . setValue ( el , value ) ;
el _grab . innerText = el _info . innerText = title ;
} ;
var _ _resetStream = function ( mode = null ) {
@@ -268,7 +294,7 @@ export function Streamer() {
tools . feature . setEnabled ( $ ( "stream-audio" ) , false ) ; // Enabling in stream_janus.js
}
if ( wm . isWindowVisible ( $ ( "stream-window" ) ) ) {
_ _streamer . ensureStream ( _ _state ? _ _state . streamer : null ) ;
_ _streamer . ensureStream ( ( _ _state && _ _state . streamer !== undefined ) ? _ _state . streamer : null ) ;
}
} ;
@@ -305,6 +331,12 @@ export function Streamer() {
} ;
var _ _sendParam = function ( name , value ) {
tools . el . setEnabled ( $ ( "stream-quality-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-desired-fps-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-resolution-selector" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-h264-bitrate-slider" ) , false ) ;
tools . el . setEnabled ( $ ( "stream-h264-gop-slider" ) , false ) ;
tools . httpPost ( "/api/streamer/set_params" , { [ name ] : value } , function ( http ) {
if ( http . status !== 200 ) {
wm . error ( "Can't configure stream" , http . responseText ) ;
@@ -312,9 +344,5 @@ export function Streamer() {
} ) ;
} ;
var _ _makeStringResolution = function ( resolution ) {
return ` ${ resolution . width } x ${ resolution . height } ` ;
} ;
_ _init _ _ ( ) ;
}