Upload remote video to YouTube with GitHub Actions and Google API

Sh Raj - Jul 31 - - Dev Community

You can use GitHub Actions to automate the process of downloading and uploading a video to YouTube. Below are the steps to set up a GitHub Actions workflow for this purpose.

GitHub logo SH20RAJ / youtube-remote-uploader

Upload Remote Videos to YouTube using GitHub Actions

YouTube Logo YouTube Remote Uploader Python Logo

GitHub release (latest by date) GitHub Workflow Status GitHub

YouTube Remote Uploader is a tool that automates the process of downloading videos from remote URLs and uploading them to YouTube using the YouTube Data API. This tool is particularly useful for batch processing and scheduled uploads using GitHub Actions.

Features

  • πŸš€ Download videos from remote URLs
  • πŸ“Ή Upload videos to YouTube with metadata (title, description, tags, etc.)
  • πŸ“¦ Batch processing of multiple videos
  • πŸ”„ Automation with GitHub Actions

Getting Started

Prerequisites

  • 🐍 Python 3.x
  • πŸ“¦ Google API Client Library
  • πŸ” GitHub repository with necessary permissions and secrets

Installation

  1. Clone the repository:

    git clone https://github.com/SH20RAJ/youtube-remote-uploader.git
    cd youtube-remote-uploader
    Enter fullscreen mode Exit fullscreen mode
  2. Install required libraries:

    pip install -r requirements.txt
    Enter fullscreen mode Exit fullscreen mode
  3. Set up Google API credentials:

    • Go to the Google Cloud Console.
    • Create a new project or select an existing project.
    • Enable the YouTube Data API v3 for your project.
    • Create OAuth 2.0 credentials and download the credentials.json file.
    • Save credentials.json in the…
  1. Create a Repository and Add Your Script:

Add the Python script (upload_video.py) to your GitHub repository. Ensure your credentials.json file and any other necessary files are added to the repository or securely stored.

  1. Set Up GitHub Secrets:

Go to your GitHub repository, navigate to Settings > Secrets and variables > Actions, and add the following secrets:

  • GOOGLE_CREDENTIALS: The content of your credentials.json file.
  1. Create a GitHub Actions Workflow:

Create a .github/workflows/upload_video.yml file in your repository with the following content:

   name: Upload Video to YouTube

   on:
     push:
       branches:
         - main
     workflow_dispatch:

   jobs:
     upload_video:
       runs-on: ubuntu-latest

       steps:
       - name: Checkout repository
         uses: actions/checkout@v3

       - name: Set up Python
         uses: actions/setup-python@v4
         with:
           python-version: '3.x'

       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
           pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client requests

       - name: Set up Google Credentials
         run: echo "${{ secrets.GOOGLE_CREDENTIALS }}" > credentials.json

       - name: Run upload script
         run: python upload_video.py
Enter fullscreen mode Exit fullscreen mode
  1. Modify Your Python Script:

Ensure your Python script (upload_video.py) reads the credentials from the credentials.json file created by the GitHub Action.

   import os
   import requests
   import google.auth
   import google.auth.transport.requests
   from google.oauth2.credentials import Credentials
   from google_auth_oauthlib.flow import InstalledAppFlow
   from googleapiclient.discovery import build
   from googleapiclient.http import MediaFileUpload

   # Set up OAuth 2.0 authorization
   SCOPES = ["https://www.googleapis.com/auth/youtube.upload"]

   def get_authenticated_service():
       creds = None
       if os.path.exists("token.json"):
           creds = Credentials.from_authorized_user_file("token.json", SCOPES)
       if not creds or not creds.valid:
           if creds and creds.expired and creds.refresh_token:
               creds.refresh(google.auth.transport.requests.Request())
           else:
               flow = InstalledAppFlow.from_client_secrets_file(
                   "credentials.json", SCOPES)
               creds = flow.run_local_server(port=0)
           with open("token.json", "w") as token:
               token.write(creds.to_json())
       return build("youtube", "v3", credentials=creds)

   def download_video(video_url, output_path):
       response = requests.get(video_url, stream=True)
       with open(output_path, 'wb') as file:
           for chunk in response.iter_content(chunk_size=8192):
               file.write(chunk)

   def upload_video(service, video_file, title, description, tags, category_id, privacy_status):
       body = {
           "snippet": {
               "title": title,
               "description": description,
               "tags": tags,
               "categoryId": category_id
           },
           "status": {
               "privacyStatus": privacy_status
           }
       }
       media = MediaFileUpload(video_file, chunksize=-1, resumable=True)
       request = service.videos().insert(
           part="snippet,status",
           body=body,
           media_body=media
       )
       response = request.execute()
       print(f"Video uploaded: {response['id']}")

   if __name__ == "__main__":
       service = get_authenticated_service()

       # Remote video URL
       video_url = "https://example.com/path_to_your_video_file.mp4"
       # Temporary local path to save the video
       local_video_file = "temp_video.mp4"

       # Download video from remote URL
       download_video(video_url, local_video_file)

       # Video details
       title = "Your Video Title"
       description = "Your video description"
       tags = ["tag1", "tag2", "tag3"]
       category_id = "22"  # See YouTube API documentation for category IDs
       privacy_status = "public"  # "public", "private", or "unlisted"

       # Upload video to YouTube
       upload_video(service, local_video_file, title, description, tags, category_id, privacy_status)

       # Optionally, remove the temporary video file
       os.remove(local_video_file)
Enter fullscreen mode Exit fullscreen mode
  1. Run the Workflow:

Push your changes to the main branch or manually trigger the workflow using the Actions tab in your GitHub repository.

This setup will allow you to automate the process of downloading a video from a remote URL and uploading it to YouTube whenever you push to the main branch or manually trigger the workflow.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .