jam-cloud/web/app/assets/javascripts/react-components/stores/WebcamViewer.js.jsx.coffee

320 lines
9.2 KiB
CoffeeScript

context = window
logger = context.JK.logger
reactContext = if window.opener? then window.opener else window
# make sure this is actually us opening the window, not someone else (by checking for MixerStore)
if window.opener?
try
m = window.opener.MixerStore
catch e
reactContext = window
VideoStore = reactContext.VideoStore
VideoActions = reactContext.VideoActions
ALERT_NAMES = context.JK.ALERT_NAMES;
BackendToFrontend = {
1 : "CIF (352x288)",
2 : "VGA (640x480)",
3 : "4CIF (704x576)",
4 : "1/2 720p HD (640x360)",
5 : "720p HD (1280x720)",
6 : "1080p HD (1920x1080)"
}
BackendNumericToBackendString = {
1 : "CIF (352X288)",
2 : "VGA (640X480)",
3 : "4CIF (704X576)",
4 : "1/2WHD (640X360)",
5 : "WHD (1280X720)",
6 : "FHD (1920x1080)"
}
BackendToFrontendFPS = {
1: 30,
2: 24,
3: 20,
4: 15,
5: 10
}
FrontendToBackend = {}
for key, value of BackendToFrontend
FrontendToBackend[value] = key
mixins = []
mixins.push(Reflux.listenTo(VideoStore, 'onVideoStateChanged'))
@WebcamViewer = React.createClass({
mixins: mixins
logger: context.JK.logger
getInitialState: () ->
{
currentDevice: null
deviceNames: {}
deviceCaps: null
currentResolution: 0
currentFrameRate: 0
encodeResolutions: {}
frameRates: {}
rescanning: false
}
onVideoStateChanged: (changes) ->
@setState(changes)
render: () ->
if @props.showBackBtn
backBtn = `<a className="hidden button-grey back-btn" onClick={this.back}>BACK</a>`
selectedDevice = this.selectedDeviceName(@state)
# build list of webcams
webcams = []
context._.each @state.deviceNames, (deviceName, deviceGuid) ->
selected = deviceName == selectedDevice
webcams.push `<option key={deviceGuid} value={deviceGuid} selected={selected}>{deviceName}</option>`
# build list of capture resolutions
captureResolutions = []
# load current settings from backend
currentResolution = @state.currentResolution
currentFrameRate = @state.currentFrameRate
# protect against non-video clients pointed at video-enabled server from getting into a session
resolutions = @state.encodeResolutions
frames = @state.frameRates
@logger.debug 'FOUND THESE RESOLUTIONS', resolutions
@logger.debug 'FOUND THESE FPS', frames
context._.each resolutions, (resolution, resolutionKey, obj) =>
#{1: "CIF (352X288)", 2: "VGA (640X480)", 3: "4CIF (704X576)", 4: "1/2WHD (640X360)", 5: "WHD (1280X720)", 6: "FHD (1920x1080)"}
context._.each frames, (frame, key, obj) =>
frontendResolution = BackendToFrontend[resolutionKey]
@logger.error("unknown resolution! #{resolution}", BackendToFrontend) unless frontendResolution
value = "#{resolutionKey}|#{frame}"
text = "#{frontendResolution} at #{frame} fps"
selected = currentResolution + '|' + currentFrameRate == value
captureResolutions.push `<option key={value} value={value} selected={selected}>{text}</option>`
autoSelect = false
if currentResolution == 0
@logger.warn("current resolution not specified; defaulting to VGA")
autoSelect = true
currentResolution = 2
if currentFrameRate == 0
autoSelect = true
@logger.warn("current frame rate not specified; defaulting to 30")
currentFrameRate = 30
else
convertedFrameRate = BackendToFrontendFPS[currentFrameRate]
@logger.debug("translating FPS: backend numeric #{currentFrameRate} to #{convertedFrameRate}")
currentFrameRate = convertedFrameRate
# backend needs to be same as frontend
if autoSelect
@updateBackend(currentResolution, currentFrameRate)
if @state.videoShared
toggleText = 'STOP WEBCAM'
else
toggleText = 'TEST WEBCAM'
if @state.rescanning
rescanning =
`<span className="rescanning-notice">
<span className="spinner-small" />
CHECKING GEAR
</span>`
`<form className="video">
<h2 className="sub-header select-webcam">select webcam:</h2>
<div className="webcam-select-container wizard_control">
<select onChange={this.selectWebcam}>
{webcams}
</select>
</div>
<h2 className="sub-header select-resolution">select video capture resolution & frame rate:</h2>
<div className="webcam-resolution-select-container wizard_control">
<select onChange={this.selectResolution}>
{captureResolutions}
</select>
<a className="ftue-video-settings-help">[?]</a>
</div>
<div className="configure-webcam wizard_control">
{backBtn}
<a className="button-orange webcam-test-btn" onClick={this.toggleWebcam}>{toggleText}</a>
</div>
{rescanning}
</form>`
componentDidMount: () ->
if @props.isVisible
@beforeShow()
$root = $(@getDOMNode())
$videoSettingsHelp = $root.find('.ftue-video-settings-help')
context.JK.helpBubble($videoSettingsHelp, 'ftue-video-settings', {}, {width:300}) if $videoSettingsHelp.length > 0
$videoSettingsHelp.click(false)
componentWillUpdate: (nextProps, nextState) ->
# protect against non-video clients pointed at video-enabled server from getting into a session
@logger.debug("webcam devices", nextState.deviceNames, @state.deviceNames)
if !@initialScan?
@initialScan = true
else
@findChangedWebcams(nextState.deviceNames, @state.deviceNames)
componentWillReceiveProps:(nextProps) ->
if nextProps.isVisible
@beforeShow()
else
@beforeHide()
beforeShow:() ->
VideoActions.refresh()
VideoActions.stopVideo()
context.JK.onBackendEvent(ALERT_NAMES.USB_CONNECTED, 'webcam-viewer', @onUsbDeviceConnected);
context.JK.onBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'webcam-viewer', @onUsbDeviceDisconnected);
beforeHide: () ->
context.JK.offBackendEvent(ALERT_NAMES.USB_CONNECTED, 'webcam-viewer', @onUsbDeviceConnected);
context.JK.offBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'webcam-viewer', @onUsbDeviceDisconnected);
if @rescanTimeout?
clearTimeout(@rescanTimeout)
@rescanTimeout = null
@setVideoOff()
onUsbDeviceConnected: () ->
# don't handle USB events when minimized
#return if !context.jamClient.IsFrontendVisible()
logger.debug("USB device connected")
@scheduleRescanSystem(3000)
onUsbDeviceDisconnected:() ->
# don't handle USB events when minimized
#return if !context.jamClient.IsFrontendVisible()
logger.debug("USB device disconnected")
@scheduleRescanSystem(3000)
scheduleRescanSystem: (time) ->
if @rescanTimeout?
clearTimeout(@rescanTimeout)
@rescanTimeout = null
@setState({rescanning: true})
@rescanTimeout = setTimeout(() =>
@setState({rescanning: false})
VideoActions.refresh()
, time)
selectWebcam:(e) ->
e.preventDefault()
device = $(e.target).val()
VideoActions.selectDevice(device, {})
updateBackend: (selectedResolution, selectedFps) ->
@logger.debug 'Selecting webcam resolution: ', selectedResolution
@logger.debug 'Selecting webcam fps: ', selectedFps
VideoActions.setVideoEncodeResolution(selectedResolution)
VideoActions.setSendFrameRate(selectedFps)
selectResolution:(e) ->
e.preventDefault()
resolution = $(e.target).val()
@logger.debug 'new capture resolution selected: ' + resolution
if resolution?
bits = resolution.split('|')
selectedResolution = bits[0]
selectedFps = bits[1]
@updateBackend(selectedResolution, selectedFps)
setVideoOff:() ->
VideoActions.stopVideo()
back: () =>
window.location = '/client#/account'
toggleWebcam:(e) ->
e.preventDefault()
$toggleBtn = $(e.target)
VideoActions.toggleVideo()
#if this.isVideoShared()
# $toggleBtn.removeClass("selected")
# VideoActions.stopVideo()
# @setState({videoShared: false})
#else
# $toggleBtn.addClass("selected")
# VideoActions.startVideo()
# @setState({videoShared: true})
selectedDeviceName:(state) ->
webcamName="None Configured"
# protect against non-video clients pointed at video-enabled server from getting into a session
webcam = state.currentDevice
@logger.debug("currently selected video device", webcam)
if (webcam? && Object.keys(webcam).length>0)
webcamName = Object.keys(webcam)[0]
webcamName
findChangedWebcams: (newList, oldList) ->
newKeys = Object.keys(newList)
oldKeys = Object.keys(oldList)
webcamSelect = $(@getDOMNode()).find('.webcam-select-container select')
if newKeys.length > oldKeys.length
for newKey in newKeys
if oldKeys.indexOf(newKey) == -1
newWebcam = newList[newKey]
@logger.debug("new webcam found: " + newWebcam, newKey)
context.JK.prodBubble(webcamSelect, 'new-webcam-found', {name: newWebcam}, {positions:['right']})
break
else if newKeys.length < oldKeys.length
for oldKey in oldKeys
if newKeys.indexOf(oldKey) == -1
oldWebcam = oldList[oldKey]
@logger.debug("webcam no longer found: " + oldWebcam)
context.JK.prodBubble(webcamSelect, 'old-webcam-lost', {name: oldWebcam}, {positions:['right']})
break
}
)