diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 9c87bf6f8..dbfd2e01e 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -272,7 +272,9 @@ module JamRuby music_session.connections.each do |connection| connection.tracks.each do |track| - recording.recorded_tracks << RecordedTrack.create_from_track(track, recording) + if connection.client_role != 'child' + recording.recorded_tracks << RecordedTrack.create_from_track(track, recording) + end end connection.video_sources.each do |video| diff --git a/web/app/assets/javascripts/dialog/localRecordingsDialog.js b/web/app/assets/javascripts/dialog/localRecordingsDialog.js index 2402c0023..dbca1c4c2 100644 --- a/web/app/assets/javascripts/dialog/localRecordingsDialog.js +++ b/web/app/assets/javascripts/dialog/localRecordingsDialog.js @@ -65,6 +65,8 @@ return; } + console.log("GetLocalRecordingState", localResults) + $.each(claimedRecordings, function(index, claimedRecording) { var options = { diff --git a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js index 97d746144..04c3a602d 100644 --- a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js +++ b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js @@ -10,6 +10,8 @@ var $dialog = null; var $saveVideoCheckbox = null var $uploadToYoutube = null + var timeout = null + var CLIENT_ROLE = context.JK.CLIENT_ROLE function resetForm() { // remove all display errors @@ -44,6 +46,47 @@ resetForm(); + if(context.jamClient.getClientParentChildRole() == CLIENT_ROLE.CHILD) { + + logger.debug("child client; launching preview after xfer"); + $('#recording-finished-dialog span.nowait').addClass('hidden') + $('#recording-finished-dialog span.pleasewait').removeClass('hidden') + $('#recording-finished-dialog .preview-area').css('visibility', 'hidden') + $('#recording-finished-dialog form').css('visibility', 'hidden') + waitForMixTransfer() + } + else { + console.log("normal client; launching preview immediately") + $('#recording-finished-dialog span.pleasewait').addClass('hidden') + $('#recording-finished-dialog span.nowait').removeClass('hidden') + $('#recording-finished-dialog .preview-area').css('visibility', 'visible') + $('#recording-finished-dialog form').css('visibility', 'visible') + launchPreview(); + } + + } + + + function waitForMixTransfer() { + timeout = setTimeout(function() { + console.log("checking for file transfer", window.RecordingStore.mixTransferred) + + if(window.RecordingStore.mixTransferred) { + $('#recording-finished-dialog span.pleasewait').addClass('hidden') + $('#recording-finished-dialog span.nowait').removeClass('hidden') + $('#recording-finished-dialog .preview-area').css('visibility', 'visible') + $('#recording-finished-dialog form').css('visibility', 'visible') + timeout = null + launchPreview() + } + else { + waitForMixTransfer(); + } + + }, 1000) + } + + function launchPreview() { var parentSelector = '#recording-finished-dialog div.genre-selector'; context.JK.GenreSelectorHelper.render(parentSelector); @@ -117,10 +160,12 @@ playbackControls.startMonitor(); } } - } - function afterHide() { + if(timeout) { + clearTimeout(timeout) + timeout = null + } if(recording && recording.video) { var name = $('#recording-finished-dialog form input[name=name]').val(); name = name.replace(/[^A-Za-z0-9\-\ ]/g, ''); diff --git a/web/app/assets/javascripts/playbackControls.js b/web/app/assets/javascripts/playbackControls.js index 1ad2b3aea..43f8c02d3 100644 --- a/web/app/assets/javascripts/playbackControls.js +++ b/web/app/assets/javascripts/playbackControls.js @@ -496,7 +496,10 @@ monitoring = false; logger.debug("playbackControl.stopMonitor") if (monitorPlaybackTimeout != null) { - clearTimeout(monitorPlaybackTimeout); + if(clearTimeout) { + clearTimeout(monitorPlaybackTimeout); + } + monitorPlaybackTimeout = null; } } diff --git a/web/app/assets/javascripts/react-components/PopupMediaControls.js.jsx.coffee b/web/app/assets/javascripts/react-components/PopupMediaControls.js.jsx.coffee index 3f4dc1230..327ef1007 100644 --- a/web/app/assets/javascripts/react-components/PopupMediaControls.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/PopupMediaControls.js.jsx.coffee @@ -716,7 +716,6 @@ mixins.push(Reflux.listenTo(UserStore, 'onUserChanged')) setTimeout(@resizeWindow, 1000) shouldComponentUpdate: () -> - console.log("THIS UNLOADED", @unloaded) return !@unloaded resizeWindow: () => diff --git a/web/app/assets/javascripts/react-components/PopupRecordingStartStop.js.jsx.coffee b/web/app/assets/javascripts/react-components/PopupRecordingStartStop.js.jsx.coffee index 8c9092b1e..d9c0ad6ce 100644 --- a/web/app/assets/javascripts/react-components/PopupRecordingStartStop.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/PopupRecordingStartStop.js.jsx.coffee @@ -36,6 +36,10 @@ if accessOpener # this.setState(chatMixer: mixers.chatMixer) onRecordingStateChanged: (recordingState) -> + if @unloaded + #console.log("PopupMediaControls unloaded. ignore onMixersChnaged") + return + this.setState(isRecording: recordingState.isRecording, recordedOnce: this.state.recordedOnce || recordingState.isRecording) startStopRecording: () -> @@ -165,6 +169,9 @@ if accessOpener ` windowUnloaded: () -> + @unloaded = true + window.unloaded = true + window.opener.RecordingActions.recordingControlsClosed() onChatHelp: (e) -> @@ -215,6 +222,9 @@ if accessOpener $root = jQuery(this.getDOMNode()) $includeChat = $root.find('#include-chat') + shouldComponentUpdate: () -> + return !@unloaded + resizeWindow: () => $container = $('#minimal-container') width = $container.width() diff --git a/web/app/assets/javascripts/react-components/SessionSelfVolumeHover.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionSelfVolumeHover.js.jsx.coffee index 68ddde797..f2e91c536 100644 --- a/web/app/assets/javascripts/react-components/SessionSelfVolumeHover.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionSelfVolumeHover.js.jsx.coffee @@ -81,7 +81,7 @@ MixerActions = @MixerActions
Volume
{monitorVolumeLeft}dB
- +
@@ -108,7 +108,7 @@ MixerActions = @MixerActions
Volume
{chatVolumeLeft}dB
- +
diff --git a/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee index fffdd03c4..f0c331233 100644 --- a/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionStatsHover.js.jsx.coffee @@ -180,6 +180,8 @@ StatsInfo = { framesize = '?' if audio.framesize == 1.0 framesize = '1 ms' + else if audio.framesize == 2.0 + framesize = '1 ms' else if audio.framesize == 2.5 framesize = '2.5 ms' else if audio.framesize == 5 @@ -242,7 +244,11 @@ StatsInfo = { onStatsChanged: (stats) -> stats = window.SessionStatsStore.stats if stats? - clientStats = stats[@props.participant.client_id] + if stats.parent? + # if we have a parent, then use stats from the JamBlaster (parent), not ourselves. Otherwise we'll get bad stats (no Audio etc) + clientStats = stats.parent[@props.participant.client_id] + else + clientStats = stats[@props.participant.client_id] else clientStats = null @setState({stats: clientStats}) diff --git a/web/app/assets/javascripts/react-components/SessionTrackGain.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionTrackGain.js.jsx.coffee index 000d176c7..aa2781b65 100644 --- a/web/app/assets/javascripts/react-components/SessionTrackGain.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionTrackGain.js.jsx.coffee @@ -8,6 +8,7 @@ MIX_MODES = context.JK.MIX_MODES propTypes: { gainType: React.PropTypes.string + controlGroup: React.PropTypes.string } getInitialState: () -> @@ -22,12 +23,11 @@ MIX_MODES = context.JK.MIX_MODES mixers = @state.mixers.mixer - # if this is a media track, jam track , or media category, affect volume of both mixer and opposing mixer if @state.mixers.mixer.group_id == ChannelGroupIds.MediaTrackGroup || @state.mixers.mixer.group_id == ChannelGroupIds.JamTrackGroup || ((@state.mixers.mixer.group_id == ChannelGroupIds.MonitorCatGroup || @state.mixers.mixer.group_id == ChannelGroupIds.MasterCatGroup) && @state.mixers.mixer.name == CategoryGroupIds.MediaTrack) - MixerActions.faderChanged(data, [@state.mixers.mixer, @state.mixers.oppositeMixer], @props.gainType) + MixerActions.faderChanged(data, [@state.mixers.mixer, @state.mixers.oppositeMixer], @props.gainType, @props.controlGroup) else - MixerActions.faderChanged(data, mixers, @props.gainType) + MixerActions.faderChanged(data, mixers, @props.gainType, @props.controlGroup) render: () -> # mixer can be a single item or array diff --git a/web/app/assets/javascripts/react-components/actions/RecordingActions.js.coffee b/web/app/assets/javascripts/react-components/actions/RecordingActions.js.coffee index f6b111ac9..ad49fc0ca 100644 --- a/web/app/assets/javascripts/react-components/actions/RecordingActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/RecordingActions.js.coffee @@ -11,4 +11,5 @@ context = window abortedRecording: {} openRecordingControls: {} recordingControlsClosed: {} + mixTransferred: {} }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee b/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee index 3c358b5b1..a475caad5 100644 --- a/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee +++ b/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee @@ -730,26 +730,43 @@ MIX_MODES = context.JK.MIX_MODES; originalVolume - faderChanged: (data, mixers, gainType) -> + faderChanged: (data, mixers, gainType, controlGroup) -> mixers = [mixers] unless $.isArray(mixers) originalVolume = @getOriginalVolume(mixers, gainType) - for mixer in mixers - broadcast = !(data.dragging) # If fader is still dragging, don't broadcast - mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast) + if controlGroup? + mixers = [mixers[0]] - relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack) + for mixer in mixers + broadcast = !(data.dragging) # If fader is still dragging, don't broadcast + mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast) - @setMixerVolume(mixer, data.percentage, relative, originalVolume) + relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack) - # keep state of mixer in sync with backend - mixer = @getMixer(mixer.id, mixer.mode) - mixer.volume_left = context.trackVolumeObject.volL + @setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup) - #if groupId == ChannelGroupIds.UserMusicInputGroup - # # there may be other mixers with this same ID in the case of a Peer Music Stream, so update them as well - # context.JK.FaderHelpers.setFaderValue(mixerId, data.percentage) + # keep state of mixer in sync with backend + mixer = @getMixer(mixer.id, mixer.mode) + mixer.volume_left = context.trackVolumeObject.volL + + else + + for mixer in mixers + broadcast = !(data.dragging) # If fader is still dragging, don't broadcast + mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast) + + relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack) + + @setMixerVolume(mixer, data.percentage, relative, originalVolume) + + # keep state of mixer in sync with backend + mixer = @getMixer(mixer.id, mixer.mode) + mixer.volume_left = context.trackVolumeObject.volL + + #if groupId == ChannelGroupIds.UserMusicInputGroup + # # there may be other mixers with this same ID in the case of a Peer Music Stream, so update them as well + # context.JK.FaderHelpers.setFaderValue(mixerId, data.percentage) initGain: (mixer) -> if $.isArray(mixer) @@ -792,7 +809,7 @@ MIX_MODES = context.JK.MIX_MODES; mixer = @getMixer(mixer.id, mixer.mode) mixer.loop = context.trackVolumeObject.loop - setMixerVolume: (mixer, volumePercent, relative, originalVolume) -> + setMixerVolume: (mixer, volumePercent, relative, originalVolume, controlGroup) -> ### // The context.trackVolumeObject has been filled with the mixer values // that go with mixerId, and the range of that mixer @@ -822,7 +839,15 @@ MIX_MODES = context.JK.MIX_MODES; else context.trackVolumeObject.volL = newVolume context.trackVolumeObject.volR = newVolume - context.jamClient.SessionSetControlState(mixer.id, mixer.mode); + if controlGroup? + + if mixer.mode == MIX_MODES.PERSONAL + controlGroupsArg = 0 + else + controlGroupsArg = 1 + context.jamClient.setSessionMixerCategoryPlayoutState(controlGroup == 'music', controlGroupsArg); + else + context.jamClient.SessionSetControlState(mixer.id, mixer.mode); percentFromMixerValue: (min, max, value) -> try diff --git a/web/app/assets/javascripts/react-components/stores/CallbackStore.js.coffee b/web/app/assets/javascripts/react-components/stores/CallbackStore.js.coffee index 65bb1d115..f5b81df87 100644 --- a/web/app/assets/javascripts/react-components/stores/CallbackStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/CallbackStore.js.coffee @@ -1,6 +1,7 @@ $ = jQuery context = window logger = context.JK.logger +RecordingActions = @RecordingActions SessionActions = @SessionActions JamBlasterActions = @JamBlasterActions @@ -27,6 +28,9 @@ JamBlasterActions = @JamBlasterActions JamBlasterActions.pairState(map) else if map.cmd == 'jamblaster_tracks_updated' JamBlasterActions.jamblasterTracksUpdated() + else if map.cmd == 'file_xfer_from_parent' + if map.filename && map.filename.indexOf('RT-mix.wav') > -1 + RecordingActions.mixTransferred() } ) diff --git a/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee b/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee index 5f097b3bc..7518f8735 100644 --- a/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee @@ -148,9 +148,9 @@ rest = context.JK.Rest() # simulate a state change to cause a UI redraw @issueChange() - onFaderChanged: (data, mixers, gainType) -> + onFaderChanged: (data, mixers, gainType, controlGroup) -> - @mixers.faderChanged(data, mixers, gainType) + @mixers.faderChanged(data, mixers, gainType, controlGroup) @issueChange() diff --git a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee index 682d8744e..70e49ee33 100644 --- a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee @@ -33,10 +33,11 @@ BackendToFrontendFPS = { this.trigger({isRecording: @recordingModel.isRecording()}) onStartRecording: (recordVideo, recordChat) -> - - frameRate = context.jamClient.GetCurrentVideoFrameRate() || 0; - - frameRate = BackendToFrontendFPS[frameRate] + frameRate = 0 + if recordVideo + if context.jamClient.GetCurrentVideoFrameRate? + frameRate = context.jamClient.GetCurrentVideoFrameRate() || 0; + frameRate = BackendToFrontendFPS[frameRate] NoVideoRecordActive = 0 WebCamRecordActive = 1 @@ -49,12 +50,14 @@ BackendToFrontendFPS = { onStartingRecording: (details) -> details.cause = 'starting' + @mixTransferred = false this.trigger(details) @popupRecordingControls() unless @recordingWindow? onStartedRecording: (details) -> details.cause = 'started' + @mixTransferred = false this.trigger(details) @popupRecordingControls() unless @recordingWindow? @@ -92,6 +95,9 @@ BackendToFrontendFPS = { logger.debug("recording controls closed") @recordingWindow = null + onMixTransferred: () -> + @mixTransferred = true + popupRecordingControls: () -> logger.debug("poupRecordingControls") @recordingWindow = window.open("/popups/recording-controls", 'Recording', 'scrollbars=yes,toolbar=no,status=no,height=315,width=340') diff --git a/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee index 7ba9f931b..30c8e2f26 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStatsStore.js.coffee @@ -158,6 +158,7 @@ AggregateThresholds = SessionStatThresholds.aggregate container[participant.id] = participant + return container changed: () -> @clientsWithAudio = {} diff --git a/web/app/views/dialogs/_recordingFinishedDialog.html.haml b/web/app/views/dialogs/_recordingFinishedDialog.html.haml index 2fadd425c..17f324423 100644 --- a/web/app/views/dialogs/_recordingFinishedDialog.html.haml +++ b/web/app/views/dialogs/_recordingFinishedDialog.html.haml @@ -4,8 +4,11 @@ = image_tag "content/recordbutton-off.png", {:height => 20, :width => 20, :class => 'content-icon'} %h1 recording finished .dialog-inner - Fill out the fields below and click the "SAVE" button to save this recording to your library. If you do not want to - keep the recording, click the "DISCARD" button. + %span.nowait + Fill out the fields below and click the "SAVE" button to save this recording to your library. If you do not want to + keep the recording, click the "DISCARD" button. + %span.pleasewait + Please wait while we transfer the necessary audio files from your JamBlaster to your client... %br/ %br/ %form.left.w40.mr20 @@ -36,7 +39,7 @@ %input{:checked => "checked", :name => "is_public", :type => "checkbox"}/ %label{:for => "is_public"} Public Recording / < - .left.w50.ml30 + .left.w50.ml30.preview-area Preview Recording: \#{render "clients/play_controls"}