Compare commits

..
6 changed files with 102 additions and 31 deletions
@@ -15,7 +15,16 @@ module Recordings
result = Recordings::VerifyYoutubeReplay.new(recording).call result = Recordings::VerifyYoutubeReplay.new(recording).call
if result.ok? if result.ok?
recording.reload
embeddable = recording.metadata.is_a?(Hash) && recording.metadata.dig("youtube", "embeddable") != false
if embeddable
Recordings::ClearTemporaryMediaJob.perform_async(recording.id, "verified") Recordings::ClearTemporaryMediaJob.perform_async(recording.id, "verified")
else
Rails.logger.warn(
"[Recordings::VerifyYoutubeReplayJob] keep_temp recording=#{recording.id} " \
"youtube_not_embeddable"
)
end
return return
end end
@@ -46,10 +46,11 @@ module Recordings
return Result.new(status: :pending, message: "vod_not_ready") return Result.new(status: :pending, message: "vod_not_ready")
end end
info = enable_embed_if_needed!(info)
apply_verified!(info) apply_verified!(info)
Rails.logger.info( Rails.logger.info(
"[Recordings::VerifyYoutubeReplay] ok recording=#{@recording.id} " \ "[Recordings::VerifyYoutubeReplay] ok recording=#{@recording.id} " \
"youtube_video_id=#{info.video_id}" "youtube_video_id=#{info.video_id} embeddable=#{info.embeddable}"
) )
Result.new(status: :ok, message: "verified") Result.new(status: :ok, message: "verified")
rescue Youtube::VodStatus::Error => e rescue Youtube::VodStatus::Error => e
@@ -68,6 +69,7 @@ module Recordings
"thumbnail_url" => info.thumbnail_url, "thumbnail_url" => info.thumbnail_url,
"privacy_status" => info.privacy_status, "privacy_status" => info.privacy_status,
"upload_status" => info.upload_status, "upload_status" => info.upload_status,
"embeddable" => info.embeddable,
"verified_via" => "live_broadcast" "verified_via" => "live_broadcast"
).compact ).compact
@@ -82,5 +84,23 @@ module Recordings
@recording.update!(attrs) @recording.update!(attrs)
end end
def enable_embed_if_needed!(info)
return info if info.embeddable != false
return info if info.video_id.to_s.start_with?("mock_")
session = @recording.stream_session
Youtube::BroadcastService.new(session.match.team).enable_video_embed!(
info.video_id,
privacy_status: info.privacy_status
)
refreshed = Youtube::VodStatus.new(@recording.team, channel: "team").fetch(info.video_id)
refreshed.ready ? refreshed : info
rescue Youtube::BroadcastService::Error, Youtube::VodStatus::Error => e
Rails.logger.warn(
"[Recordings::VerifyYoutubeReplay] enable_embed recording=#{@recording.id}: #{e.message}"
)
info
end
end end
end end
@@ -97,6 +97,24 @@ module Youtube
:skipped :skipped
end end
def enable_video_embed!(video_id, privacy_status: "unlisted")
return if video_id.blank? || video_id.to_s.start_with?("mock_")
return if @credential.blank? || missing_oauth_config?
client = authorized_client
video = Google::Apis::YoutubeV3::Video.new(
id: video_id,
status: Google::Apis::YoutubeV3::VideoStatus.new(
embeddable: true,
privacy_status: privacy_status.presence || "unlisted",
self_declared_made_for_kids: false
)
)
client.update_video("status", video)
rescue Google::Apis::Error => e
raise Error, e.message
end
def complete_broadcast!(broadcast_id) def complete_broadcast!(broadcast_id)
return if broadcast_id.blank? return if broadcast_id.blank?
return if @credential.blank? || missing_oauth_config? return if @credential.blank? || missing_oauth_config?
+5 -2
View File
@@ -13,6 +13,7 @@ module Youtube
:thumbnail_url, :thumbnail_url,
:privacy_status, :privacy_status,
:upload_status, :upload_status,
:embeddable,
keyword_init: true keyword_init: true
) )
@@ -32,7 +33,8 @@ module Youtube
duration_secs: nil, duration_secs: nil,
thumbnail_url: nil, thumbnail_url: nil,
privacy_status: "unlisted", privacy_status: "unlisted",
upload_status: "processed" upload_status: "processed",
embeddable: true
) )
end end
@@ -51,7 +53,8 @@ module Youtube
duration_secs: parse_duration(item.content_details&.duration), duration_secs: parse_duration(item.content_details&.duration),
thumbnail_url: item.snippet&.thumbnails&.high&.url || item.snippet&.thumbnails&.default&.url, thumbnail_url: item.snippet&.thumbnails&.high&.url || item.snippet&.thumbnails&.default&.url,
privacy_status: item.status&.privacy_status, privacy_status: item.status&.privacy_status,
upload_status: upload_status upload_status: upload_status,
embeddable: item.status&.embeddable != false
) )
rescue Google::Apis::Error => e rescue Google::Apis::Error => e
raise Error, e.message raise Error, e.message
+27 -27
View File
@@ -14,33 +14,6 @@
<h2><%= t("replay.show.processing_title") %></h2> <h2><%= t("replay.show.processing_title") %></h2>
<p><%= t("replay.show.processing_body") %></p> <p><%= t("replay.show.processing_body") %></p>
</div> </div>
<% elsif @recording.ready? && @recording.replay_source == "youtube" && @recording.youtube_video_id.present? && !@recording.youtube_video_id.to_s.start_with?("mock_") %>
<div class="live-player-wrap live-player-wrap--embed">
<iframe src="https://www.youtube.com/embed/<%= @recording.youtube_video_id %>"
title="<%= @recording.title_or_default %>"
class="live-player-embed"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
<%= render "public/live/player_overlays",
match: @match,
session: @session,
stream_closed: true,
on_air: false,
badge_label: t("replay.show.badge_label"),
badge_class: "badge-ended" %>
</div>
<p class="replay-show__meta-line">
<%= l_local(@recording.recorded_at_or_fallback) %>
· <%= t("replay.show.meta_line_duration", value: @recording.duration_label) %>
· <%= @recording.views_label %>
<% if @recording.source_platform_label != "—" %>
· <%= @recording.source_platform_label %>
<% end %>
</p>
<p class="replay-show__meta-line">
<%= t("replay.show.youtube_only_body") %>
<%= link_to t("replay.show.youtube_link"), @recording.youtube_watch_url, target: "_blank", rel: "noopener" %>
</p>
<% elsif @recording.ready? && @recording.storage_key.present? %> <% elsif @recording.ready? && @recording.storage_key.present? %>
<div class="live-player-wrap"> <div class="live-player-wrap">
<video id="replay-player" controls playsinline preload="metadata" <video id="replay-player" controls playsinline preload="metadata"
@@ -80,6 +53,33 @@
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<% elsif @recording.ready? && @recording.replay_source == "youtube" && @recording.youtube_video_id.present? && !@recording.youtube_video_id.to_s.start_with?("mock_") %>
<div class="live-player-wrap live-player-wrap--embed">
<iframe src="https://www.youtube.com/embed/<%= @recording.youtube_video_id %>"
title="<%= @recording.title_or_default %>"
class="live-player-embed"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
<%= render "public/live/player_overlays",
match: @match,
session: @session,
stream_closed: true,
on_air: false,
badge_label: t("replay.show.badge_label"),
badge_class: "badge-ended" %>
</div>
<p class="replay-show__meta-line">
<%= l_local(@recording.recorded_at_or_fallback) %>
· <%= t("replay.show.meta_line_duration", value: @recording.duration_label) %>
· <%= @recording.views_label %>
<% if @recording.source_platform_label != "—" %>
· <%= @recording.source_platform_label %>
<% end %>
</p>
<p class="replay-show__meta-line">
<%= t("replay.show.youtube_only_body") %>
<%= link_to t("replay.show.youtube_link"), @recording.youtube_watch_url, target: "_blank", rel: "noopener" %>
</p>
<% elsif @recording.ready? %> <% elsif @recording.ready? %>
<div class="stream-ended" role="status"> <div class="stream-ended" role="status">
<h2><%= t("replay.show.file_missing_title") %></h2> <h2><%= t("replay.show.file_missing_title") %></h2>
@@ -57,4 +57,25 @@ RSpec.describe "Public replay show youtube-only", type: :request do
expect(response.body).to include("id=\"replay-player\"") expect(response.body).to include("id=\"replay-player\"")
expect(response.body).not_to include("youtube.com/embed/") expect(response.body).not_to include("youtube.com/embed/")
end end
it "preferisce il player MP4 locale se la copia temporanea YouTube è ancora presente" do
Recording.create!(
stream_session: session,
team: team,
status: "ready",
storage_policy: "temporary",
storage_key: "temporary_replays/teams/#{team.id}/sessions/#{session.id}/replay.mp4",
youtube_video_id: "publicYtVid01",
youtube_verified_at: Time.current,
privacy_status: "unlisted",
title: "Derby temp",
expires_at: nil,
metadata: { "source_platform" => "youtube" }
)
get "/replay/#{session.id}"
expect(response).to have_http_status(:ok)
expect(response.body).to include("id=\"replay-player\"")
expect(response.body).not_to include("youtube.com/embed/publicYtVid01")
end
end end