From 4fdd07fc5839502880431e802b0049253bcde8a9 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Tue, 21 May 2024 12:36:42 -0700 Subject: [PATCH] [WIP] started on codec parser --- lib/pinchflat/downloading/codec_parser.ex | 49 +++++++++++++++++++ .../downloading/download_option_builder.ex | 30 ++++++++---- .../media_items/media_item_html.ex | 1 + 3 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 lib/pinchflat/downloading/codec_parser.ex diff --git a/lib/pinchflat/downloading/codec_parser.ex b/lib/pinchflat/downloading/codec_parser.ex new file mode 100644 index 0000000..ff4d68b --- /dev/null +++ b/lib/pinchflat/downloading/codec_parser.ex @@ -0,0 +1,49 @@ +defmodule Pinchflat.Downloading.CodecParser do + # TODO: test + def generate_vcodec_string(nil), do: "bestvideo[vcodec~='^avc']/bestvideo" + def generate_vcodec_string([]), do: generate_vcodec_string(nil) + + def generate_vcodec_string(video_codecs) do + video_codecs + |> Enum.map(&video_codec_map()[&1]) + |> Enum.reject(&is_nil/1) + |> Enum.map(&"bestvideo[vcodec~='^#{&1}']") + |> Enum.concat(["bestvideo", "best"]) + |> Enum.join("/") + end + + # TODO: test + def generate_acodec_string(nil), do: "bestaudio[acodec~='^mp4a']/bestaudio[acodec~='^mp3']/bestaudio" + def generate_acodec_string([]), do: generate_acodec_string(nil) + + def generate_acodec_string(audio_codecs) do + audio_codecs + |> Enum.map(&audio_codec_map()[&1]) + |> Enum.reject(&is_nil/1) + |> Enum.map(&"bestaudio[acodec~='^#{&1}']") + |> Enum.concat(["bestaudio", "best"]) + |> Enum.join("/") + end + + defp video_codec_map do + %{ + "av01" => "av01", + "avc" => "avc", + "vp9" => "vp0?9" + } + end + + defp audio_codec_map do + %{ + "flac" => "flac", + "alac" => "alac", + "wav" => "wav", + "aiff" => "aiff", + "aac" => "aac", + "mp4a" => "mp4a", + "mp3" => "mp3", + "opus" => "opus", + "vorbis" => "vorbis" + } + end +end diff --git a/lib/pinchflat/downloading/download_option_builder.ex b/lib/pinchflat/downloading/download_option_builder.ex index c1ccf6f..ec00616 100644 --- a/lib/pinchflat/downloading/download_option_builder.ex +++ b/lib/pinchflat/downloading/download_option_builder.ex @@ -6,6 +6,7 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do alias Pinchflat.Sources alias Pinchflat.Sources.Source alias Pinchflat.Media.MediaItem + alias Pinchflat.Downloading.CodecParser alias Pinchflat.Downloading.OutputPathBuilder alias Pinchflat.Utils.FilesystemUtils, as: FSUtils @@ -120,23 +121,32 @@ defmodule Pinchflat.Downloading.DownloadOptionBuilder do end) end + # TODO: test defp quality_options(media_profile) do + vcodec_string = CodecParser.generate_vcodec_string(["vp9", "av01"]) + acodec_string = CodecParser.generate_acodec_string(["opus", "aac", "mp4a"]) + video_codec_option = fn res -> - [format_sort: "res:#{res},+codec:avc:m4a", remux_video: "mp4"] + [ + format_sort: "res:#{res}", + # Since Plex doesn't support reading metadata from MKV + remux_video: "mp4", + format: "((#{vcodec_string})+(#{acodec_string}))/best" + ] end - audio_format_precedence = [ - "bestaudio[ext=m4a]", - "bestaudio[ext=mp3]", - "bestaudio", - "best[ext=m4a]", - "best[ext=mp3]", - "best" - ] + # audio_format_precedence = [ + # "bestaudio[ext=m4a]", + # "bestaudio[ext=mp3]", + # "bestaudio", + # "best[ext=m4a]", + # "best[ext=mp3]", + # "best" + # ] case media_profile.preferred_resolution do # Also be aware that :audio disabled all embedding options for subtitles - :audio -> [:extract_audio, format: Enum.join(audio_format_precedence, "/")] + :audio -> [:extract_audio, format: "#{acodec_string}/best"] :"360p" -> video_codec_option.("360") :"480p" -> video_codec_option.("480") :"720p" -> video_codec_option.("720") diff --git a/lib/pinchflat_web/controllers/media_items/media_item_html.ex b/lib/pinchflat_web/controllers/media_items/media_item_html.ex index 659e742..672a454 100644 --- a/lib/pinchflat_web/controllers/media_items/media_item_html.ex +++ b/lib/pinchflat_web/controllers/media_items/media_item_html.ex @@ -15,6 +15,7 @@ defmodule PinchflatWeb.MediaItems.MediaItemHTML do !!media_item.media_filepath and File.exists?(media_item.media_filepath) end + # TODO: update for new format types def media_type(media_item) do case Path.extname(media_item.media_filepath) do ext when ext in [".mp4", ".webm", ".mkv"] -> :video