This is the last part of the series on building a YouTube content creation bot that utilizes Twitch clips. If you have yet to see it, be sure to start with the first part.
Uploading the Video to Youtube
Generating Title, Description, Tags and Thumbnail
We have completed the video, but before uploading it, several other fields must be filled out when uploading it to YouTube, such as the title, description, tags, and thumbnail. But, these can also be created from the information we obtained through the Twitch API.
A simple title can be created by including the name of the game the compilation of clips is from, and the number of clips included. Additionally, we can specify that these are the top most-watched clips of the week.
<game_name> Clips of the Week"
In the description, I want to include the time range when the clips were created, the languages the clips were taken from and provide a list of the clips and their URLs. Additionally, it is possible to add timestamps for each clip by utilizing the individual duration of each clip to calculate the values.
Here is an example of a description created from the clips' information:
Tags are keywords that are related to the video, they are not visible to the viewers, but they play an essential role in making the video more discoverable. As all the videos will be compilations of gaming highlights from Twitch, many general tags such as "twitch" and "gaming" can be added to each video. Additionally, more specific tags can be added, such as the names of the broadcasters and the game's name, using the previously collected information. In the program, I initialize a set, so there are no repetitions, with the available tags, and I loop through the clip's info adding the specific information from each clip. After that, I convert the set into an array.
The thumbnail is an image that represents the video and can be created in various ways. The template I used consists of displaying the words "Top
<game_name> Twitch Clips" on it and featuring a grid of individual clip thumbnails as the background. The number of thumbnails in the grid is determined by the
floor(sqrt(number_of_clips)) function. I used abbreviations for some games with longer names to save space and make the thumbnail more appealing. For instance, instead of displaying "League of Legends" in the thumbnail, it will show "LOL."
Here is an example of the thumbnail:
If you want to check the specific code for creating the title, description, tags and thumbnail here is the link
Uploading with the Youtube API
Now that I have the video and all the relevant metadata, I will upload the video to Youtube. For this, I utilized the Youtube API. I will not go into detail on how to do it since they already provide an excellent guide for how to start using the Youtube API with Python. You need to download the Python libraries to authenticate with Google, set up a project on Google Cloud and then you will be able to download the API credentials as JSON file.
Google provides code snippets for many actions that you may want to make using the API in this website: developers.google.com/youtube/v3/code_samples/code_snippets. I utilized the code they already provided under the "videos" resource and "insert" method. The only problem is that when the video takes long to upload, there will be an error. To fix that, I found you need to put in place a resumable upload that will resume the video upload if it times out. Here is a sample code.
Besides the video, I also need to upload the category ID (for gaming, it's 20) and the privacy status (I set it to "Public" so the video will be discoverable immediately after upload). After the video is uploaded, I'll use the returned video ID to upload the thumbnail in a separate request.
This is a snippet of the code I used to upload videos to YouTube
def upload_thumbnail(self, video_id, file_path): print('Uploading thumbnail...') request = self.youtube.thumbnails().set( videoId=video_id, media_body=file_path ) response = request.execute() print(response) def upload_video(self, file_path, video_content): body = dict( snippet=dict( title=video_content.title, description=video_content.description, tags=video_content.tags, categoryId=video_content.category_id ), status=dict( privacyStatus=video_content.privacy_status ) ) insert_request = self.youtube.videos().insert( part=",".join(body.keys()), body=body, media_body= MediaFileUpload( file_path, chunksize=-1, resumable=True) ) video_id = self.resumable_upload(insert_request) self.upload_thumbnail(video_id, 'files/youtube/thumbnail.png')
With this, I end the series about my project that automates collecting Twitch clips, creating a video compilation, and uploading it to YouTube. Overall, this project shows the power of automation and APIs to create and distribute content efficiently and effectively. Despite this, the project still has several limitations that prevent it from being on par with channels managed by humans. Here are some examples:
- When it gets clips using the Twitch API for a specific category, many clips that are returned are from people who were streaming under that category. Still, the clip is unrelated to that category. For example, a streamer playing League of Legends might only show their camera between games. An event unrelated to the game might occur, resulting in a famous clip under the "League of Legends" category.
- Many clips may need knowledge of the streamer's context to be understood, making them less suitable to include in compilations that an audience may view without that context.
- Many YouTube channels that post similar content edit the clips to make them more entertaining. They do this by zooming in on important moments, highlighting areas of interest with red circles, adding sound effects, and many other things.
I hope you enjoyed reading this. If you have any questions, please leave them in the comments. If you want to check the source code or look at the Youtube channel I created to test it, here are the links:
- GitHub Repository: github.com/viniciusenari/twitch-highlights-bot
- YouTube Channel: youtube.com/@mostwatchedtwitchclips
Top comments (0)