$ = jQuery context = window logger = context.JK.logger rest = context.JK.Rest() EVENTS = context.JK.EVENTS MIX_MODES = context.JK.MIX_MODES SessionActions = @SessionActions MixerActions = @MixerActions SessionStatThresholds = gon.session_stat_thresholds NetworkThresholds = SessionStatThresholds.network SystemThresholds = SessionStatThresholds.system AudioThresholds = SessionStatThresholds.audio AggregateThresholds = SessionStatThresholds.aggregate @SessionStatsStore = Reflux.createStore( { listenables: @SessionStatsActions rawStats: null, parentStats: null clientsWithAudio: null init: -> # Register with the app store to get @app this.listenTo(context.AppStore, this.onAppInit) onAppInit: (@app) -> onPushStats: (stats, parentStats) -> @rawStats = stats @parentStats = parentStats @changed() classify: (holder, field, threshold) -> value = holder[field] fieldLevel = field + '_level' fieldThreshold = threshold[field] if value? && fieldThreshold? if fieldThreshold.inverse if fieldThreshold.zero_is_good holder[fieldLevel] = 'good' else if value <= fieldThreshold.poor holder[fieldLevel] = 'poor' @participantClassification = 3 else if value <= fieldThreshold.warn holder[fieldLevel] = 'warn' @participantClassification = 2 if @participantClassification == 1 else holder[fieldLevel] = 'good' else if fieldThreshold.eql if value == fieldThreshold.poor holder[fieldLevel] = 'poor' @participantClassification = 3 else if value == fieldThreshold.warn holder[fieldLevel] = 'warn' @participantClassification = 2 if @participantClassification == 1 else holder[fieldLevel] = 'good' else if value >= fieldThreshold.poor holder[fieldLevel] = 'poor' @participantClassification = 3 else if value >= fieldThreshold.warn holder[fieldLevel] = 'warn' @participantClassification = 2 if @participantClassification == 1 else holder[fieldLevel] = 'good' classifyStats: (statBag) -> container = {} self = null for participant in statBag if participant.id == @app.clientId self = participant break for participant in statBag aggregate = {} @participantClassification = 1 # 1=good, 2=warn, 3=poor total_latency = 0 if participant.cpu? system = {cpu: participant.cpu} @classify(system, 'cpu', SystemThresholds) participant.system = system 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) @classify(network, 'audio_bitrate_tx', NetworkThresholds) @classify(network, 'video_rtpbw_tx', NetworkThresholds) @classify(network, 'video_rtpbw_rx', NetworkThresholds) @classify(network, 'ping', NetworkThresholds) @classify(network, 'pkt_loss', NetworkThresholds) @classify(network, 'wifi', NetworkThresholds) total_latency += network.ping / 2 total_latency += network.audiojq_median * 2.5 aggregate.one_way = network.ping / 2 aggregate.jq = network.audiojq_median * 2.5 if network.using_ars_path == 0 network.ars_vs_p2p = 'P2P' if network.preferred_path == 'p2p' network.ars_vs_p2p_level = 'good' else network.ars_vs_p2p_level = 'warn' else network.ars_vs_p2p = 'ARS' if network.preferred_path == 'p2p' network.ars_vs_p2p_level = 'warn' else network.ars_vs_p2p_level = 'good' console.log("NETWORK!", network) else total_latency = null audio = participant.audio if audio? if audio.cpu? system = {cpu: audio.cpu} @classify(system, 'cpu', SystemThresholds) participant.system = system if audio.in_latency? and audio.out_latency? audio.latency = audio.in_latency + audio.out_latency @classify(audio, 'framesize', AudioThresholds) @classify(audio, 'latency', AudioThresholds) @classify(audio, 'input_jitter', AudioThresholds) @classify(audio, 'output_jitter', AudioThresholds) @classify(audio, 'audio_in_type', AudioThresholds) if total_latency != null total_latency += audio.out_latency total_latency += self.audio.in_latency aggregate.their_out_latency = audio.out_latency aggregate.your_in_latency = self.audio.in_latency else total_latency = null if participant.id != @app.clientId aggregate.latency = total_latency @classify(aggregate, 'latency', AggregateThresholds) participant.aggregate = aggregate switch @participantClassification when 1 then participant.classification = 'good' when 2 then participant.classification = 'warn' when 3 then participant.classification = 'poor' else participant.classification = 'unknown' 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) } )