Renamed column; added format options and tests
This commit is contained in:
parent
4bc03c16e9
commit
fa22580094
6 changed files with 73 additions and 20 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 |
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue