I created an updated YouTube video descriptions script, based on my ideas after creating the original, which automates more of my YouTube video uploading process. Multiple videos can be processed at once to avoid constantly having to check on them, so it can run in the background while I do something else and I only have to check it once all the videos are processed. The command line interface also contains arguments for special descriptions before and after the automatically generated description, muting the videos (for cases where people do not want their voice in the videos), writing the generated description to a text file, and/or only creating the upload YAML file without actually uploading the videos.
The videos themselves are recorded using Nvidia GeForce Experience’s Instant Replay, which saves the last 15 minutes (GSF matches are at most 15 minutes and time out after that, so this is a good amount of time) of gameplay, so they are by default untrimmed and may contain stuff before and after the match that should be removed. The script reads the video’s frames (by default, it takes a frame every 2 seconds in the video in order to balance accuracy (not skipping important frames) with runtime (proportional to the number of frames read)) to find the start and end of the actual GSF match and then trims the video to those points (and mutes it if necessary). It uses the OpenCV Python module to preprocess the images to invert them (usually the text is light text on a dark background, which is not ideal for Tesseract) and improve contrast, then Tesseract OCR (through the pytesseract Python module) to read text from the video’s start/end frames, pulling information like the match type, the map, a list of characters on each side (which fulfills my original desire to have this list without too much effort), and the final score. This is also used for determining whether the frame is a start/end frame, by determining whether the score/map name/match type is valid. The start frame to trim to is the first detected start frame after an end frame (since sometimes the end of the previous match also gets recorded into this match’s video) or loading screen frame (loading screens are determined by large black-ish (actually a value of 382.5) rectangles along the side and top of the frame), and the start frame to read the match type, map, and characters from is the last continuous start frame after the trim point. The end frame to trim to and to get the score from is read backwards from the end of the video (and is the first end frame seen).



After all the videos are trimmed and the match start/end information is read from it, there is a manual step where I can fill in information about the match that cannot be read directly from the video by selecting options from a list, similar to the original YouTube video description script: the character I’m playing (if it’s not one that’s already listed as my character), the faction (if there’s no default set for the character), the server (if there’s no default server set for that character), and the ship(s) flown (this is technically possible by matching the ship image at the lower left to possible ships, but I have not tried yet since it’s fast to get it manually and may be difficult to automate) and their builds. Since the OCR is not perfect, there are some functions to fix common issues with things that have been read, and a way to fix any character names that were incorrectly read. It does not handle accents on character names, which are allowed in SWTOR, but I would likely not type them either. There is a confirmation after each video is processed where the manual section can be repeated, in case I make a mistake typing it the first time. Uploading a video can also be skipped if I realize there was something wrong with the trimming or I otherwise no longer want to upload it.


Finally, a YAML file appropriate for youtube-video-upload is generated, containing the description, title, and some default tags, and the videos are uploaded together using the youtube_video_upload Python module. They are uploaded as private so I can wait for YouTube’s processing to finish and check them before publishing them, though in practice I usually don’t watch them. I had to create an API key for YouTube Data API v3 in order to do this, and the paths to the credentials and secrets files are passed in the YAML file. The YAML file also serves as a record of the videos I uploaded, which is a nice plus.
Sometimes, the script gets the start/end point wrong, and I have to manually trim the video. I also created a script for this purpose, which only does the trimming to a certain start and end point, and there is a -trimmed option for the main script to take the start and end points of the video as-is and not try to trim it again. The accuracy was greatly improved by using the loading screen as well as the previous match’s end to determine when the match start can occur, however.
The script can be downloaded at https://drive.google.com/file/d/1qt35xwhWIsBLFNL4aG4bVxidGdtwjxID/view?usp=sharing.