module Sessions class Create def self.normalize_privacy(value) value.to_s == "public" ? "public" : "unlisted" end def initialize(user:, match:, params:) @user = user @match = match @params = params end def call platform = @params[:platform].presence || "matchlivetv" ent = @match.team.entitlements ent.assert_can_stream_on!(platform) ent.assert_concurrent_stream! session = StreamSession.new( match: @match, user: @user, platform: platform, privacy_status: Sessions::Create.normalize_privacy(@params[:privacy_status]), quality_preset: @params[:quality_preset] || "720p_30_2.5mbps", target_bitrate: @params[:target_bitrate] || 2_500_000, target_fps: @params[:target_fps] || 30, status: "idle" ) youtube_channel = nil if session.platform == "youtube" youtube_channel = @params[:youtube_channel].presence assert_youtube_channel!(youtube_channel) end StreamSession.transaction do session.save! Scoring::Engine.ensure_score_for(session) mtx = Mediamtx::Client.new mtx.create_path(session) log_event(session, "pairing", { created: true, platform: session.platform }) end if session.platform == "youtube" YoutubeBroadcastSetupJob.perform_later(session.id, youtube_channel) end session end private def assert_youtube_channel!(youtube_channel) resolver = Youtube::CredentialResolver.new(@match.team, channel: youtube_channel) if resolver.resolve.blank? raise Teams::EntitlementError.new( "Canale YouTube selezionato non disponibile", code: "youtube_channel_unavailable" ) end end def attach_youtube_broadcast!(session, youtube_channel: nil) Youtube::SetupBroadcast.call(session, youtube_channel: youtube_channel) end def log_event(session, type, metadata) session.stream_events.create!(event_type: type, metadata: metadata, occurred_at: Time.current) end end end