116 lines
3.6 KiB
Python
116 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
yt_poster.py
|
|
|
|
This module handles the upload of videos to YouTube using the YouTube Data API v3.
|
|
It supports setting metadata such as title, description, tags, category, and privacy settings.
|
|
It also ensures that the game title "Fortnite" is included in the metadata to trigger proper categorization.
|
|
|
|
Author: gramps@llamachile.shop
|
|
"""
|
|
|
|
import os
|
|
import google.auth
|
|
from googleapiclient.discovery import build
|
|
from googleapiclient.http import MediaFileUpload
|
|
|
|
from modules.config import OPENAI_API_KEY, DEBUG
|
|
from modules.archive import save_metadata_record
|
|
|
|
# Category ID for "Gaming" on YouTube (required for accurate categorization)
|
|
CATEGORY_ID = "20"
|
|
|
|
# Default tags to include if none are provided
|
|
DEFAULT_TAGS = [
|
|
"Fortnite", "Zero Build", "Gramps", "CoolHandGramps",
|
|
"funny", "gaming", "highlights"
|
|
]
|
|
|
|
# Default visibility setting
|
|
DEFAULT_PRIVACY = "public"
|
|
|
|
def ensure_fortnite_tag(metadata):
|
|
"""
|
|
Ensures that the word 'Fortnite' appears in at least one of the following:
|
|
- Title
|
|
- Description
|
|
- Tags list
|
|
|
|
This helps YouTube automatically detect the game and associate the video
|
|
with Fortnite gameplay.
|
|
"""
|
|
if "fortnite" not in metadata["title"].lower() and \
|
|
"fortnite" not in metadata["description"].lower() and \
|
|
not any("fortnite" in tag.lower() for tag in metadata.get("tags", [])):
|
|
metadata.setdefault("tags", []).append("Fortnite")
|
|
|
|
def upload_video(youtube, video_path, metadata):
|
|
"""
|
|
Uploads a video to YouTube with the provided metadata.
|
|
|
|
Args:
|
|
youtube: Authenticated YouTube API service object.
|
|
video_path: Path to the video file to be uploaded.
|
|
metadata: Dictionary containing video metadata fields.
|
|
|
|
Returns:
|
|
str: URL of the uploaded YouTube video.
|
|
"""
|
|
|
|
# Ensure the 'Fortnite' keyword is present somewhere in metadata
|
|
ensure_fortnite_tag(metadata)
|
|
|
|
# Construct the request body for YouTube API
|
|
request_body = {
|
|
"snippet": {
|
|
"title": metadata["title"],
|
|
"description": metadata["description"],
|
|
"tags": metadata.get("tags", DEFAULT_TAGS),
|
|
"categoryId": CATEGORY_ID # Set to "Gaming"
|
|
},
|
|
"status": {
|
|
"privacyStatus": metadata.get("privacy", DEFAULT_PRIVACY)
|
|
}
|
|
}
|
|
|
|
# Wrap the video file in a MediaFileUpload object
|
|
media = MediaFileUpload(video_path, mimetype="video/*", resumable=True)
|
|
|
|
print(f"📤 Uploading {video_path} to YouTube...")
|
|
|
|
# Execute the video insert request
|
|
request = youtube.videos().insert(
|
|
part="snippet,status",
|
|
body=request_body,
|
|
media_body=media
|
|
)
|
|
|
|
response = request.execute()
|
|
video_id = response["id"]
|
|
youtube_url = f"https://www.youtube.com/watch?v={video_id}"
|
|
|
|
print(f"✅ Uploaded to YouTube: {youtube_url}")
|
|
|
|
# Record the YouTube URL in the metadata for archive history
|
|
metadata.setdefault("youtube_url", []).append(youtube_url)
|
|
|
|
# Persist the metadata archive only if we're not in DEBUG mode
|
|
if not DEBUG:
|
|
save_metadata_record(video_path, metadata)
|
|
|
|
return youtube_url
|
|
|
|
def get_authenticated_service():
|
|
"""
|
|
Returns an authenticated YouTube API service using Application Default Credentials.
|
|
This requires that `gcloud auth application-default login` has been run successfully,
|
|
or that a service account token is available in the environment.
|
|
|
|
Returns:
|
|
googleapiclient.discovery.Resource: The YouTube API client object.
|
|
"""
|
|
credentials, _ = google.auth.default(
|
|
scopes=["https://www.googleapis.com/auth/youtube.upload"]
|
|
)
|
|
return build("youtube", "v3", credentials=credentials)
|