Non propone più il link MLTV per sessioni YouTube; la pagina /live reindirizza a YouTube; il relay verso YouTube si riavvia al connect. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
3.2 KiB
Ruby
84 lines
3.2 KiB
Ruby
module Public
|
||
class LiveController < SiteBaseController
|
||
include MediamtxPlayback
|
||
|
||
layout "marketing_live"
|
||
|
||
ACTIVE_STATUSES = %w[live connecting reconnecting].freeze
|
||
|
||
def index
|
||
@query = params[:q].to_s.strip
|
||
@club = Club.find_by(id: params[:club_id]) if params[:club_id].present?
|
||
team_ids = @club&.teams&.pluck(:id)
|
||
|
||
sessions = StreamSession
|
||
.broadcasting
|
||
.publicly_listed
|
||
.where(platform: "matchlivetv")
|
||
.includes(:score_state, match: { team: :club })
|
||
sessions = sessions.joins(:match).where(matches: { team_id: team_ids }) if team_ids.present?
|
||
|
||
@sessions = sessions
|
||
.search_by_team_or_opponent(@query)
|
||
.order(Arel.sql("started_at DESC NULLS LAST"), created_at: :desc)
|
||
|
||
# Solo dirette già in onda: le partite «programmate» restano visibili anche se c’è sessione idle.
|
||
broadcasting_match_ids = StreamSession.broadcasting.select(:match_id)
|
||
upcoming = Match.scheduled_for_live.includes(team: :club)
|
||
upcoming = upcoming.where(team_id: team_ids) if team_ids.present?
|
||
|
||
@upcoming_matches = upcoming
|
||
.search_teams_or_opponents(@query)
|
||
.where.not(id: broadcasting_match_ids)
|
||
.order(scheduled_at: :asc)
|
||
.limit(50)
|
||
|
||
@online_paths = Mediamtx::Client.new.online_path_names
|
||
|
||
return unless logged_in? && @club
|
||
|
||
@schedulable_teams = current_user.schedulable_teams_for(@club)
|
||
@can_schedule_match = @schedulable_teams.any?
|
||
end
|
||
|
||
def show
|
||
@session = StreamSession.includes(match: { team: :club }).find(params[:id])
|
||
@session = Mediamtx::PublisherSync.new(@session).call unless @session.terminal?
|
||
@match = @session.match
|
||
@stream_closed = @session.terminal?
|
||
@on_air = !@stream_closed && mediamtx_stream_playable?(@session)
|
||
@publisher_online = !@stream_closed && mediamtx_publisher_online?(@session)
|
||
end
|
||
|
||
def status
|
||
# Mai cache: il tabellone deve restare allineato con l'app (poll ogni ~1,5s).
|
||
response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate"
|
||
response.headers["Pragma"] = "no-cache"
|
||
|
||
session = StreamSession.includes(match: { team: :club }).find(params[:id])
|
||
session = Mediamtx::PublisherSync.new(session).call unless session.terminal?
|
||
closed = session.terminal?
|
||
publisher_online = !closed && mediamtx_publisher_online?(session)
|
||
playable = !closed && mediamtx_stream_playable?(session)
|
||
render json: {
|
||
status: session.status,
|
||
paused: session.paused?,
|
||
stream_closed: closed,
|
||
live: !closed && (
|
||
session.live? || session.paused? || session.connecting? || session.reconnecting? ||
|
||
mediamtx_publisher_online?(session)
|
||
),
|
||
on_air: playable,
|
||
publisher_online: publisher_online,
|
||
awaiting_signal: !closed && !mediamtx_path_has_output?(session),
|
||
showing_cover: !closed && mediamtx_path_has_output?(session) &&
|
||
(session.paused? || !mediamtx_publisher_online?(session)),
|
||
ended_at: session.ended_at,
|
||
home_name: session.match.team.name,
|
||
away_name: session.match.opponent_name,
|
||
score: session.score_state&.as_cable_payload
|
||
}
|
||
end
|
||
end
|
||
end
|