Files
MatchLiveTv/backend/app/channels/session_channel.rb
Emiliano Frascaro ab9cb02083 Aggiunge overlay server-side burn-in e stabilizza diretta live.
Tabellone, badge e brand sono ricodificati nel flusso _air via OverlayRelay;
sync punteggio HTTP, volume condiviso rails/sidekiq, qualità 720p migliorata
e badge CONNECTING in ripresa da pausa.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 23:55:17 +02:00

89 lines
2.2 KiB
Ruby

class SessionChannel < ApplicationCable::Channel
include CableBroadcastable
def subscribed
session = resolve_session
reject unless session && session.id.to_s == params[:session_id].to_s
stream_for session
session.device_states.find_or_create_by!(device_role: params[:device_role] || "controller")
end
def resolve_session
if connection.regia_session
connection.regia_session
else
StreamSession.joins(match: :team)
.merge(connection.current_user.manageable_teams)
.find_by(id: params[:session_id])
end
end
def unsubscribed
stop_all_streams
end
def receive(data)
session = resolve_session
return unless session
handle_message(session, data)
end
private
def handle_message(session, data)
case data["type"]
when "command"
SessionChannel.broadcast_message(session, data)
execute_command(session, data)
when "score_update"
update_score(session, data)
when "timeout"
update_timeout(session, data)
when "device_state"
update_device(session, data)
end
end
def execute_command(session, data)
case data["action"]
when "start_stream"
Sessions::Start.new(session).call
when "stop_stream"
Sessions::Stop.new(session).call
when "pause_stream"
Sessions::Pause.new(session).call
when "resume_stream"
Sessions::Resume.new(session).call
end
end
def update_score(session, data)
Scoring::SyncState.new(session: session, payload: data).call
end
def update_timeout(session, data)
score = session.score_state
return unless score
if data["team"] == "home"
score.update!(timeout_home: true)
else
score.update!(timeout_away: true)
end
SessionChannel.broadcast_message(session, { type: "timeout", team: data["team"] })
end
def update_device(session, data)
state = session.device_states.find_or_initialize_by(device_role: data["device_role"] || "camera")
state.update!(
battery_level: data["battery"],
network_type: data["network"],
current_bitrate: data["bitrate"],
fps: data["fps"],
last_seen_at: Time.current
)
SessionChannel.broadcast_message(session, state.as_cable_payload)
end
end