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.

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

Stay up to date

Sign up for the mailing list and get notified via email when new blog posts come out.