1
0
mirror of https://github.com/algora-io/tv.git synced 2025-03-17 20:17:45 +02:00

120 lines
3.3 KiB
Elixir

defmodule Algora.Library.Video do
require Logger
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias Algora.Accounts.User
alias Algora.Library.Video
alias Algora.Shows.Show
alias Algora.Chat.Message
alias Algora.Ads.{Appearance, ContentMetrics, ProductReview}
@type t() :: %__MODULE__{}
schema "videos" do
field :duration, :integer
field :title, :string
field :description, :string
field :type, Ecto.Enum, values: [vod: 1, livestream: 2]
field :format, Ecto.Enum, values: [mp4: 1, hls: 2, youtube: 3]
field :corrupted, :boolean, default: false
field :is_live, :boolean, default: false
field :thumbnail_url, :string
field :vertical_thumbnail_url, :string
field :og_image_url, :string
field :url, :string
field :url_root, :string
field :uuid, :string
field :filename, :string
field :channel_handle, :string, virtual: true
field :channel_name, :string, virtual: true
field :channel_avatar_url, :string, virtual: true
field :messages_count, :integer, virtual: true, default: 0
field :visibility, Ecto.Enum, values: [public: 1, unlisted: 2]
field :remote_path, :string
field :local_path, :string
field :deleted_at, :naive_datetime
belongs_to :user, User
belongs_to :show, Show
belongs_to :transmuxed_from, Video
has_one :content_metrics, ContentMetrics
has_many :messages, Message
has_many :appearances, Appearance
has_many :product_reviews, ProductReview
timestamps()
end
@doc false
def changeset(video, attrs) do
video
|> cast(attrs, [:title])
|> validate_required([:title])
end
def put_user(%Ecto.Changeset{} = changeset, %User{} = user) do
put_assoc(changeset, :user, user)
end
def put_video_uuid(%Ecto.Changeset{} = changeset) do
if changeset.valid? do
uuid = Ecto.UUID.generate()
changeset
|> put_change(:uuid, uuid)
|> put_change(:url_root, url_root(uuid))
else
changeset
end
end
def put_video_meta(%Ecto.Changeset{} = changeset, format, basename \\ "index")
when format in [:mp4, :hls] do
if changeset.valid? do
filename = "#{basename}#{fileext(format)}"
changeset
|> put_video_uuid()
|> put_change(:filename, filename)
else
changeset
end
end
def put_video_url(%Ecto.Changeset{} = changeset, format, basename \\ "index")
when format in [:mp4, :hls] do
if changeset.valid? do
changeset = changeset |> put_video_meta(format, basename)
%{uuid: uuid, filename: filename} = changeset.changes
changeset
|> put_change(:url, url(uuid, filename))
|> put_change(:remote_path, "#{uuid}/#{filename}")
else
changeset
end
end
defp fileext(:mp4), do: ".mp4"
defp fileext(:hls), do: ".m3u8"
defp url_root(uuid) do
bucket = Algora.config([:buckets, :media])
%{scheme: scheme, host: host} = Application.fetch_env!(:ex_aws, :s3) |> Enum.into(%{})
"#{scheme}#{host}/#{bucket}/#{uuid}"
end
defp url(uuid, filename), do: "#{url_root(uuid)}/#{filename}"
def slug(%Video{} = video), do: Slug.slugify("#{video.id}-#{video.title}")
def id_from_slug(slug), do: slug |> String.split("-") |> Enum.at(0)
def not_deleted(query) do
from v in query, where: is_nil(v.deleted_at)
end
end