Automating Content Creation with Python: Obtaining Clips from Twitch
Tags: python, api, showdev, tutorial
Published: 2023-01-25 18:51:49

This is a continuation of a multi-part 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](https://dev.to/viniciusenari/automating-content-creation-with-python-a-guide-to-building-a-twitch-highlights-bot-part-1-1h6m).

## Retrieving and Downloading the Most Viewed Clips

### Using the Twitch API

As before mentioned, I used the Twitch API to retrieve the most viewed clips. To access the Twitch API, you must first have a Twitch account and register an application on [dev.twitch.tv/console](https://dev.twitch.tv/console). You will get a `Client ID` and a `Client Secret`. Once you have these credentials, you can make a post request to https://id.twitch.tv/oauth2/token to receive a token in response. With this token, you can make requests to the Twitch API endpoints.

You can refer to this more [in-depth guide](https://dev.twitch.tv/docs/api/get-started/) on how to get started using the Twitch API.

In Python, you can use the `requests` library to request to authenticate.
```python
import requests

class TwitchAPI():

    def __init__(self):
        self.headers = None

    def auth(self, client_id, client_secret):
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded',
        }

        data = f'client_id={client_id}&client_secret={client_secret}&grant_type=client_credentials'

        try:
            response = requests.post('https://id.twitch.tv/oauth2/token', headers=headers, data=data)
            response.raise_for_status()
        except requests.exceptions.HTTPError as err:
            raise SystemExit(err)
        except requests.exceptions.RequestException as err:
            raise SystemExit(err)
            
        bearer = response.json()['access_token']

        self.headers = {
            'Authorization': f'Bearer {bearer}',
            'Client-Id': client_id,
        }
```


### Retrieving Clips

The Twitch API offers an [endpoint](https://dev.twitch.tv/docs/api/reference/#get-clips) that enables developers to retrieve information about specific clips. This endpoint allows developers to query for clips from a broadcaster or game or by using particular clip IDs. In this application, the request query parameters that were utilized include:
- `game_id` to query for clips from a specific game.
- `started_at` and `ended_at` to select a particular period in which the clips were created.
- `first` to specify the number of clips that must be returned.

You can use the [Get Top Games endpoint](https://dev.twitch.tv/docs/api/reference/#get-top-games) from the Twitch API to get information about the most watched games on Twitch at the moment, which includes the games' IDs. If you want to know the ID of a game that is not on the top games being watched, you can use the [Get Games endpoint](https://dev.twitch.tv/docs/api/reference/#get-games). For my project, getting the IDs of the top games is enough since they are the games that are more likely to attract an audience to a YouTube channel. You can store the game IDs in a Python dictionary and then use this data to query for the top clips.

Below is an example of how you can store the game's IDs in a dictionary
```python
import requests
from project.twitch_api import TwitchAPI
from project.utils import client_id, client_secret

api = TwitchAPI()
api.auth(client_id, client_secret)

def get_top_games(self):
	url = 'https://api.twitch.tv/helix/games/top'
	response = requests.get(url, params={'first':100}, headers=api.headers)

	games_id = {}
	for game in response.json()['data']:
		games_id[game['name']] = game['id']
		
	return games_id

games_id = get_top_games()
```

The last step before obtaining the clips is to add an option to filter them by language, as the API does not allow queries for clips in a particular language. This way, it will be easier to create compilations of clips that target more specific audiences, as opposed to having clips in different languages.

In summary, the process involves requesting clips, filtering them based on desired languages, saving relevant information, and continuing until it has the desired number of clips. The information of each clip in a `ClipContent` object
```python
class ClipContent:

    def __init__(self, url, broadcaster_id, broadcaster_name, game_id, creator_name, title, thumbnail_url, duration, path):
        self.url = url
        self.broadcaster_id = broadcaster_id
        self.broadcaster_name = broadcaster_name
        self.game_id = game_id
        self.title = title
        self.thumbnail_url = thumbnail_url
        self.duration = duration
        self.path = path
```

If you want to check how I implemented it, you can find the code on my GitHub repository at this [link](https://github.com/viniciusenari/twitch-highlights-bot/blob/main/project/clips.py)

### Downloading the Clips

Having obtained information about the clips, one can proceed to download them. There is no direct method to download clips via the API. Still, it is possible to do so using its information. A technique that works most of the time involves utilizing the thumbnail URL of each clip.

A clip thumbnail URL looks like this:
`https://clips-media-assets2.twitch.tv/jTk1-Xmig5ji1Dll05ivnA/AT-cm%7CjTk1-Xmig5ji1Dll05ivnA-preview-260x147.jpg`

Removing the "-preview-260x147.jpg" from the URL and adding a ".mp4" extension can generate a valid address for downloading the clip. This method may not work for older clips, but it has worked for recent clips in my testing.

Here is an example of how you can download the clip from the thumbnail URL using Python.
```python
def download_clip(clip):
	index = clip.thumbnail_url.find('-preview')
	clip_url = clip.thumbnail_url[:index] + '.mp4'
	r = requests.get(clip_url)

	if r.headers['Content-Type'] == 'binary/octet-stream':
		if not os.path.exists('files/clips'): os.makedirs('files/clips')
		with open(clip.path, 'wb') as f:
			f.write(r.content)

	else:
		print(f'Failed to download clip from thumb: {clip.thumbnail_url}')
```

### Conclusion

In this part of the series, I covered how to use the Twitch API to get information on the most popular clips and download them. In the [next part](https://dev.to/viniciusenari/automating-content-creation-with-python-a-guide-to-building-a-twitch-highlights-bot-part-3-pk9), I will cover how I use the MoviePy library to edit videos. Please comment or reach out if you have any questions.