Skip to content

Commit

Permalink
Implement mp4 provider for videos
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoroth committed Oct 22, 2024
1 parent 5863cb5 commit fc37a8c
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
Empty file removed app/assets/images/.keep
Empty file.
Binary file added app/assets/images/posters/fallback.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion app/javascript/controllers/video_player_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ export default class extends Controller {
playbackRateOptions = [1, 1.25, 1.5, 1.75, 2]

connect () {
const providerOptions = {}

if (this.hasProviderValue) {
providerOptions.provider = this.providerValue
}

this.player = new Vlitejs(this.playerTarget, {
provider: this.hasProviderValue ? this.providerValue : 'youtube',
...providerOptions,
options: {
poster: this.posterValue,
controls: true
Expand Down
53 changes: 42 additions & 11 deletions app/models/talk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ class Talk < ApplicationRecord
validates :language, presence: true,
inclusion: {in: Language.alpha2_codes, message: "%{value} is not a valid IS0-639 alpha2 code"}

# scopes
scope :with_topics, -> { joins(:talk_topics) }
scope :without_topics, -> { where.missing(:talk_topics) }

# delegates
delegate :name, to: :event, prefix: true, allow_nil: true

# enums
enum :video_provider, %w[youtube mp4].index_by(&:itself)

# attributes
attribute :video_provider, default: :youtube

# jobs
performs :update_from_yml_metadata!, queue_as: :low

Expand Down Expand Up @@ -109,7 +111,7 @@ def analyze_talk_topics!
scope :with_topics, -> { joins(:talk_topics) }

scope :with_essential_card_data, -> do
select(:id, :slug, :title, :date, :thumbnail_sm, :thumbnail_lg, :video_id, :event_id, :language)
select(:id, :slug, :title, :date, :thumbnail_sm, :thumbnail_lg, :video_id, :video_provider, :event_id, :language)
.includes(:speakers, :event)
end

Expand Down Expand Up @@ -147,23 +149,51 @@ def to_meta_tags
end

def thumbnail_xs
self[:thumbnail_xs].presence || "https://i.ytimg.com/vi/#{video_id}/default.jpg"
thumbnail(:thumbnail_xs)
end

def thumbnail_sm
self[:thumbnail_sm].presence || "https://i.ytimg.com/vi/#{video_id}/mqdefault.jpg"
thumbnail(:thumbnail_sm)
end

def thumbnail_md
self[:thumbnail_md].presence || "https://i.ytimg.com/vi/#{video_id}/hqdefault.jpg"
thumbnail(:thumbnail_md)
end

def thumbnail_lg
self[:thumbnail_lg].presence || "https://i.ytimg.com/vi/#{video_id}/sddefault.jpg"
thumbnail(:thumbnail_lg)
end

def thumbnail_xl
self[:thumbnail_xl].presence || "https://i.ytimg.com/vi/#{video_id}/maxresdefault.jpg"
thumbnail(:thumbnail_xl)
end

def fallback_thumbnail
"/assets/#{Rails.application.assets.load_path.find("posters/fallback.png").digested_path}"
end

def thumbnail(size = :thumbnail_lg)
if self[size].present?
return self[size] if self[size].start_with?("https://")

if (asset = Rails.application.assets.load_path.find(self[size]))
return "/assets/#{asset.digested_path}"
else
return fallback_thumbnail
end
end

return fallback_thumbnail if video_provider != "youtube"

youtube = {
thumbnail_xs: "default",
thumbnail_sm: "mqdefault",
thumbnail_md: "hqdefault",
thumbnail_lg: "sddefault",
thumbnail_xl: "maxresdefault"
}

"https://i.ytimg.com/vi/#{video_id}/#{youtube[size]}.jpg"
end

def related_talks(limit: 6)
Expand Down Expand Up @@ -221,7 +251,8 @@ def update_from_yml_metadata!(event: nil)
thumbnail_lg: static_metadata.thumbnail_lg || "",
thumbnail_xl: static_metadata.thumbnail_xl || "",
language: static_metadata.language || Language::DEFAULT,
slides_url: static_metadata.slides_url
slides_url: static_metadata.slides_url,
video_provider: static_metadata.video_provider || :youtube
)

self.speakers = Array.wrap(static_metadata.speakers).reject(&:blank?).map { |speaker_name|
Expand Down
3 changes: 1 addition & 2 deletions app/views/talks/_card_horizontal.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
<% active = talk == current_talk %>
<div class="<%= class_names("w-full flex items-center gap-2", "border border-secondary rounded-lg p-1": active) %>" id="<%= dom_id(talk, :card_horizontal) %>" data-talk-horizontal-card>
<%= link_to talk_path(talk),
class: "flex aspect-video shrink-0 relative w-28" do %>
<%= link_to talk_path(talk), class: "flex aspect-video shrink-0 relative w-28" do %>
<%= image_tag talk.thumbnail_sm, srcset: ["#{talk.thumbnail_lg} 2x"], id: dom_id(talk), class: "w-full h-auto object-cover", style: "view-transition-name: #{dom_id(talk, :image)}#{active ? "active" : ""}", loading: :lazy %>
<% end %>
<div class="flex flex-col gap-2 text-sm">
Expand Down
25 changes: 14 additions & 11 deletions app/views/talks/_talk.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@
data: {
controller: "video-player",
video_player_poster_value: talk.thumbnail_lg,
video_player_provider_value: "youtube",
video_player_provider_value: (talk.video_provider == "mp4") ? nil : talk.video_provider,
video_player_src_value: talk.video_id
} do %>

<h1 class="text-neutral mb-4 text-2xl"><%= talk.title %></h1>

<div <%= tag.attributes(
class: "aspect-video banner-img card-horizontal-img relative",
style: "view-transition-name: #{dom_id(talk, :image)}"
) %>>

<%= content_tag :div, "",
class: "image",
id: dom_id(talk, :youtube),
data: {video_player_target: "player",
youtube_id: talk.video_id} %>
<div class="aspect-video banner-img card-horizontal-img relative" style="view-transition-name: <%= dom_id(talk, :image) %>">
<% if talk.video_provider == "mp4" %>
<video id="player" data-video-player-target="player" src="<%= talk.video_id %>"></video>
<% elsif talk.video_provider == "youtube" %>
<div
class="image"
id="<%= dom_id(talk, :youtube) %>"
data-video-player-target="player"
data-youtube-id="<%= talk.video_id %>"></div>
<% else %>
Provider <%= talk.video_provider %> is not configured.
<% end %>
</div>


<div class="py-4 flex flex-col gap-4 my-4">

<div class="flex flex-wrap gap-2">
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/talks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ one:
- Bad practices
slug: yaroslav-shmarov-hotwire-cookbook-common-uses-essential-patterns-best-practices-rails-world
video_id: F75k4Oc6g9Q
video_provider: youtube
raw_transcript: '[{"start_time": "00:00:15.280", "end_time": "00:00:21.320", "text": "so nice to be here with you thank you all for coming so uh my name is uh"}, {"start_time": "00:00:21.320", "end_time": "00:00:27.800", "text": "yaroslav I m from Ukraine you might know me from my blog or from my super Al"}, {"start_time": "00:00:27.800", "end_time": "00:00:34.399", "text": "YouTube channel where I post a lot of stuff about trby and especially about hot fire so I originate from Ukraine"}, {"start_time": "00:00:34.399", "end_time": "00:00:40.239", "text": "from the north of Ukraine so right now it is liberated so that is Kev Chernobyl"}, {"start_time": "00:00:40.239", "end_time": "00:00:45.920", "text": "and chern so I used to live 80 kmers away from Chernobyl great"}, {"start_time": "00:00:45.920", "end_time": "00:00:52.680", "text": "place yeah and uh that is my family s home so it got boned in one of the first"}, {"start_time": "00:00:52.680", "end_time": "00:01:00.000", "text": "days of war that is my godfather he went to defend Ukraine and uh I mean we are"}, {"start_time": "00:01:00.000", "end_time": "00:01:05.799", "text": "he has such a beautiful venue but there is the war going on and like just today"}, {"start_time": "00:01:05.799", "end_time": "00:01:13.159", "text": "the city of har was randomly boned by the Russians and there are many Ruby"}, {"start_time": "00:01:13.159", "end_time": "00:01:19.520", "text": "rails people from Ukraine some of them are actually fighting this is verok he contributed to Ruby and he is actually"}, {"start_time": "00:01:19.520", "end_time": "00:01:27.960", "text": "defending Ukraine right now but on a positive note I just recently became a father"}, {"start_time": "00:01:27.960", "end_time": "00:01:35.000", "text": "so yeah um it is uh just 2 and a half months ago in uh France and uh today we"}, {"start_time": "00:01:35.000", "end_time": "00:01:35.000", "text": "are going to talk about hot fire"}]'

two:
Expand Down

0 comments on commit fc37a8c

Please sign in to comment.