Skip to content

Commit

Permalink
TitleDescriptionUpdater - Add subtitle uploading
Browse files Browse the repository at this point in the history
The title updater script can now go through the list of subtitle files in a folder, and automatically upload the subtitles to a video
  • Loading branch information
ThioJoe committed Jan 6, 2023
1 parent a369536 commit 54131c7
Showing 1 changed file with 123 additions and 18 deletions.
141 changes: 123 additions & 18 deletions TitleDescriptionUpdater.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# Script to automatically update a YouTube video with the translated title, description, and subtitles for each language
import auth
from googleapiclient.errors import HttpError
from googleapiclient.http import MediaFileUpload
import copy
import json
import os
import sys
import langcodes

videoID = "abcdefghijkl"
translatedJsonFile = r"output\Translated Items.json"
subtitlesFolder = r"output"

updateTitleAndDescription = True
uploadSubtitles = True

# Override language codes, like for localization. Put the original on the left, and the new on the right
overRiddenLangCodes = {
Expand All @@ -20,6 +28,80 @@

YOUTUBE_API = auth.youtube_authentication()

# ---------------------------------------------------------------------------------------

################################ Subtitles ################################
if uploadSubtitles:
# Process subtitles to upload
subtitleFilesDict = {}

# Get list of subtitle files in the directory
for file in os.listdir(subtitlesFolder):
if file.endswith(".srt"):
nameNoExt = os.path.splitext(file)[0]
# Get the language code from the end of the filename. Assumes the code will be separated by ' - '
if ' - ' in nameNoExt:
parsedLanguageCode = nameNoExt.split(' - ')[-1].strip()
else:
# Print error and ask whether to continue
print(f"\nWARNING: Could not find language code in filename: {file}")
print("\nTo read the language code, separate the language code from the rest of the filename with: ")
print(" ' - ' (a dash surrounded by spaces)")
print("For example: 'Whatever Video - en-us.wav'")
print("Enter 'y' to skip that track and conitnue, or enter anything else to exit.")

userInput = input("Continue Anyway? (y/n): ")
if userInput.lower() != 'y':
sys.exit()

# Check if the language code is valid, if so save to dictionary for next steps
try:
langObject = langcodes.get(parsedLanguageCode)
threeLetterCode = langObject.to_alpha3()
languageDisplayName = langcodes.get(threeLetterCode).display_name()
# Add to dictionary
subtitleFilesDict[parsedLanguageCode] = file

except:
print(f"\nWARNING: Language code '{parsedLanguageCode}' is not valid for file: {file}")
print("Enter 'y' to skip that track and conitnue, or enter anything else to exit.")
userInput = input("\nContinue Anyway and Skip File? (y/n): ")
if userInput.lower() != 'y':
sys.exit()


def list_captions(videoID):
results = auth.YOUTUBE_API.captions().list(
part="snippet",
videoId=videoID
).execute()
return results

#captionsList = list_captions(videoID)


def upload_caption(videoID, language, name, file):
# Convert file to bytes
subtitleData = MediaFileUpload(file, mimetype="text/plain", resumable=True)

insert_result = auth.YOUTUBE_API.captions().insert(
part="snippet",
body=dict(
snippet=dict(
videoId=videoID,
language=language,
name=name,
isDraft=False
)
),
media_body=subtitleData
).execute()
pass

# ---------------------------------------------------------------------------------------

################################ Title and Description ################################

def get_video_info(videoID):
response = YOUTUBE_API.videos().list(
part = "snippet,localizations",
Expand Down Expand Up @@ -61,14 +143,27 @@ def update_title_and_description(videoID, translatedJson):
"description": description
}

# Send request to update localization
localization_result = YOUTUBE_API.videos().update(
part = "localizations",
body = {
"id": videoID,
"localizations": newLocals
},
).execute()
try:
# Send request to update localization
localization_result = YOUTUBE_API.videos().update(
part = "localizations",
body = {
"id": videoID,
"localizations": newLocals
},
).execute()

except HttpError as hx:
print(f"An HTTP error {hx.resp.status} occurred:\n{hx.content}")
errorMessage = str(hx.error_details[0]['message'])
errorReason = str(hx.error_details[0]['reason'])
if errorReason == "insufficientPermissions":
print(f"Error: {errorMessage}.\nThis script requires a different set of permissions for use with YouTube.")
print("Create a separate project in the Google Cloud Platform, and follow these steps:")
print(" - Enable the YouTube Data API, grant the scopes: https://www.googleapis.com/auth/youtube.force-ssl")
print(" - Save the credentials file, but for this one call it 'yt_client_secrets.json'")

# ---------------------------------------------------------------------------------------

def get_video_title(videoID):
try:
Expand All @@ -87,7 +182,9 @@ def get_video_title(videoID):
else:
print("Something went wrong. No video found.")
return None


# ---------------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------------

# Get video title to confirm
Expand All @@ -102,14 +199,22 @@ def get_video_title(videoID):
elif choice.lower() == "y":
pass

try:
# ---------------------------------------------------------------------------------------

if updateTitleAndDescription:
# Update titles and descriptions
print("\nUpdating titles and descriptions...")
update_title_and_description(videoID, translatedJson)
except HttpError as hx:
print(f"An HTTP error {hx.resp.status} occurred:\n{hx.content}")
errorMessage = str(hx.error_details[0]['message'])
errorReason = str(hx.error_details[0]['reason'])
if errorReason == "insufficientPermissions":
print(f"Error: {errorMessage}.\nThis script requires a different set of permissions for use with YouTube.")
print("Create a separate project in the Google Cloud Platform, and follow these steps:")
print(" - Enable the YouTube Data API, grant the scopes: https://www.googleapis.com/auth/youtube.force-ssl")
print(" - Save the credentials file, but for this one call it 'yt_client_secrets.json'")

if uploadSubtitles:
# Upload captions
for langCode, fileName in subtitleFilesDict.items():
# Get language display name
languageDisplayName = langcodes.get(langCode).display_name()
# Get file path
filePath = os.path.join(subtitlesFolder, fileName)
# Upload the caption
print("\nUploading caption for language: " + languageDisplayName + " (" + langCode + ")")
upload_caption(videoID, langCode, "", filePath) # Use empty string as the name, so it will apply as the default caption for that language

print("\nDone!")

0 comments on commit 54131c7

Please sign in to comment.