2024-02-29 22:31:42 +03:00
|
|
|
defmodule Algora.Library.Video do
|
|
|
|
require Logger
|
|
|
|
use Ecto.Schema
|
|
|
|
import Ecto.Changeset
|
|
|
|
|
2024-04-01 18:39:03 +03:00
|
|
|
alias Algora.Accounts.User
|
|
|
|
alias Algora.Library.Video
|
|
|
|
alias Algora.Chat.Message
|
2024-02-29 22:31:42 +03:00
|
|
|
|
|
|
|
@type t() :: %__MODULE__{}
|
|
|
|
|
|
|
|
schema "videos" do
|
|
|
|
field :duration, :integer
|
|
|
|
field :title, :string
|
2024-04-01 18:39:03 +03:00
|
|
|
field :description, :string
|
2024-02-29 22:31:42 +03:00
|
|
|
field :type, Ecto.Enum, values: [vod: 1, livestream: 2]
|
2024-04-01 18:39:03 +03:00
|
|
|
field :format, Ecto.Enum, values: [mp4: 1, hls: 2, youtube: 3]
|
2024-02-29 22:31:42 +03:00
|
|
|
field :is_live, :boolean, default: false
|
2024-03-06 19:51:58 +03:00
|
|
|
field :thumbnail_url, :string
|
2024-03-07 02:02:32 +03:00
|
|
|
field :vertical_thumbnail_url, :string
|
2024-02-29 22:31:42 +03:00
|
|
|
field :url, :string
|
|
|
|
field :url_root, :string
|
|
|
|
field :uuid, :string
|
2024-04-01 18:39:03 +03:00
|
|
|
field :filename, :string
|
2024-03-11 23:40:26 +03:00
|
|
|
field :channel_handle, :string, virtual: true
|
2024-02-29 22:31:42 +03:00
|
|
|
field :channel_name, :string, virtual: true
|
2024-04-01 18:39:03 +03:00
|
|
|
field :messages_count, :integer, virtual: true, default: 0
|
2024-02-29 22:31:42 +03:00
|
|
|
field :visibility, Ecto.Enum, values: [public: 1, unlisted: 2]
|
2024-04-01 18:39:03 +03:00
|
|
|
field :remote_path, :string
|
|
|
|
field :local_path, :string
|
|
|
|
|
|
|
|
belongs_to :user, User
|
|
|
|
belongs_to :transmuxed_from, Video
|
|
|
|
|
|
|
|
has_many :messages, Message
|
2024-02-29 22:31:42 +03:00
|
|
|
|
|
|
|
timestamps()
|
|
|
|
end
|
|
|
|
|
|
|
|
@doc false
|
|
|
|
def changeset(video, attrs) do
|
|
|
|
video
|
|
|
|
|> cast(attrs, [:title])
|
|
|
|
|> validate_required([:title])
|
|
|
|
end
|
|
|
|
|
2024-04-01 18:39:03 +03:00
|
|
|
def put_user(%Ecto.Changeset{} = changeset, %User{} = user) do
|
2024-02-29 22:31:42 +03:00
|
|
|
put_assoc(changeset, :user, user)
|
|
|
|
end
|
|
|
|
|
2024-04-01 18:39:03 +03:00
|
|
|
def put_video_meta(%Ecto.Changeset{} = changeset, format, basename \\ "index")
|
|
|
|
when format in [:mp4, :hls] do
|
2024-02-29 22:31:42 +03:00
|
|
|
if changeset.valid? do
|
|
|
|
uuid = Ecto.UUID.generate()
|
2024-04-01 18:39:03 +03:00
|
|
|
filename = "#{basename}#{fileext(format)}"
|
2024-02-29 22:31:42 +03:00
|
|
|
|
|
|
|
changeset
|
2024-04-01 18:39:03 +03:00
|
|
|
|> put_change(:filename, filename)
|
2024-02-29 22:31:42 +03:00
|
|
|
|> put_change(:uuid, uuid)
|
2024-04-01 18:39:03 +03:00
|
|
|
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
|
2024-02-29 22:31:42 +03:00
|
|
|
|> put_change(:url, url(uuid, filename))
|
|
|
|
|> put_change(:url_root, url_root(uuid))
|
2024-04-01 18:39:03 +03:00
|
|
|
|> put_change(:remote_path, "#{uuid}/#{filename}")
|
2024-02-29 22:31:42 +03:00
|
|
|
else
|
|
|
|
changeset
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-04-01 18:39:03 +03:00
|
|
|
defp fileext(:mp4), do: ".mp4"
|
|
|
|
defp fileext(:hls), do: ".m3u8"
|
2024-02-29 22:31:42 +03:00
|
|
|
|
|
|
|
defp url_root(uuid) do
|
|
|
|
bucket = Algora.config([:files, :bucket])
|
|
|
|
%{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}"
|
|
|
|
end
|