Renamed column; added format options and tests

This commit is contained in:
Kieran Eglin 2024-11-27 09:41:53 -08:00
parent 4bc03c16e9
commit fa22580094
No known key found for this signature in database
GPG key ID: 193984967FCF432D
6 changed files with 73 additions and 20 deletions

View file

@ -1,19 +1,31 @@
defmodule Pinchflat.Downloading.QualityOptionBuilder do defmodule Pinchflat.Downloading.QualityOptionBuilder do
@moduledoc """
A standalone builder module for building quality-related options for yt-dlp to download media.
Currently exclusively used in DownloadOptionBuilder since this logic is too complex to just
place in the main module.
"""
alias Pinchflat.Settings alias Pinchflat.Settings
alias Pinchflat.Profiles.MediaProfile alias Pinchflat.Profiles.MediaProfile
# TODO: test @doc """
def build(%MediaProfile{preferred_resolution: :audio, media_container: container}) do Builds the quality-related options for yt-dlp to download media based on the given media profile
Includes things like container, preferred format/codec, and audio track options.
"""
def build(%MediaProfile{preferred_resolution: :audio, media_container: container} = media_profile) do
acodec = Settings.get!(:audio_codec_preference) acodec = Settings.get!(:audio_codec_preference)
[ [
:extract_audio, :extract_audio,
format_sort: "+acodec:#{acodec}", format_sort: "+acodec:#{acodec}",
audio_format: container || "best" audio_format: container || "best",
] ++ build_format_string(nil) format: build_format_string(media_profile)
]
end end
def build(%MediaProfile{preferred_resolution: resolution_atom, media_container: container}) do def build(%MediaProfile{preferred_resolution: resolution_atom, media_container: container} = media_profile) do
vcodec = Settings.get!(:video_codec_preference) vcodec = Settings.get!(:video_codec_preference)
acodec = Settings.get!(:audio_codec_preference) acodec = Settings.get!(:audio_codec_preference)
{resolution_string, _} = resolution_atom |> Atom.to_string() |> Integer.parse() {resolution_string, _} = resolution_atom |> Atom.to_string() |> Integer.parse()
@ -21,22 +33,27 @@ defmodule Pinchflat.Downloading.QualityOptionBuilder do
[ [
# Since Plex doesn't support reading metadata from MKV # Since Plex doesn't support reading metadata from MKV
remux_video: container || "mp4", remux_video: container || "mp4",
format_sort: "res:#{resolution_string},+codec:#{vcodec}:#{acodec}" format_sort: "res:#{resolution_string},+codec:#{vcodec}:#{acodec}",
] ++ build_format_string(nil) format: build_format_string(media_profile)
]
end end
# TODO: pass in the entire media profile once we have the language preference column defp build_format_string(%MediaProfile{preferred_resolution: :audio, audio_track: audio_track}) do
# TODO: test if audio_track do
# TODO: Set to ba/b if it's audio-only "bestaudio[#{build_format_modifier(audio_track)}]/bestaudio/best"
defp build_format_string(language_preference) do
if language_preference do
["bestvideo+bestaudio[#{build_format_modifier(language_preference)}]/bestvideo*+bestaudio/best"]
else else
["bestvideo*+bestaudio/best"] "bestaudio/best"
end
end
defp build_format_string(%MediaProfile{audio_track: audio_track}) do
if audio_track do
"bestvideo+bestaudio[#{build_format_modifier(audio_track)}]/bestvideo*+bestaudio/best"
else
"bestvideo*+bestaudio/best"
end end
end end
# TODO: test
defp build_format_modifier("original"), do: "format_note*=original" defp build_format_modifier("original"), do: "format_note*=original"
defp build_format_modifier("default"), do: "format_note*=(default)" defp build_format_modifier("default"), do: "format_note*=(default)"
# This uses the carat to anchor the language to the beginning of the string # This uses the carat to anchor the language to the beginning of the string

View file

@ -26,7 +26,7 @@ defmodule Pinchflat.Profiles.MediaProfile do
sponsorblock_categories sponsorblock_categories
shorts_behaviour shorts_behaviour
livestream_behaviour livestream_behaviour
audio_lang audio_track
preferred_resolution preferred_resolution
media_container media_container
redownload_delay_days redownload_delay_days
@ -66,7 +66,7 @@ defmodule Pinchflat.Profiles.MediaProfile do
# See `build_format_clauses` in the Media context for more. # See `build_format_clauses` in the Media context for more.
field :shorts_behaviour, Ecto.Enum, values: ~w(include exclude only)a, default: :include field :shorts_behaviour, Ecto.Enum, values: ~w(include exclude only)a, default: :include
field :livestream_behaviour, Ecto.Enum, values: ~w(include exclude only)a, default: :include field :livestream_behaviour, Ecto.Enum, values: ~w(include exclude only)a, default: :include
field :audio_lang, :string field :audio_track, :string
field :preferred_resolution, Ecto.Enum, values: ~w(4320p 2160p 1080p 720p 480p 360p audio)a, default: :"1080p" field :preferred_resolution, Ecto.Enum, values: ~w(4320p 2160p 1080p 720p 480p 360p audio)a, default: :"1080p"
field :media_container, :string, default: nil field :media_container, :string, default: nil

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 KiB

After

Width:  |  Height:  |  Size: 438 KiB

View file

@ -3,7 +3,7 @@ defmodule Pinchflat.Repo.Migrations.AddAudioLangToMediaProfiles do
def change do def change do
alter table(:media_profiles) do alter table(:media_profiles) do
add :audio_lang, :string add :audio_track, :string
end end
end end
end end

View file

@ -6,7 +6,6 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilderTest do
alias Pinchflat.Sources alias Pinchflat.Sources
alias Pinchflat.Profiles alias Pinchflat.Profiles
alias Pinchflat.Settings
alias Pinchflat.Utils.FilesystemUtils alias Pinchflat.Utils.FilesystemUtils
alias Pinchflat.Downloading.DownloadOptionBuilder alias Pinchflat.Downloading.DownloadOptionBuilder

View file

@ -6,7 +6,32 @@ defmodule Pinchflat.Downloading.QualityOptionBuilderTest do
alias Pinchflat.Settings alias Pinchflat.Settings
alias Pinchflat.Downloading.QualityOptionBuilder alias Pinchflat.Downloading.QualityOptionBuilder
# TODO: this basically tests the existing logic but doesn't test any of the new stuff. Add those tests. describe "build/1" do
test "includes format options if audio_track is set to original" do
media_profile = media_profile_fixture(%{audio_track: "original"})
assert res = QualityOptionBuilder.build(media_profile)
assert {:format, "bestvideo+bestaudio[format_note*=original]/bestvideo*+bestaudio/best"} in res
end
test "includes format options if audio_track is set to default" do
media_profile = media_profile_fixture(%{audio_track: "default"})
assert res = QualityOptionBuilder.build(media_profile)
assert {:format, "bestvideo+bestaudio[format_note*=(default)]/bestvideo*+bestaudio/best"} in res
end
test "includes format options if audio_track is set to a language code" do
media_profile = media_profile_fixture(%{audio_track: "en"})
assert res = QualityOptionBuilder.build(media_profile)
assert {:format, "bestvideo+bestaudio[language^=en]/bestvideo*+bestaudio/best"} in res
end
end
describe "build/1 when testing audio profiles" do describe "build/1 when testing audio profiles" do
setup do setup do
{:ok, media_profile: media_profile_fixture(%{preferred_resolution: :audio})} {:ok, media_profile: media_profile_fixture(%{preferred_resolution: :audio})}
@ -29,6 +54,12 @@ defmodule Pinchflat.Downloading.QualityOptionBuilderTest do
assert {:audio_format, "flac"} in res assert {:audio_format, "flac"} in res
end end
test "includes custom format options", %{media_profile: media_profile} do
assert res = QualityOptionBuilder.build(media_profile)
assert {:format, "bestaudio/best"} in res
end
end end
describe "build/1 when testing non-audio profiles" do describe "build/1 when testing non-audio profiles" do
@ -68,5 +99,11 @@ defmodule Pinchflat.Downloading.QualityOptionBuilderTest do
assert {:remux_video, "mkv"} in res assert {:remux_video, "mkv"} in res
end end
test "includes custom format options", %{media_profile: media_profile} do
assert res = QualityOptionBuilder.build(media_profile)
assert {:format, "bestvideo*+bestaudio/best"} in res
end
end end
end end