pinchflat/lib/pinchflat/media_client/backends/yt_dlp/video_collection.ex

56 lines
1.7 KiB
Elixir

defmodule Pinchflat.MediaClient.Backends.YtDlp.VideoCollection do
@moduledoc """
Contains utilities for working with collections of
videos (aka: a source [ie: channels, playlists]).
"""
@doc """
Returns a list of strings representing the video ids in the collection.
Returns {:ok, [binary()]} | {:error, any, ...}.
"""
def get_video_ids(url, command_opts \\ []) do
runner = Application.get_env(:pinchflat, :yt_dlp_runner)
opts = command_opts ++ [:simulate, :skip_download]
case runner.run(url, opts, "%(id)s") do
{:ok, output} -> {:ok, String.split(output, "\n", trim: true)}
res -> res
end
end
@doc """
Gets a source's ID and name from its URL.
yt-dlp does not _really_ have source-specific functions, so
instead we're fetching just the first video (using playlist_end: 1)
and parsing the source ID and name from _its_ metadata
Returns {:ok, map()} | {:error, any, ...}.
"""
def get_source_details(source_url) do
opts = [:simulate, :skip_download, playlist_end: 1]
output_template = "%(.{channel,channel_id,playlist_id,playlist_title})j"
with {:ok, output} <- backend_runner().run(source_url, opts, output_template),
{:ok, parsed_json} <- Phoenix.json_library().decode(output) do
{:ok, format_source_details(parsed_json)}
else
err -> err
end
end
# TODO: test
defp format_source_details(response) do
%{
channel_id: response["channel_id"],
channel_name: response["channel"],
playlist_id: response["playlist_id"],
playlist_name: response["playlist_title"]
}
end
defp backend_runner do
Application.get_env(:pinchflat, :yt_dlp_runner)
end
end