Upload on Youtube With Elixir
For a project of mine I had to upload video on youtube using the Youtube data API. I struggled a bit to get the right OAuth token and on the google generated elixir library ...
I detailed every step with the current 2022 google cloud interface.
The github repo for the elixir code https://github.com/mrdotb/youtube_upload_with_elixir
Table of contents
Setup on google cloud platform
Create project
Enable Youtube api
Type youtube api
in the search bar then click on YouTube Data api v3.
Enable it.
Setup oauth consent screen
Click Oauth consent screen then tick external then create.
Fill the mandatory fields App name, User support email and Email addresses.
Add or remove scopes.
Tick youtube and youtube upload then update.
Add a test user this user is the google who own the youtube channel you want to upload.
Create credentials
Click create credentials then OAuth client ID.
Choose Web application and fill the name and the return uri as https://developers.google.com/oauthplayground
. This is mandatory to get the refresh token from the oauthplayground! Keep the page open you will need the client_id
and client_secret
.
Get the refresh token on google playground
Go to oauthplayground.
On the right side of the screen open the settings and input your client id and client secret.
On left side tick youtube and youtube.upload then click on authorize api you will be redirected and prompted to give the youtube authorization to your app.
Now click exchange the authorization code for tokens. Copy the refresh token you will need it after.
Elixir code
mix new --sup upload_with_elixir cd upload_with_elixir
Add these dependencies to your mix.exs
... {:goth, "~> 1.3-rc"}, {:hackney, "~> 1.17"}, {:google_api_you_tube, "~> 0.40"} ...
Install the deps
mix deps.get
Edit application.ex
to setup goth
defmodule UploadWithElixir.Application do use Application def start(_type, _args) do # I just put creds here in a real project you should use config credentials = %{ # Fill it with your client id "client_id" => "...", # Fill it with your client secret "client_secret" => "...", # the token we got from the oauthplayground "refresh_token" => "..." } source = {:refresh_token, credentials, []} children = [ {Goth, name: UploadWithElixir.Goth, source: source} ] Supervisor.start_link(children, strategy: :one_for_one) end end
Verify if you can get token with goth.
Goth.fetch(UploadWithElixir.Goth) {:ok, %Goth.Token{ ... }}
The google lib is verbose so let's write some function to do the insert.
defmodule UploadWithElixir do def video_insert do # get the token {:ok, token} = Goth.fetch(UploadWithElixir.Goth) # set the token conn = GoogleApi.YouTube.V3.Connection.new(token.token) # The path to your video video_path = Path.expand("./sample.webm", __DIR__) # upload GoogleApi.YouTube.V3.Api.Videos.youtube_videos_insert_simple( conn, ["snippet", "status"], "multipart", %GoogleApi.YouTube.V3.Model.Video{ snippet: %GoogleApi.YouTube.V3.Model.VideoSnippet{ title: "Test Video upload from elixir", description: "Description of the uploaded video" }, status: %GoogleApi.YouTube.V3.Model.VideoStatus{ privacyStatus: "private" } }, video_path ) end end
Start iex and run the function you should get ok.
UploadWithElixir.video_insert() {:ok, %GoogleApi.YouTube.V3.Model.Video{ ... }}
If it does not work. There is 10,000 quota allocation an upload cost 1600. So if it does not work double check everything. Even a fail request cost 1600 you can do only 6 upload request per 24hours.
Some limitations:
- it's not possible to put the video as public without having you app verified by google...
- the refresh_token will expire after 7 days