From 7c9b49378b128b47bd5f539c566a8fbd24547f1a Mon Sep 17 00:00:00 2001 From: Benjamin Piouffle Date: Mon, 7 Oct 2024 21:23:44 +0200 Subject: [PATCH] implement youtube download --- apps/cf/lib/application.ex | 38 +++++++++++++--- .../cf/lib/videos/captions_fetcher_youtube.ex | 45 +++++-------------- apps/cf/mix.exs | 1 + 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/apps/cf/lib/application.ex b/apps/cf/lib/application.ex index 93d1a21c..20024e72 100644 --- a/apps/cf/lib/application.ex +++ b/apps/cf/lib/application.ex @@ -1,8 +1,8 @@ defmodule CF.Application do use Application - # See http://elixir-lang.org/docs/stable/elixir/Application.html - # for more information on OTP Applications + require Logger + def start(_type, _args) do import Supervisor.Spec @@ -13,13 +13,20 @@ defmodule CF.Application do # Misc workers worker(CF.Accounts.UsernameGenerator, []), # Sweep tokens from db - worker(Guardian.DB.Token.SweeperServer, []) + worker(Guardian.DB.Token.SweeperServer, []), ] - # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html - # for other strategies and supported options opts = [strategy: :one_for_one, name: CF.Supervisor] - Supervisor.start_link(children, opts) + + goth_credentials = get_goth_worker_credentials() + if goth_credentials do + IO.inspect(goth_credentials) + source = {:refresh_token, goth_credentials, []} + children = [{Goth, name: CF.Goth, source: source}] ++ children + Supervisor.start_link(children, opts) + else + Supervisor.start_link(children, opts) + end end def version() do @@ -36,4 +43,23 @@ defmodule CF.Application do def env() do (Kernel.function_exported?(Mix, :env, 0) && Mix.env()) || :prod end + + defp get_goth_worker_credentials() do + System.fetch_env("GOOGLE_APPLICATION_CREDENTIALS_JSON") + |> case do + {:ok, credentials} -> + case Jason.decode(credentials) do + {:ok, decoded} -> + Logger.info("GOOGLE_APPLICATION_CREDENTIALS_JSON found") + decoded + {:error, _} -> + Logger.error("GOOGLE_APPLICATION_CREDENTIALS_JSON is not a valid JSON") + nil + end + + _ -> + Logger.warn("GOOGLE_APPLICATION_CREDENTIALS_JSON not found") + nil + end + end end diff --git a/apps/cf/lib/videos/captions_fetcher_youtube.ex b/apps/cf/lib/videos/captions_fetcher_youtube.ex index 346e37f4..ff0e4f19 100644 --- a/apps/cf/lib/videos/captions_fetcher_youtube.ex +++ b/apps/cf/lib/videos/captions_fetcher_youtube.ex @@ -97,37 +97,16 @@ defmodule CF.Videos.CaptionsFetcherYoutube do # Below is an implementation using the official YouTube API, but it requires OAuth2 authentication. # It is left here for reference, in case we loose access to the unofficial API. - # defp fetch_captions_content_with_official_api(video_id, locale) do - # # TODO: Continue dev here. See https://www.perplexity.ai/search/Can-you-show-jioyCtw.S4yrL8mlIBdqGg - # {:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/youtube.force-ssl") - # conn = YouTubeConnection.new(token.token) - # {:ok, captions} = GoogleApi.YouTube.V3.Api.Captions.youtube_captions_list(conn, ["snippet"], video_id, []) - # { - # "kind": "youtube#captionListResponse", - # "etag": "kMTAKpyU_VGu7GxgEnxXHqcuEXM", - # "items": [ - # { - # "kind": "youtube#caption", - # "etag": "tWo68CIcRRFZA0oXPt8HGxCYia4", - # "id": "AUieDaZJxYug0L5YNAw_31GbXz73b0CPXCDFlsPNSNe7KQvuv1g", - # "snippet": { - # "videoId": "v2IoEhuho2k", - # "lastUpdated": "2024-06-16T18:45:12.56697Z", - # "trackKind": "asr", - # "language": "fr", - # "name": "", - # "audioTrackType": "unknown", - # "isCC": false, - # "isLarge": false, - # "isEasyReader": false, - # "isDraft": false, - # "isAutoSynced": false, - # "status": "serving" - # } - # } - # ] - # } - # caption_id = List.first(captions.items).id # TODO inspect to pick the right caption - # {:ok, caption} = GoogleApi.YouTube.V3.Api.Captions.youtube_captions_download(conn, caption_id, []) - # end + def fetch_captions_content_with_official_api(video_id, locale) do + {:ok, token} = Goth.fetch(CF.Goth) + conn = GoogleApi.YouTube.V3.Connection.new(token.token) + + IO.inspect(token) + + {:ok, result} = GoogleApi.YouTube.V3.Api.Captions.youtube_captions_list(conn, ["snippet"], video_id, []) + IO.inspect(Enum.count(result.items)) + caption_id = List.first(result.items).id + {:ok, caption} = + GoogleApi.YouTube.V3.Api.Captions.youtube_captions_download(conn, caption_id, []) #FAILS, you can only download captions for your own videos :-( + end end diff --git a/apps/cf/mix.exs b/apps/cf/mix.exs index bba8d07c..53117e1a 100644 --- a/apps/cf/mix.exs +++ b/apps/cf/mix.exs @@ -61,6 +61,7 @@ defmodule CF.Mixfile do {:jason, "~> 1.4"}, {:openai, "~> 0.6.1"}, {:sweet_xml, "~> 0.7.4"}, + {:goth, "~> 1.3"}, # ---- Internal ---- {:db, in_umbrella: true},