Merge branch 'feature/jbmvp' into develop
This commit is contained in:
commit
80145a09da
|
|
@ -368,4 +368,5 @@ retailers.sql
|
|||
second_ed.sql
|
||||
second_ed_v2.sql
|
||||
retailers_v2.sql
|
||||
retailer_interest.sql
|
||||
retailer_interest.sql
|
||||
connection_role.sql
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE connections ADD COLUMN client_role VARCHAR;
|
||||
ALTER TABLE connections ADD COLUMN parent_client_id VARCHAR;
|
||||
|
|
@ -402,7 +402,7 @@ SQL
|
|||
music_session.creator
|
||||
end
|
||||
|
||||
def join_music_session(user, client_id, music_session, as_musician, tracks, audio_latency, video_sources=nil)
|
||||
def join_music_session(user, client_id, music_session, as_musician, tracks, audio_latency, client_role = nil, parent_client_id = nil, video_sources=nil)
|
||||
connection = nil
|
||||
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
|
|
@ -418,7 +418,7 @@ SQL
|
|||
raise JamPermissionError, "wrong user_id associated with connection #{client_id}"
|
||||
end
|
||||
|
||||
connection.join_the_session(music_session, as_musician, tracks, user, audio_latency, video_sources)
|
||||
connection.join_the_session(music_session, as_musician, tracks, user, audio_latency, client_role, parent_client_id, video_sources)
|
||||
JamRuby::MusicSessionUserHistory.join_music_session(user.id, music_session.id, client_id)
|
||||
# connection.music_session_id = music_session.id
|
||||
# connection.as_musician = as_musician
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ module JamRuby
|
|||
[music_sessions, user_scores]
|
||||
end
|
||||
|
||||
def self.participant_create(user, music_session_id, client_id, as_musician, tracks, audio_latency, video_sources=nil)
|
||||
def self.participant_create(user, music_session_id, client_id, as_musician, tracks, audio_latency, client_role = nil, parent_client_id = nil, video_sources=nil)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
# USERS ARE ALREADY IN SESSION
|
||||
|
|
@ -514,7 +514,7 @@ module JamRuby
|
|||
active_music_session.with_lock do # VRFS-1297
|
||||
active_music_session.tick_track_changes
|
||||
# VRFS-3986
|
||||
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, video_sources)
|
||||
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, client_role, parent_client_id, video_sources)
|
||||
|
||||
if connection.errors.any?
|
||||
# rollback the transaction to make sure nothing is disturbed in the database
|
||||
|
|
@ -573,7 +573,7 @@ module JamRuby
|
|||
|
||||
# auto-join this user into the newly created session
|
||||
as_musician = true
|
||||
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, video_sources)
|
||||
connection = ConnectionManager.new.join_music_session(user, client_id, active_music_session, as_musician, tracks, audio_latency, client_role, parent_client_id, video_sources)
|
||||
|
||||
unless connection.errors.any?
|
||||
user.update_progression_field(:first_music_session_at)
|
||||
|
|
|
|||
|
|
@ -176,11 +176,13 @@ module JamRuby
|
|||
true
|
||||
end
|
||||
|
||||
def join_the_session(music_session, as_musician, tracks, user, audio_latency, videos=nil)
|
||||
def join_the_session(music_session, as_musician, tracks, user, audio_latency, client_role = nil, parent_client_id = nil, videos=nil)
|
||||
self.music_session_id = music_session.id
|
||||
self.as_musician = as_musician == true # this is deliberate; otherwise we create a warning in one our tests that passes 'blarg' (rails warning about casting strings to false)
|
||||
self.joining_session = true
|
||||
self.joined_session_at = Time.now
|
||||
self.client_role = client_role
|
||||
self.parent_client_id = parent_client_id
|
||||
associate_tracks(tracks) unless tracks.nil?
|
||||
associate_videos(videos) unless videos.nil?
|
||||
self.save
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@
|
|||
return;
|
||||
}
|
||||
|
||||
console.log("GetLocalRecordingState", localResults)
|
||||
|
||||
$.each(claimedRecordings, function(index, claimedRecording) {
|
||||
|
||||
var options = {
|
||||
|
|
|
|||
|
|
@ -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, '');
|
||||
|
|
|
|||
|
|
@ -496,7 +496,10 @@
|
|||
monitoring = false;
|
||||
logger.debug("playbackControl.stopMonitor")
|
||||
if (monitorPlaybackTimeout != null) {
|
||||
clearTimeout(monitorPlaybackTimeout);
|
||||
if(clearTimeout) {
|
||||
clearTimeout(monitorPlaybackTimeout);
|
||||
}
|
||||
|
||||
monitorPlaybackTimeout = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ JamBlasterActions = @JamBlasterActions
|
|||
|
||||
audio: () ->
|
||||
`<div className="audio-content">
|
||||
<JamBlasterTrackConfig />
|
||||
To edit the JamBlaster audio settings, get into a session, and click the Settings link under My Tracks.
|
||||
</div>`
|
||||
|
||||
ipSettingsChanged: (key, e) ->
|
||||
|
|
|
|||
|
|
@ -716,7 +716,6 @@ mixins.push(Reflux.listenTo(UserStore, 'onUserChanged'))
|
|||
setTimeout(@resizeWindow, 1000)
|
||||
|
||||
shouldComponentUpdate: () ->
|
||||
console.log("THIS UNLOADED", @unloaded)
|
||||
return !@unloaded
|
||||
|
||||
resizeWindow: () =>
|
||||
|
|
|
|||
|
|
@ -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
|
|||
</div>`
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ ConfigureTracksActions = @ConfigureTracksActions
|
|||
$connectionState,
|
||||
'SessionStatsHover',
|
||||
() =>
|
||||
{participant: {client_id: this.props.clientId, user: name: 'You', possessive: 'Your'}, }
|
||||
{myTrack: true, participant: {client_id: this.props.connStatsClientId, user: name: 'You', possessive: 'Your'}, }
|
||||
,
|
||||
{width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'})
|
||||
|
||||
|
|
|
|||
|
|
@ -9,15 +9,29 @@ MixerActions = context.MixerActions
|
|||
session = sessionMixers.session
|
||||
mixers = sessionMixers.mixers
|
||||
noAudioUsers = mixers.noAudioUsers
|
||||
clientsWithAudioOverride = mixers.clientsWithAudioOverride
|
||||
|
||||
participants = []
|
||||
|
||||
if session.inSession()
|
||||
|
||||
self = session.getParticipant(@app.clientId)
|
||||
|
||||
myJamBlasterClientId = null
|
||||
if self? && self.client_role == 'child' && self.parent_client_id?
|
||||
myJamBlasterClientId = self.parent_client_id
|
||||
|
||||
for participant in session.otherParticipants()
|
||||
|
||||
#if participant.is_jamblaster
|
||||
#continue
|
||||
if myJamBlasterClientId? && participant.client_id == myJamBlasterClientId
|
||||
# don't show my parent jamblaster in 'others'
|
||||
continue
|
||||
|
||||
if participant.client_role == 'child' && participant.parent_client_id?
|
||||
#participant.parent = session.getParticipant(participant.parent_client_id)
|
||||
# don't show children nodes
|
||||
continue
|
||||
|
||||
|
||||
if participant.client_id == @app.clientId
|
||||
participant.user.possessive = "Your"
|
||||
|
|
@ -55,6 +69,10 @@ MixerActions = context.MixerActions
|
|||
|
||||
name = "#{name}: #{instrumentDescription}"
|
||||
|
||||
noAudio = false
|
||||
if !clientsWithAudioOverride[participant.client_id]
|
||||
noAudio = noAudioUsers[participant.client_id]
|
||||
|
||||
participantState = {
|
||||
participant: participant,
|
||||
tracks: tracks,
|
||||
|
|
@ -63,7 +81,7 @@ MixerActions = context.MixerActions
|
|||
instrumentIcon: instrumentIcon,
|
||||
photoUrl: photoUrl,
|
||||
hasMixer: hasMixer,
|
||||
noAudio: noAudioUsers[participant.client_id]
|
||||
noAudio: noAudio
|
||||
}
|
||||
|
||||
MixerActions.missingPeerMixer(participant.client_id) unless hasMixer
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ MixerActions = @MixerActions
|
|||
<div>Volume</div>
|
||||
<div>{monitorVolumeLeft}dB</div>
|
||||
</div>
|
||||
<SessionTrackGain mixers={this.state.inputGroupMixers} gainType='music' />
|
||||
<SessionTrackGain mixers={this.state.inputGroupMixers} gainType='music' controlGroup="music" />
|
||||
<div className={monitorMuteClasses} data-control="mute" onClick={this.handleAudioInputMute}/>
|
||||
|
||||
<input type="checkbox" name="mute"/>
|
||||
|
|
@ -108,7 +108,7 @@ MixerActions = @MixerActions
|
|||
<div>Volume</div>
|
||||
<div>{chatVolumeLeft}dB</div>
|
||||
</div>
|
||||
<SessionTrackGain mixers={this.state.chatGroupMixers} />
|
||||
<SessionTrackGain mixers={this.state.chatGroupMixers} controlGroup="chat" />
|
||||
<div className={chatMuteClasses} data-control="mute" onClick={this.handleChatMute}/>
|
||||
|
||||
<input type="checkbox" name="mute"/>
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ StatsInfo = {
|
|||
audio = @state.stats?.audio
|
||||
|
||||
aggregateTag = null
|
||||
if aggregate?
|
||||
if aggregate? && !this.props.myTrack
|
||||
if aggregate.latency
|
||||
aggregateStats.push(@stat(aggregate, 'aggregate', 'Tot Latency', 'latency', Math.round(aggregate.latency)))
|
||||
|
||||
|
|
@ -173,10 +173,16 @@ StatsInfo = {
|
|||
audio_type = 'WDM'
|
||||
else if audio_long.indexOf('core') > -1
|
||||
audio_type = 'CoreAudio'
|
||||
else if audio_long.indexOf('alsa') > -1
|
||||
audio_type = 'JamBlaster'
|
||||
audioStats.push(@stat(audio, 'audio', 'Gear Driver', 'audio_in_type', audio_type))
|
||||
if audio.framesize?
|
||||
framesize = '?'
|
||||
if audio.framesize == 2.5
|
||||
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
|
||||
framesize = '5 ms'
|
||||
|
|
@ -185,7 +191,7 @@ StatsInfo = {
|
|||
audioStats.push(@stat(audio, 'audio', 'Frame Size', 'framesize', framesize))
|
||||
|
||||
networkTag = null
|
||||
if network?
|
||||
if network? && !this.props.myTrack
|
||||
if network.ping?
|
||||
networkStats.push(@stat(network, 'network', 'Latency', 'ping', (network.ping / 2).toFixed(1) + ' ms'))
|
||||
if network.audiojq_median?
|
||||
|
|
@ -238,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})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ context = window
|
|||
metronomeChanged: {}
|
||||
deadUserRemove: {}
|
||||
missingPeerMixer: {}
|
||||
clientsWithAudio: {}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ context = window
|
|||
abortedRecording: {}
|
||||
openRecordingControls: {}
|
||||
recordingControlsClosed: {}
|
||||
mixTransferred: {}
|
||||
})
|
||||
|
|
@ -8,7 +8,7 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
|
||||
@MixerHelper = class MixerHelper
|
||||
|
||||
constructor: (@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixMode) ->
|
||||
constructor: (@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixMode) ->
|
||||
@mixMode = MIX_MODES.PERSONAL # TODO - remove mixMode from MixerHelper? Or at least stop using it in most functions
|
||||
@app = @session.app
|
||||
@mixersByResourceId = {}
|
||||
|
|
@ -622,13 +622,12 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
return mixerPair.personal
|
||||
|
||||
|
||||
findMixerForTrack: (client_id, track, myTrack, mode = MIX_MODES.PERSONAL) ->
|
||||
findMixerForTrack: (client_id, track, myTrack, mode) ->
|
||||
mixer = null # what is the best mixer for this track/client ID?
|
||||
oppositeMixer = null # what is the corresponding mixer in the opposite mode?
|
||||
vuMixer = null
|
||||
muteMixer = null
|
||||
|
||||
|
||||
if myTrack
|
||||
# when it's your track, look it up by the backend resource ID
|
||||
mixer = @getMixerByTrackId(track.client_track_id, mode)
|
||||
|
|
@ -674,7 +673,7 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
oppositeMixer = oppositeMixers[ChannelGroupIds.UserMusicInputGroup][0]
|
||||
|
||||
if !oppositeMixer
|
||||
logger.warn("unable to find UserMusicInputGroup corresponding to PeerAudioInputMusicGroup mixer", mixer, @personalMixers )
|
||||
logger.warn("unable to find UserMusicInputGroup corresponding to PeerAudioInputMusicGroup mixer", mixer, @personalMixers)
|
||||
|
||||
when MIX_MODES.PERSONAL
|
||||
mixers = @groupedMixersForClientId(client_id, [ ChannelGroupIds.UserMusicInputGroup], {}, MIX_MODES.PERSONAL)
|
||||
|
|
@ -693,6 +692,8 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
logger.error("personaol: found remote mixer that was not of groupID: PeerAudioInputMusicGroup", client_id, track.client_track_id, mixer)
|
||||
|
||||
#vuMixer = oppositeMixer; # for personal mode, use the PeerAudioInputMusicGroup's VUs
|
||||
else
|
||||
logger.error("no UserMusicInputGroup for client_id #{client_id} in PERSONAL mode", mixers)
|
||||
|
||||
{
|
||||
mixer: mixer,
|
||||
|
|
@ -729,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)
|
||||
|
|
@ -791,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
|
||||
|
|
@ -821,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
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ badCode = 'This is not a valid code. Please carefully re-enter the code and try
|
|||
|
||||
if errorText? && errorText.indexOf('already claimed') > -1
|
||||
errorText = 'This card has already been claimed. If you believe this is in error, please email us at support@jamkazam.com to report this problem.'
|
||||
|
||||
|
||||
buttonClassnames = classNames({'redeem-giftcard': true, 'button-orange': true, disabled: @state.processing || @state.done })
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ MIDI_TRACK = context.JK.MIDI_TRACK
|
|||
if session.inSession()
|
||||
participant = session.getParticipant(@app.clientId)
|
||||
|
||||
connStatsClientId = @app.clientId
|
||||
|
||||
if participant.client_role == 'child' && participant.parent_client_id?
|
||||
participant.parent = session.getParticipant(participant.parent_client_id)
|
||||
connStatsClientId = participant.parent_client_id
|
||||
|
||||
if participant
|
||||
photoUrl = context.JK.resolveAvatarUrl(participant.user.photo_url);
|
||||
|
||||
|
|
@ -79,7 +85,7 @@ MIDI_TRACK = context.JK.MIDI_TRACK
|
|||
associatedVst = vst
|
||||
break
|
||||
|
||||
tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, hasMixer:hasMixer, name: name, trackName: trackName, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id, associatedVst: associatedVst})
|
||||
tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, hasMixer:hasMixer, name: name, trackName: trackName, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id, associatedVst: associatedVst, connStatsClientId: connStatsClientId})
|
||||
else
|
||||
logger.warn("SessionMyTracks: unable to find participant")
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ rest = context.JK.Rest()
|
|||
checkingMissingPeers : {}
|
||||
missingMixerPeers : {}
|
||||
recheckTimeout : null
|
||||
clientsWithAudioOverride : {}
|
||||
|
||||
init: ->
|
||||
# Register with the app store to get @app
|
||||
|
|
@ -38,6 +39,7 @@ rest = context.JK.Rest()
|
|||
this.listenTo(context.MixerActions.metronomeChanged, this.onMetronomeChanged)
|
||||
this.listenTo(context.MixerActions.deadUserRemove, this.onDeadUserRemove)
|
||||
this.listenTo(context.MixerActions.missingPeerMixer, this.onMissingPeerMixer)
|
||||
this.listenTo(context.MixerActions.clientsWithAudio, this.onClientsWithAudio)
|
||||
|
||||
context.JK.HandleVolumeChangeCallback2 = @handleVolumeChangeCallback
|
||||
context.JK.HandleMetronomeCallback2 = @handleMetronomeCallback
|
||||
|
|
@ -76,7 +78,7 @@ rest = context.JK.Rest()
|
|||
# metroSound = args.sound
|
||||
SessionActions.syncWithServer()
|
||||
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
|
||||
@issueChange()
|
||||
|
||||
|
|
@ -132,7 +134,7 @@ rest = context.JK.Rest()
|
|||
@masterMixers = context.jamClient.SessionGetAllControlState(true);
|
||||
@personalMixers = context.jamClient.SessionGetAllControlState(false);
|
||||
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
|
||||
@issueChange()
|
||||
|
||||
|
|
@ -146,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()
|
||||
|
||||
|
|
@ -171,7 +173,7 @@ rest = context.JK.Rest()
|
|||
@metro.sound = sound
|
||||
context.jamClient.SessionSetMetronome(@metro.tempo, @metro.sound, 1, 0);
|
||||
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@issueChange()
|
||||
|
||||
onDeadUserRemove: (clientId) ->
|
||||
|
|
@ -193,6 +195,9 @@ rest = context.JK.Rest()
|
|||
|
||||
@issueChange()
|
||||
|
||||
onClientsWithAudio: (clients) ->
|
||||
@clientsWithAudioOverride = clients
|
||||
|
||||
onMissingPeerMixer: (clientId) ->
|
||||
|
||||
missingPeerAttempts = @missingMixerPeers[clientId]
|
||||
|
|
@ -219,7 +224,7 @@ rest = context.JK.Rest()
|
|||
@masterMixers = context.jamClient.SessionGetAllControlState(true);
|
||||
@personalMixers = context.jamClient.SessionGetAllControlState(false);
|
||||
logger.debug("MixerStore: recheckForMixers")
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@issueChange()
|
||||
|
||||
onInitGain: (mixer) ->
|
||||
|
|
@ -234,7 +239,7 @@ rest = context.JK.Rest()
|
|||
|
||||
logger.debug("MixerStore: onMixersChanged")
|
||||
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
|
||||
|
||||
SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo())
|
||||
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ EVENTS = context.JK.EVENTS
|
|||
MIX_MODES = context.JK.MIX_MODES
|
||||
|
||||
SessionActions = @SessionActions
|
||||
MixerActions = @MixerActions
|
||||
|
||||
SessionStatThresholds = gon.session_stat_thresholds
|
||||
NetworkThresholds = SessionStatThresholds.network
|
||||
|
|
@ -16,7 +17,9 @@ AggregateThresholds = SessionStatThresholds.aggregate
|
|||
@SessionStatsStore = Reflux.createStore(
|
||||
{
|
||||
listenables: @SessionStatsActions
|
||||
rawStats: null
|
||||
rawStats: null,
|
||||
parentStats: null
|
||||
clientsWithAudio: null
|
||||
|
||||
init: ->
|
||||
# Register with the app store to get @app
|
||||
|
|
@ -24,8 +27,9 @@ AggregateThresholds = SessionStatThresholds.aggregate
|
|||
|
||||
onAppInit: (@app) ->
|
||||
|
||||
onPushStats: (stats) ->
|
||||
onPushStats: (stats, parentStats) ->
|
||||
@rawStats = stats
|
||||
@parentStats = parentStats
|
||||
@changed()
|
||||
|
||||
classify: (holder, field, threshold) ->
|
||||
|
|
@ -65,17 +69,15 @@ AggregateThresholds = SessionStatThresholds.aggregate
|
|||
else
|
||||
holder[fieldLevel] = 'good'
|
||||
|
||||
|
||||
changed: () ->
|
||||
@stats = {}
|
||||
|
||||
classifyStats: (statBag) ->
|
||||
container = {}
|
||||
self = null
|
||||
for participant in @rawStats
|
||||
for participant in statBag
|
||||
if participant.id == @app.clientId
|
||||
self = participant
|
||||
break
|
||||
|
||||
for participant in @rawStats
|
||||
for participant in statBag
|
||||
|
||||
aggregate = {}
|
||||
|
||||
|
|
@ -93,6 +95,9 @@ AggregateThresholds = SessionStatThresholds.aggregate
|
|||
network = participant.network
|
||||
|
||||
if network?
|
||||
if network.audio_bitrate_rx > 0 && network.audio_bitrate_tx > 0
|
||||
@clientsWithAudio[participant.id] = true
|
||||
|
||||
@classify(network, 'audiojq_median', NetworkThresholds)
|
||||
@classify(network, 'jitter_var', NetworkThresholds)
|
||||
@classify(network, 'audio_bitrate_rx', NetworkThresholds)
|
||||
|
|
@ -151,8 +156,23 @@ AggregateThresholds = SessionStatThresholds.aggregate
|
|||
else
|
||||
participant.classification = 'unknown'
|
||||
|
||||
@stats[participant.id] = participant
|
||||
container[participant.id] = participant
|
||||
|
||||
return container
|
||||
|
||||
changed: () ->
|
||||
@clientsWithAudio = {}
|
||||
@stats = {}
|
||||
|
||||
@stats = @classifyStats(@rawStats)
|
||||
if @parentStats
|
||||
@stats.parent = @classifyStats(@parentStats)
|
||||
else
|
||||
@stats.parent = null
|
||||
|
||||
MixerActions.clientsWithAudio(@clientsWithAudio)
|
||||
|
||||
# see if we can reset noAudio
|
||||
@trigger(@stats)
|
||||
}
|
||||
)
|
||||
|
|
@ -728,8 +728,19 @@ ConfigureTracksActions = @ConfigureTracksActions
|
|||
context.jamClient.SessionRegisterCallback("JK.HandleBridgeCallback2");
|
||||
context.jamClient.RegisterRecordingCallbacks("JK.HandleRecordingStartResult", "JK.HandleRecordingStopResult", "JK.HandleRecordingStarted", "JK.HandleRecordingStopped", "JK.HandleRecordingAborted");
|
||||
context.jamClient.SessionSetConnectionStatusRefreshRate(1000);
|
||||
clientRole = context.jamClient.getClientParentChildRole();
|
||||
parentClientId = context.jamClient.getParentClientId();
|
||||
logger.debug("role when joining session: #{clientRole}, parent client id #{parentClientId}")
|
||||
#context.JK.HelpBubbleHelper.jamtrackGuideSession($screen.find('li.open-a-jamtrack'), $screen)
|
||||
|
||||
if clientRole == 0
|
||||
clientRole = 'child'
|
||||
else if clientRole == 1
|
||||
clientRole = 'parent'
|
||||
|
||||
if clientRole == '' || !clientRole
|
||||
clientRole = null
|
||||
|
||||
# subscribe to events from the recording model
|
||||
@recordingRegistration()
|
||||
|
||||
|
|
@ -741,6 +752,8 @@ ConfigureTracksActions = @ConfigureTracksActions
|
|||
as_musician: true,
|
||||
tracks: @userTracks,
|
||||
session_id: @currentSessionId,
|
||||
client_role: clientRole,
|
||||
parent_client_id: parentClientId
|
||||
audio_latency: context.jamClient.FTUEGetExpectedLatency().latency
|
||||
})
|
||||
.done((response) =>
|
||||
|
|
@ -840,8 +853,11 @@ ConfigureTracksActions = @ConfigureTracksActions
|
|||
@backendStatsInterval = window.setInterval((() => (@updateBackendStats())), 1000)
|
||||
|
||||
updateBackendStats: () ->
|
||||
connectionStats = window.jamClient.getConnectionDetail('')
|
||||
SessionStatsActions.pushStats(connectionStats)
|
||||
connectionStats = window.jamClient.getConnectionDetail('', false)
|
||||
parentConnectionStats = window.jamClient.getConnectionDetail('', true)
|
||||
#console.log("CONNECTION STATES", connectionStats)
|
||||
#console.log("PARENT STATES", parentConnectionStats)
|
||||
SessionStatsActions.pushStats(connectionStats, parentConnectionStats)
|
||||
|
||||
trackChanges: (header, payload) ->
|
||||
if @currentTrackChanges < payload.track_changes_counter
|
||||
|
|
|
|||
|
|
@ -297,7 +297,9 @@ class ApiMusicSessionsController < ApiController
|
|||
params[:client_id],
|
||||
params[:as_musician],
|
||||
params[:tracks],
|
||||
params[:audio_latency]
|
||||
params[:audio_latency],
|
||||
params[:client_role],
|
||||
params[:parent_client_id]
|
||||
)
|
||||
|
||||
if @connection.errors.any?
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ else
|
|||
|
||||
child(:connections => :participants) {
|
||||
collection @music_sessions, :object_root => false
|
||||
attributes :ip_address, :client_id, :joined_session_at, :audio_latency, :id, :metronome_open, :is_jamblaster
|
||||
attributes :ip_address, :client_id, :joined_session_at, :audio_latency, :id, :metronome_open, :is_jamblaster, :client_role, :parent_client_id
|
||||
|
||||
node :user do |connection|
|
||||
{ :id => connection.user.id, :photo_url => connection.user.photo_url, :name => connection.user.name, :is_friend => connection.user.friends?(current_user), :connection_state => connection.aasm_state }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/ <a href="#"><<img src="images/shared/icon_help.png" width="12" height="12" /></a>
|
||||
.left.w50.ml30
|
||||
.left.w50.ml30.preview-area
|
||||
Preview Recording:
|
||||
|
||||
\#{render "clients/play_controls"}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<li class="affiliate account-menu-group"><%= link_to "Affiliate Report", '/client#/account/affiliate' %></li>
|
||||
<% end %>
|
||||
<% if @nativeClient && Rails.application.config.jamblaster_menu %>
|
||||
<li class="jamblaster-config"><%= link_to "JamBlaster", '/client#/jamblaster' %></li>
|
||||
<li class="jamblaster-config"><%= link_to "JamBlaster Settings", '/client#/jamblaster' %></li>
|
||||
<% end %>
|
||||
<% if current_user && current_user.musician? %>
|
||||
<li class="band-setup"><%= link_to "Band Setup", '/client#/band/setup/new' %></li>
|
||||
|
|
|
|||
|
|
@ -740,6 +740,10 @@ module JamWebsockets
|
|||
ipv4_link_local = options["ipv4_link_local"]
|
||||
ipv6_link_local = options["ipv6_link_local"]
|
||||
|
||||
# it's nice to have client_ids not flap in the wind, and we can do that with jamblasters
|
||||
if jamblaster_serial_no && client_id.nil?
|
||||
client_id = jamblaster_serial_no
|
||||
end
|
||||
# TESTING
|
||||
#if jamblaster_serial_no.nil?
|
||||
# jamblaster_serial_no = 'hi'
|
||||
|
|
|
|||
Loading…
Reference in New Issue