2024-06-14 19:40:07 -04:00
/ * B l a c k m a g i c C a m e r a C o n t r o l W e b U I
WebUI Script functions
( c ) Dylan Speiser 2024
github . com / DylanSpeiser
* /
2024-06-11 19:46:25 -04:00
2024-06-13 19:49:36 -04:00
2024-06-14 19:40:07 -04:00
/* Global variables */
var cameras = [ ] ; // Array to store all of the camera objects
var ci = 0 ; // Index into this array for the currently selected camera.
// cameras[ci] is used to reference the currently selected camera object
2024-06-11 19:46:25 -04:00
2024-06-14 19:40:07 -04:00
var WBMode = 0 ; // 0: balance, 1: tint
2024-06-11 19:46:25 -04:00
2024-07-02 17:53:25 -04:00
var defaultControlsHTML ;
2024-07-02 20:04:53 -04:00
var unsavedChanges = [ ] ;
2024-06-14 19:40:07 -04:00
// Set everything up
function bodyOnLoad ( ) {
2024-07-02 17:53:25 -04:00
defaultControlsHTML = document . getElementById ( "allCamerasContainer" ) . innerHTML ;
2024-06-11 19:46:25 -04:00
}
2024-07-02 17:53:25 -04:00
// Checks the hostname, if it replies successfully then a new BMCamera object
2024-06-14 19:40:07 -04:00
// is made and gets put in the array at ind
2024-07-02 17:53:25 -04:00
function initCamera ( ) {
// Get hostname from Hostname text field
let hostname = document . getElementById ( "hostnameInput" ) . value ;
try {
// Check if the hostname is valid
let response = sendRequest ( "GET" , "http://" + hostname + "/control/api/v1/system" , "" ) ;
2024-06-13 17:46:46 -04:00
if ( response . status < 300 ) {
2024-06-14 19:40:07 -04:00
// Success, make a new camera, get all relevant info, and populate the UI
2024-07-02 17:53:25 -04:00
cameras [ ci ] = new BMCamera ( hostname ) ;
cameras [ ci ] . updateUI = updateUIAll ;
cameras [ ci ] . active = true ;
2024-06-14 19:40:07 -04:00
document . getElementById ( "connectionErrorSpan" ) . innerHTML = "Connected." ;
document . getElementById ( "connectionErrorSpan" ) . setAttribute ( "style" , "color: #6e6e6e;" ) ;
2024-06-13 17:46:46 -04:00
} else {
2024-06-14 19:40:07 -04:00
// Something has gone wrong, tell the user
2024-06-13 17:46:46 -04:00
document . getElementById ( "connectionErrorSpan" ) . innerHTML = response . statusText ;
}
2024-07-02 17:53:25 -04:00
} catch ( error ) {
2024-06-14 19:40:07 -04:00
// Something has gone wrong, tell the user
2024-06-13 17:46:46 -04:00
document . getElementById ( "connectionErrorSpan" ) . title = error ;
document . getElementById ( "connectionErrorSpan" ) . innerHTML = "Error " + error . code + ": " + error . name + " (Your hostname is probably incorrect, hover for more details)" ;
2024-07-02 17:53:25 -04:00
}
2024-06-13 17:46:46 -04:00
}
2024-07-02 17:53:25 -04:00
// =============================== UI Updater ==================================
// =============================================================================
2024-06-14 19:40:07 -04:00
function updateUIAll ( ) {
2024-07-02 17:53:25 -04:00
// ========== Camera Name ==========
2024-06-14 19:40:07 -04:00
document . getElementById ( "cameraName" ) . innerHTML = cameras [ ci ] . name ;
2024-07-02 17:53:25 -04:00
// ========== Hostname ==========
2024-06-14 19:40:07 -04:00
document . getElementById ( "hostnameInput" ) . value = cameras [ ci ] . hostname ;
2024-07-02 17:53:25 -04:00
// ========== Format ==========
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
document . getElementById ( "formatCodec" ) . innerHTML = cameras [ ci ] . propertyData [ '/system/format' ] ? . codec . toUpperCase ( ) . replace ( ":" , " " ) . replace ( "_" , ":" ) ;
let resObj = cameras [ ci ] . propertyData [ '/system/format' ] ? . recordResolution ;
document . getElementById ( "formatResolution" ) . innerHTML = resObj ? . width + "x" + resObj ? . height ;
document . getElementById ( "formatFPS" ) . innerHTML = cameras [ ci ] . propertyData [ '/system/format' ] ? . frameRate + " fps" ;
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== Recording State ==========
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
if ( cameras [ ci ] . propertyData [ '/transports/0/record' ] ? . recording ) {
2024-06-14 19:40:07 -04:00
document . getElementById ( "cameraControlHeadContainer" ) . classList . add ( "liveCam" ) ;
document . getElementById ( "cameraControlExpandedHeadContainer" ) . classList . add ( "liveCam" ) ;
} else {
document . getElementById ( "cameraControlHeadContainer" ) . classList . remove ( "liveCam" ) ;
document . getElementById ( "cameraControlExpandedHeadContainer" ) . classList . remove ( "liveCam" ) ;
}
2024-07-02 20:04:53 -04:00
// ========== Playback Loop State ==========
let loopState = cameras [ ci ] . propertyData [ '/transports/0/playback' ] ? . loop ;
let singleClipState = cameras [ ci ] . propertyData [ '/transports/0/playback' ] ? . singleClip ;
let loopButton = document . getElementById ( "loopButton" ) ;
let singleClipButton = document . getElementById ( "singleClipButton" ) ;
if ( loopState ) {
loopButton . classList . add ( "activated" ) ;
} else {
loopButton . classList . remove ( "activated" ) ;
}
if ( singleClipState ) {
singleClipButton . classList . add ( "activated" ) ;
} else {
singleClipButton . classList . remove ( "activated" ) ;
}
2024-07-02 17:53:25 -04:00
// ========== Timecode ==========
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
document . getElementById ( "timecodeLabel" ) . innerHTML = parseTimecode ( cameras [ ci ] . propertyData [ '/transports/0/timecode' ] ? . timecode ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== Presets Dropdown ==========
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "presets" ) ) {
2024-07-02 17:53:25 -04:00
2024-07-02 20:04:53 -04:00
var presetsList = document . getElementById ( "presetsDropDown" ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
presetsList . innerHTML = "" ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
cameras [ ci ] . propertyData [ '/presets' ] ? . presets . forEach ( ( presetItem ) => {
let presetName = presetItem . split ( '.' , 1 ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
let textNode = document . createTextNode ( presetName ) ;
let optionNode = document . createElement ( "option" ) ;
optionNode . setAttribute ( "name" , "presetOption" + presetName ) ;
optionNode . appendChild ( textNode ) ;
document . getElementById ( "presetsDropDown" ) . appendChild ( optionNode ) ;
} ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== Active Preset ==========
2024-07-02 20:04:53 -04:00
var presetsList = document . getElementById ( "presetsDropDown" ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
presetsList . childNodes . forEach ( ( child ) => {
if ( child . nodeName == 'OPTION' && ( child . value + ".cset" ) == cameras [ ci ] . propertyData [ '/presets/active' ] ? . preset ) {
child . selected = true
} else {
child . selected = false
}
} )
}
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== Iris ==========
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
document . getElementById ( "irisRange" ) . value = cameras [ ci ] . propertyData [ '/lens/iris' ] ? . normalised ;
document . getElementById ( "apertureStopsLabel" ) . innerHTML = cameras [ ci ] . propertyData [ '/lens/iris' ] ? . apertureStop . toFixed ( 1 ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== Zoom ==========
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
document . getElementById ( "zoomRange" ) . value = cameras [ ci ] . propertyData [ '/lens/zoom' ] ? . normalised ;
document . getElementById ( "zoomMMLabel" ) . innerHTML = cameras [ ci ] . propertyData [ '/lens/zoom' ] ? . focalLength + "mm" ;
// ========== Focus ==========
document . getElementById ( "focusRange" ) . value = cameras [ ci ] . propertyData [ '/lens/focus' ] ? . normalised ;
// ========== ISO ==========
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "ISO" ) ) {
if ( cameras [ ci ] . propertyData [ '/video/iso' ] )
document . getElementById ( "ISOInput" ) . value = cameras [ ci ] . propertyData [ '/video/iso' ] ? . iso ;
}
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== GAIN ==========
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "Gain" ) ) {
let gainString = "" ;
let gainInt = cameras [ ci ] . propertyData [ '/video/gain' ] ? . gain
2024-07-02 17:53:25 -04:00
2024-07-02 20:04:53 -04:00
if ( gainInt >= 0 ) {
gainString = "+" + gainInt + "db"
} else {
gainString = gainInt + "db"
}
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
document . getElementById ( "gainSpan" ) . innerHTML = gainString ;
}
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ========== WHITE BALANCE ===========
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "WB" ) ) {
document . getElementById ( "whiteBalanceSpan" ) . innerHTML = cameras [ ci ] . propertyData [ '/video/whiteBalance' ] ? . whiteBalance + "K" ;
}
if ( ! unsavedChanges . includes ( "WBT" ) ) {
document . getElementById ( "whiteBalanceTintSpan" ) . innerHTML = cameras [ ci ] . propertyData [ '/video/whiteBalanceTint' ] ? . whiteBalanceTint ;
}
2024-07-02 17:53:25 -04:00
// =========== ND =============
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "ND" ) ) {
if ( cameras [ ci ] . propertyData [ '/video/ndFilter' ] ) {
document . getElementById ( "ndFilterSpan" ) . innerHTML = cameras [ ci ] . propertyData [ '/video/ndFilter' ] ? . stop ;
} else {
document . getElementById ( "ndFilterSpan" ) . innerHTML = 0 ;
document . getElementById ( "ndFilterSpan" ) . disabled = true ;
}
2024-06-14 19:40:07 -04:00
}
2024-07-02 17:53:25 -04:00
// ============ Shutter =====================
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "Shutter" ) ) {
let shutterString = "SS"
let shutterObj = cameras [ ci ] . propertyData [ '/video/shutter' ] ;
if ( shutterObj ? . shutterSpeed ) {
shutterString = "1/" + shutterObj . shutterSpeed
} else if ( shutterObj ? . shutterAngle ) {
var shangleString = ( shutterObj . shutterAngle / 100 ) . toFixed ( 1 ) . toString ( )
if ( shangleString . indexOf ( ".0" ) > 0 ) {
shutterString = parseFloat ( shangleString ) . toFixed ( 0 ) + "°" ;
} else {
shutterString = shangleString + "°" ;
}
2024-06-14 19:40:07 -04:00
}
2024-07-02 20:04:53 -04:00
document . getElementById ( "shutterSpan" ) . innerHTML = shutterString ;
}
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// =========== Auto Exposure Mode ===========
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "AutoExposure" ) ) {
let AEmodeSelect = document . getElementById ( "AEmodeDropDown" ) ;
let AEtypeSelect = document . getElementById ( "AEtypeDropDown" ) ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
AEmodeSelect . value = cameras [ ci ] . propertyData [ '/video/autoExposure' ] ? . mode ;
AEtypeSelect . value = cameras [ ci ] . propertyData [ '/video/autoExposure' ] ? . type ;
}
2024-07-02 17:53:25 -04:00
// =========== COLOR CORRECTION =============
2024-06-14 19:40:07 -04:00
// Lift
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC0" ) ) {
let liftProps = cameras [ ci ] . propertyData [ '/colorCorrection/lift' ] ;
document . getElementsByClassName ( "CClumaLabel" ) [ 0 ] . innerHTML = liftProps ? . luma . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCredLabel" ) [ 0 ] . innerHTML = liftProps ? . red . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCgreenLabel" ) [ 0 ] . innerHTML = liftProps ? . green . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCblueLabel" ) [ 0 ] . innerHTML = liftProps ? . blue . toFixed ( 2 ) ;
}
2024-06-14 19:40:07 -04:00
// Gamma
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC1" ) ) {
let gammaProps = cameras [ ci ] . propertyData [ '/colorCorrection/gamma' ] ;
document . getElementsByClassName ( "CClumaLabel" ) [ 1 ] . innerHTML = gammaProps ? . luma . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCredLabel" ) [ 1 ] . innerHTML = gammaProps ? . red . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCgreenLabel" ) [ 1 ] . innerHTML = gammaProps ? . green . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCblueLabel" ) [ 1 ] . innerHTML = gammaProps ? . blue . toFixed ( 2 ) ;
}
2024-06-14 19:40:07 -04:00
// Gain
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC2" ) ) {
let gainProps = cameras [ ci ] . propertyData [ '/colorCorrection/gain' ] ;
document . getElementsByClassName ( "CClumaLabel" ) [ 2 ] . innerHTML = gainProps ? . luma . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCredLabel" ) [ 2 ] . innerHTML = gainProps ? . red . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCgreenLabel" ) [ 2 ] . innerHTML = gainProps ? . green . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCblueLabel" ) [ 2 ] . innerHTML = gainProps ? . blue . toFixed ( 2 ) ;
}
2024-06-14 19:40:07 -04:00
// Offset
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC3" ) ) {
let offsetProps = cameras [ ci ] . propertyData [ '/colorCorrection/offset' ] ;
document . getElementsByClassName ( "CClumaLabel" ) [ 3 ] . innerHTML = offsetProps ? . luma . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCredLabel" ) [ 3 ] . innerHTML = offsetProps ? . red . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCgreenLabel" ) [ 3 ] . innerHTML = offsetProps ? . green . toFixed ( 2 ) ;
document . getElementsByClassName ( "CCblueLabel" ) [ 3 ] . innerHTML = offsetProps ? . blue . toFixed ( 2 ) ;
}
2024-06-14 19:40:07 -04:00
// Contrast
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC4" ) ) {
let constrastProps = cameras [ ci ] . propertyData [ '/colorCorrection/contrast' ] ;
document . getElementById ( "CCcontrastPivotRange" ) . value = constrastProps ? . pivot ;
document . getElementById ( "CCcontrastPivotLabel" ) . innerHTML = constrastProps ? . pivot . toFixed ( 2 ) ;
document . getElementById ( "CCcontrastAdjustRange" ) . value = constrastProps ? . adjust ;
document . getElementById ( "CCcontrastAdjustLabel" ) . innerHTML = parseInt ( constrastProps ? . adjust * 50 ) + "%" ;
}
2024-06-14 19:40:07 -04:00
// Color
2024-07-02 20:04:53 -04:00
if ( ! unsavedChanges . includes ( "CC5" ) ) {
let colorProps = cameras [ ci ] . propertyData [ '/colorCorrection/color' ] ;
document . getElementById ( "CChueRange" ) . value = colorProps ? . hue ;
document . getElementById ( "CCcolorHueLabel" ) . innerHTML = parseInt ( ( colorProps ? . hue + 1 ) * 180 ) + "°" ;
document . getElementById ( "CCsaturationRange" ) . value = colorProps ? . saturation ;
document . getElementById ( "CCcolorSatLabel" ) . innerHTML = parseInt ( colorProps ? . saturation * 50 ) + "%" ;
2024-06-14 19:40:07 -04:00
2024-07-02 20:04:53 -04:00
let lumaContributionProps = cameras [ ci ] . propertyData [ '/colorCorrection/lumaContribution' ] ;
document . getElementById ( "CClumaContributionRange" ) . value = lumaContributionProps ? . lumaContribution ;
document . getElementById ( "CCcolorLCLabel" ) . innerHTML = parseInt ( lumaContributionProps ? . lumaContribution * 100 ) + "%" ;
}
2024-06-14 19:40:07 -04:00
2024-07-02 17:53:25 -04:00
// ============ Footer Links ===============
2024-06-14 19:40:07 -04:00
document . getElementById ( "documentationLink" ) . href = "http://" + cameras [ ci ] . hostname + "/control/documentation.html" ;
document . getElementById ( "mediaManagerLink" ) . href = "http://" + cameras [ ci ] . hostname ;
}
// ==============================================================================
2024-07-02 17:53:25 -04:00
// Called when the user changes tabs to a different camera
function switchCamera ( index ) {
2024-06-12 20:18:19 -04:00
if ( cameras [ ci ] ) {
2024-07-02 17:53:25 -04:00
cameras [ ci ] . active = false ;
2024-06-12 20:18:19 -04:00
}
2024-06-11 19:46:25 -04:00
2024-06-12 20:18:19 -04:00
ci = index ;
2024-07-02 17:53:25 -04:00
// Reset the Controls
document . getElementById ( "allCamerasContainer" ) . innerHTML = defaultControlsHTML ;
// Update the UI
2024-06-12 20:18:19 -04:00
for ( var i = 0 ; i < 8 ; i ++ ) {
if ( i == ci ) {
document . getElementsByClassName ( "cameraSwitchLabel" ) [ i ] . classList . add ( "selectedCam" ) ;
} else {
document . getElementsByClassName ( "cameraSwitchLabel" ) [ i ] . classList . remove ( "selectedCam" ) ;
}
}
document . getElementById ( "cameraNumberLabel" ) . innerHTML = "CAM" + ( ci + 1 ) ;
2024-06-13 19:49:36 -04:00
document . getElementById ( "cameraName" ) . innerHTML = "CAMERA NAME" ;
2024-07-02 17:53:25 -04:00
if ( cameras [ ci ] ) {
cameras [ ci ] . active = true ;
}
2024-06-12 20:18:19 -04:00
}
2024-06-14 19:40:07 -04:00
// For not-yet-implemented Color Correction UI
2024-06-12 20:18:19 -04:00
function setCCMode ( mode ) {
if ( mode == 0 ) {
// Lift
} else if ( mode == 1 ) {
// Gamma
} else {
// Gain
}
for ( var i = 0 ; i < 3 ; i ++ ) {
if ( i == mode ) {
document . getElementsByClassName ( "ccTabLabel" ) [ i ] . classList . add ( "selectedTab" ) ;
} else {
document . getElementsByClassName ( "ccTabLabel" ) [ i ] . classList . remove ( "selectedTab" ) ;
}
}
}
2024-06-14 19:40:07 -04:00
// Allows for changing WB/Tint displayed in the UI
2024-06-13 17:46:46 -04:00
function swapWBMode ( ) {
if ( WBMode == 0 ) {
// Balance
document . getElementById ( "WBLabel" ) . innerHTML = "TINT" ;
document . getElementById ( "WBValueContainer" ) . classList . add ( "dNone" ) ;
document . getElementById ( "WBTintValueContainer" ) . classList . remove ( "dNone" ) ;
WBMode = 1 ;
} else {
//Tint
document . getElementById ( "WBLabel" ) . innerHTML = "BALANCE" ;
document . getElementById ( "WBValueContainer" ) . classList . remove ( "dNone" ) ;
document . getElementById ( "WBTintValueContainer" ) . classList . add ( "dNone" ) ;
WBMode = 0 ;
}
}
2024-06-14 19:40:07 -04:00
// Triggered by the button by those text boxes. Reads the info from the inputs and sends it to the camera.
2024-06-13 17:46:46 -04:00
function manualAPICall ( ) {
const requestRadioGET = document . getElementById ( "requestTypeGET" ) ;
const requestEndpointText = document . getElementById ( "manualRequestEndpointLabel" ) . value ;
let requestData = "" ;
try {
requestData = JSON . parse ( document . getElementById ( "manualRequestBodyLabel" ) . value ) ;
} catch ( err ) {
document . getElementById ( "manualRequestResponseP" ) . innerHTML = err ;
}
const requestMethod = ( requestRadioGET . checked ? "GET" : "PUT" ) ;
const requestURL = cameras [ ci ] . APIAddress + requestEndpointText ;
2024-07-02 17:53:25 -04:00
let response = sendRequest ( requestMethod , requestURL , requestData ) ;
2024-06-12 20:18:19 -04:00
2024-07-02 17:53:25 -04:00
document . getElementById ( "manualRequestResponseP" ) . innerHTML = JSON . stringify ( response ) ;
2024-06-12 20:18:19 -04:00
}
2024-07-02 18:30:59 -04:00
/* Control Calling Functions */
/* Makes the HTML cleaner. */
function decreaseND ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/ndFilter" , { stop : cameras [ ci ] . propertyData [ '/video/ndFilter' ] . stop - 2 } ) ;
2024-07-02 18:30:59 -04:00
}
function increaseND ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/ndFilter" , { stop : cameras [ ci ] . propertyData [ '/video/ndFilter' ] . stop + 2 } ) ;
2024-07-02 18:30:59 -04:00
}
function decreaseGain ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/gain" , { gain : cameras [ ci ] . propertyData [ '/video/gain' ] . gain - 2 } ) ;
2024-07-02 18:30:59 -04:00
}
function increaseGain ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/gain" , { gain : cameras [ ci ] . propertyData [ '/video/gain' ] . gain + 2 } ) ;
2024-07-02 18:30:59 -04:00
}
function decreaseShutter ( ) {
let cam = cameras [ ci ] ;
2024-07-02 20:04:53 -04:00
if ( 'shutterSpeed' in cam . propertyData [ '/video/shutter' ] ) {
cam . PUTdata ( "/video/shutter" , { "shutterSpeed" : cam . propertyData [ '/video/shutter' ] . shutterSpeed + 10 } ) ;
2024-07-02 18:30:59 -04:00
} else {
2024-07-02 20:04:53 -04:00
cam . PUTdata ( "/video/shutter" , { "shutterAngle" : cam . propertyData [ '/video/shutter' ] . shutterAngle - 1000 } ) ;
2024-07-02 18:30:59 -04:00
}
}
function increaseShutter ( ) {
let cam = cameras [ ci ] ;
2024-07-02 20:04:53 -04:00
if ( 'shutterSpeed' in cam . propertyData [ '/video/shutter' ] ) {
cam . PUTdata ( "/video/shutter" , { "shutterSpeed" : cam . propertyData [ '/video/shutter' ] . shutterSpeed - 10 } ) ;
2024-07-02 18:30:59 -04:00
} else {
2024-07-02 20:04:53 -04:00
cam . PUTdata ( "/video/shutter" , { "shutterAngle" : cam . propertyData [ '/video/shutter' ] . shutterAngle + 1000 } ) ;
2024-07-02 18:30:59 -04:00
}
}
2024-07-02 20:04:53 -04:00
function handleShutterInput ( ) {
let inputString = document . getElementById ( "shutterSpan" ) . innerHTML ;
if ( event . key === 'Enter' ) {
let cam = cameras [ ci ] ;
2024-07-02 18:30:59 -04:00
2024-07-02 20:04:53 -04:00
if ( 'shutterSpeed' in cam . propertyData [ '/video/shutter' ] ) {
if ( inputString . indexOf ( "1/" ) >= 0 ) {
cam . PUTdata ( "/video/shutter" , { "shutterSpeed" : parseInt ( inputString . substring ( 2 ) ) } ) ;
} else {
cam . PUTdata ( "/video/shutter" , { "shutterSpeed" : parseInt ( inputString ) } ) ;
}
2024-07-02 18:30:59 -04:00
} else {
2024-07-02 20:04:53 -04:00
cam . PUTdata ( "/video/shutter" , { "shutterAngle" : parseInt ( parseFloat ( inputString ) * 100 ) } ) ;
2024-07-02 18:30:59 -04:00
}
2024-07-02 20:04:53 -04:00
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "Shutter" } ) ;
2024-07-02 18:30:59 -04:00
} else {
2024-07-02 20:04:53 -04:00
unsavedChanges . push ( 'Shutter' ) ;
2024-07-02 18:30:59 -04:00
}
}
function decreaseWhiteBalance ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/whiteBalance" , { whiteBalance : cameras [ ci ] . propertyData [ '/video/whiteBalance' ] . whiteBalance - 50 } ) ;
2024-07-02 18:30:59 -04:00
}
function increaseWhiteBalance ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/whiteBalance" , { whiteBalance : cameras [ ci ] . propertyData [ '/video/whiteBalance' ] . whiteBalance + 50 } ) ;
2024-07-02 18:30:59 -04:00
}
function decreaseWhiteBalanceTint ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/whiteBalanceTint" , { whiteBalanceTint : cameras [ ci ] . propertyData [ '/video/whiteBalanceTint' ] . whiteBalanceTint - 1 } ) ;
2024-07-02 18:30:59 -04:00
}
function increaseWhiteBalanceTint ( ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/whiteBalanceTint" , { whiteBalanceTint : cameras [ ci ] . propertyData [ '/video/whiteBalanceTint' ] . whiteBalanceTint + 1 } ) ;
}
function presetInputHandler ( ) {
let selectedPreset = document . getElementById ( "presetsDropDown" ) . value ;
cameras [ ci ] . PUTdata ( "/presets/active" , { preset : selectedPreset + ".cset" } ) ;
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "presets" } ) ;
2024-07-02 18:30:59 -04:00
}
function AEmodeInputHandler ( ) {
let AEmode = document . getElementById ( "AEmodeDropDown" ) . value ;
let AEtype = document . getElementById ( "AEtypeDropDown" ) . value ;
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/video/autoExposure" , { mode : AEmode , type : AEtype } ) ;
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "AutoExposure" } ) ;
}
function ISOInputHandler ( ) {
let ISOInput = document . getElementById ( "ISOInput" ) ;
if ( event . key === 'Enter' ) {
event . preventDefault ;
cameras [ ci ] . PUTdata ( "/video/iso" , { iso : parseInt ( ISOInput . value ) } )
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "ISO" } ) ;
} else {
unsavedChanges . push ( 'ISO' ) ;
}
}
2024-07-03 18:02:18 -04:00
// 0: lift, 1: gamma, 2: gain, 3: offset, 4: contrast, 5: color & LC
2024-07-02 20:04:53 -04:00
function CCInputHandler ( which ) {
if ( event . key === 'Enter' ) {
event . preventDefault ;
setCCFromUI ( which ) ;
} else {
unsavedChanges . push ( 'CC' + which ) ;
}
}
function NDFilterInputHandler ( ) {
if ( event . key === 'Enter' ) {
event . preventDefault ;
cameras [ ci ] . PUTdata ( "/video/ndFilter" , { stop : parseInt ( document . getElementById ( "ndFilterSpan" ) . innerHTML ) } )
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "ND" } ) ;
} else {
unsavedChanges . push ( 'ND' ) ;
}
}
function GainInputHandler ( ) {
if ( event . key === 'Enter' ) {
event . preventDefault ;
cameras [ ci ] . PUTdata ( "/video/gain" , { gain : parseInt ( document . getElementById ( "gainSpan" ) . innerHTML ) } )
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "Gain" } ) ;
} else {
unsavedChanges . push ( 'Gain' ) ;
}
}
function WBInputHandler ( ) {
if ( event . key === 'Enter' ) {
event . preventDefault ;
cameras [ ci ] . PUTdata ( "/video/whiteBalance" , { whiteBalance : parseInt ( document . getElementById ( "whiteBalanceSpan" ) . innerHTML ) } )
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "WB" } ) ;
} else {
unsavedChanges . push ( 'WB' ) ;
}
}
function WBTInputHandler ( ) {
if ( event . key === 'Enter' ) {
event . preventDefault ;
cameras [ ci ] . PUTdata ( "/video/whiteBalanceTint" , { whiteBalanceTint : parseInt ( document . getElementById ( "whiteBalanceTintSpan" ) . innerHTML ) } )
unsavedChanges = unsavedChanges . filter ( ( e ) => { return e !== "WBT" } ) ;
} else {
unsavedChanges . push ( 'WBT' ) ;
}
2024-07-02 18:30:59 -04:00
}
// 0: lift, 1: gamma, 2: gain, 3: offset
function setCCFromUI ( which ) {
2024-07-03 18:04:02 -04:00
if ( which < 4 ) {
let lumaFloat = parseFloat ( document . getElementsByClassName ( "CClumaLabel" ) [ which ] . innerHTML ) ;
let redFloat = parseFloat ( document . getElementsByClassName ( "CCredLabel" ) [ which ] . innerHTML ) ;
let greenFloat = parseFloat ( document . getElementsByClassName ( "CCgreenLabel" ) [ which ] . innerHTML ) ;
let blueFloat = parseFloat ( document . getElementsByClassName ( "CCblueLabel" ) [ which ] . innerHTML ) ;
let ccobject = { "red" : redFloat , "green" : greenFloat , "blue" : blueFloat , "luma" : lumaFloat } ;
}
2024-07-02 18:30:59 -04:00
if ( which == 0 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/lift" , ccobject ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 1 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/gamma" , ccobject ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 2 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/gain" , ccobject ) ;
2024-07-03 18:02:18 -04:00
} else if ( which == 3 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/offset" , ccobject ) ;
2024-07-03 18:02:18 -04:00
} else if ( which == 4 ) {
let pivotFloat = parseFloat ( document . getElementById ( "CCcontrastPivotLabel" ) . innerHTML ) ;
let adjustFloat = parseFloat ( document . getElementById ( "CCcontrastAdjustLabel" ) . innerHTML ) ;
cameras [ ci ] . PUTdata ( "/colorCorrection/contrast" , { pivot : pivotFloat , adjust : adjustFloat } ) ;
} else {
let hueFloat = parseFloat ( document . getElementById ( "CCcolorHueLabel" ) . innerHTML ) ;
let satFloat = parseFloat ( document . getElementById ( "CCcolorSatLabel" ) . innerHTML ) ;
let lumCoFloat = parseFloat ( document . getElementById ( "CCcolorLCLabel" ) . innerHTML ) ;
cameras [ ci ] . PUTdata ( "/colorCorrection/color" , { hue : hueFloat , saturation : satFloat } ) ;
cameras [ ci ] . PUTdata ( "/colorCorrection/lumaContribution" , { lumaContribution : lumCoFloat } ) ;
2024-07-02 18:30:59 -04:00
}
2024-07-02 20:04:53 -04:00
2024-07-03 18:02:18 -04:00
unsavedChanges = unsavedChanges . filter ( ( e ) => { return ! e . includes ( "CC" + which ) } ) ;
2024-07-02 18:30:59 -04:00
}
// Reset Color Correction Values
// 0: lift, 1: gamma, 2: gain, 3: offset, 4: contrast, 5: color & LC
function resetCC ( which ) {
if ( which == 0 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/lift" , { "red" : 0.0 , "green" : 0.0 , "blue" : 0.0 , "luma" : 0.0 } ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 1 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/gamma" , { "red" : 0.0 , "green" : 0.0 , "blue" : 0.0 , "luma" : 0.0 } ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 2 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/gain" , { "red" : 1.0 , "green" : 1.0 , "blue" : 1.0 , "luma" : 1.0 } ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 3 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/offset" , { "red" : 0.0 , "green" : 0.0 , "blue" : 0.0 , "luma" : 0.0 } ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 4 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/contrast" , { "pivot" : 0.5 , "adjust" : 1.0 } ) ;
2024-07-02 18:30:59 -04:00
} else if ( which == 5 ) {
2024-07-02 20:04:53 -04:00
cameras [ ci ] . PUTdata ( "/colorCorrection/color" , { "hue" : 0.0 , "saturation" : 1.0 } ) ;
cameras [ ci ] . PUTdata ( "/colorCorrection/lumaContribution" , { "lumaContribution" : 1.0 } ) ;
2024-07-02 18:30:59 -04:00
}
}
2024-07-02 20:04:53 -04:00
// Triggered by the Loop and Single Clip buttons
function loopHandler ( callerString ) {
let playbackState = cameras [ ci ] . propertyData [ '/transports/0/playback' ] ;
if ( callerString === "Loop" ) {
playbackState . loop = ! playbackState . loop ;
} else if ( callerString === "Single Clip" ) {
playbackState . singleClip = ! playbackState . singleClip ;
}
cameras [ ci ] . PUTdata ( "/transports/0/playback" , playbackState ) ;
}
2024-07-02 17:53:25 -04:00
/* Helper Functions */
function parseTimecode ( timecodeBCD ) {
let noDropFrame = timecodeBCD & 0b01111111111111111111111111111111 ; // The first bit of the timecode is 1 if "Drop Frame Timecode" is on. We don't want to include that in the display.
let decimalTCInt = parseInt ( noDropFrame . toString ( 16 ) , 10 ) ; // Convert the BCD number into base ten
let decimalTCString = decimalTCInt . toString ( ) . padStart ( 8 , '0' ) ; // Convert the base ten number to a string eight characters long
let finalTCString = decimalTCString . match ( /.{1,2}/g ) . join ( ':' ) ; // Put colons between every two characters
return finalTCString ;
2024-06-11 19:46:25 -04:00
}