module Youtube # Crea broadcast/stream YouTube e avvia relay (operazione lenta, ~20s). class SetupBroadcast class Error < StandardError; end def self.call(session, youtube_channel: nil) new(session, youtube_channel: youtube_channel).call end # Nuova broadcast se YouTube ha chiuso la precedente (auto_stop / ingest perso). def self.recreate!(session, youtube_channel: nil) new(session, youtube_channel: youtube_channel).recreate! end def initialize(session, youtube_channel: nil) @session = session @youtube_channel = youtube_channel end def recreate! @session.reload return @session if @session.terminal? return @session unless @session.platform == "youtube" Streams::YoutubeRelay.stop(@session) @session.update!( youtube_broadcast_id: nil, youtube_stream_id: nil, stream_key: nil, rtmp_url: nil ) call end def call @session.reload return @session if @session.terminal? return @session if @session.platform != "youtube" return @session if @session.youtube_broadcast_id.present? yt = BroadcastService.new(@session.match.team, youtube_channel: @youtube_channel) title = "#{@session.match.team.name} vs #{@session.match.opponent_name}" broadcast = yt.create_broadcast!( title: title, privacy_status: @session.privacy_status, scheduled_at: @session.match.scheduled_at ) @session.update!( youtube_broadcast_id: broadcast[:broadcast_id], youtube_stream_id: broadcast[:stream_id], stream_key: broadcast[:stream_key], rtmp_url: broadcast[:rtmp_url] ) # Relay solo quando _air pubblica (overlay pronto); altrimenti ffmpeg esce subito. if Streams::OverlayRelay.running?(@session.id) Streams::YoutubeRelay.start(@session) end @session.stream_events.create!( event_type: "youtube_ready", metadata: { broadcast_id: broadcast[:broadcast_id] }, occurred_at: Time.current ) SessionChannel.broadcast_message( @session, { type: "youtube_ready", youtube_watch_url: @session.youtube_watch_url, share_url: @session.share_url, youtube_broadcast_id: @session.youtube_broadcast_id } ) @session rescue BroadcastService::Error => e @session.stream_events.create!( event_type: "error", metadata: { source: "youtube_setup", message: e.message }, occurred_at: Time.current ) raise Error, e.message end end end