Skip to content

Commit

Permalink
Merge pull request #24 from offish/v1.5.0
Browse files Browse the repository at this point in the history
v1.5.0
  • Loading branch information
offish authored Jan 24, 2021
2 parents 95d9927 + 590b4af commit 2f79280
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 296 deletions.
80 changes: 29 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Automatically make video compilations of the most viewed Twitch clips and upload
## Features
* Downloads the most popular clips from given `channel` or `game`
* Downloads only the needed clips to reach `VIDEO_LENGTH`
* Upload automatically to YouTube using Selenium and Firefox
* Customizable
* Option for concatninating clips into one video
* Option for custom intro, transition and outro
* Option for custom resolution
Expand All @@ -32,104 +34,80 @@ this repo. Only a couple of titles and thumbnails have been changed.
## Installation
Download the repo as ZIP and unzip it somewhere accessible.

To install all the packages needed you need to run this command (has to be in
the right directory).
To install all the packages needed, you have to run this command. Has to be in same directory as the `requirements.txt` and `main.py` files are.

```
pip install -r requirements.txt
```

Download [geckodriver](https://github.com/mozilla/geckodriver/releases) and place the .exe file inside `C:\Users\USERNAME\AppData\Local\Programs\Python\Python37`.

## Configuration
### Creating your Twitch Application
Go to https://dev.twitch.tv/console and register a new application.
The name of the application does not matter. Set "OAuth Redirect URLs" to https://twitchapps.com/tokengen/
Set category to "Application Integration" or "Other".
You will now see your Client ID, copy this ID.
Go to [`config.py`](twitchtube/config.py), find CLIENT_ID and paste it inside apostrophes.
Go to [`config.py`](twitchtube/config.py), find `CLIENT_ID` and paste it inside apostrophes.

### Getting your OAuth Token
Now head over to https://twitchapps.com/tokengen/ and paste in your Client ID.
Scopes does not matter in our case. Click "Connect" and then authorize with Twitch.
Copy your OAuth Token, go to [`config.py`](twitchtube/config.py), find `OAUTH_TOKEN` and paste it inside the apostrophes.

### Creating your Google Project
Go to https://console.cloud.google.com/ and create a new project.
Name does not matter.

### Enabling YouTube Data API v3
Click on the menu on the left side of your screen and navigate to "APIs & Services".
Hover over this button and click "Library".
Search for "YouTube Data API v3" and click the first result.
Enable this API.

### Getting your client_secret
When you have clicked "Enable" you should now be under the "Overview" tab.
Click "Credentials" and then "+ Create Credentials".
You will now see 3 options, click "OAuth client ID".
Now you might need to configure consent screen.
If you need to configure this, click "External" and then "Create".
Write something in the application name field, might be wise to name it something you will remember like "twitchtube" or
"YouTube Twitch Bot".
Now you will see your application, go to "Credentials" again and click "+ Create Credentials" and then "OAuth client ID".
Set application type to Desktop app and name it whatever.
Click "Ok", and then click the download icon.
Open the JSON file that gets downloaded, select everything in this fiel and paste it into the [`client_secret.json`](twitchtube/client_secret.json) file.

### Adding/removing to LIST
If you want to add a game or channel, you simply write the name of the game how it appears on Twitch inside the `LIST` list in [`config.py`](twitchtube/config.py).
If you want to add Rust for example, `LIST` should look like this:
### Setting up Firefox
Open Firefox and create a new profile for Selenium, (this is not needed, but highly recommended). Go to `about:profiles` and click "Create a New profile", name it "Selenium" or whatever. When you have done that, copy the "Root Directory" path of that profile and paste it into the `ROOT_PROFILE_PATH` in [`config.py`](twitchtube/config.py). Now click "Launch profile in new browser". Go to [YouTube](https://youtube.com) and login to the account you want to use with twitchtube. Voilà, you are now set. You migth want to set another profile to your default profile though.

### Adding and removing games or channels to LIST
**`LIST` MUST MATCH `MODE`. IF `MODE` IS SET TO `GAME`, THERE SHOULD ONLY BE GAMES INSIDE OF `LIST`, SAME GOES FOR `CHANNEL`.**

If you want to add a game or channel, you simply write the name of the game or channel, how it appears on Twitch, inside the `LIST` in [`config.py`](twitchtube/config.py).
If you want to add Rust for example, then `LIST` should look like this:

```python
LIST = ['Rust', 'Just Chatting', 'Team Fortress 2']
LIST = ["Rust", "Just Chatting", "Team Fortress 2"]
```

Last entry in the list should not have a comma.

If you only want to have 1 game or channel, `LIST` should look like this:
If you only want to have one game or channel, `LIST` should look like this:

```python
LIST = ['Just Chatting']
LIST = ["Just Chatting"]
```

Example:

```python
LIST = ['Just Chatting']
MODE = "game"

LIST = ["Just Chatting"]

TITLE = "Most Viewed Just Chatting Clips - 24.01.2021"

# Tags are currently not supported
TAGS = {
'Just Chatting': 'just chatting, just chatting twitch, just chatting twitch highlights'
"Just Chatting": "just chatting, just chatting twitch, just chatting twitch highlights"
}

# Descriptions are though
DESCRIPTIONS = {
'Just Chatting': 'The most viewed Just Chatting clips today.\n\n{}\n#Twitch #TwitchHighlights #Just Chatting'
"Just Chatting": "The most viewed Just Chatting clips today.\n\n{}\n #Twitch #TwitchHighlights #Just Chatting"
}
```

Counter-Strike: Global Offensive is currently not supported since folders can't include colons in their folder name.

## Explanation
The script starts off by checking every game or channel listed in the config. It will then create a folder with
the current date as folder name and inside this folder, it will create another folder for the
with the current game or channel as folder name. It will send a request to Twitch's Kraken API
and ask for the top 100 clips. It will then save this data in a JSON
file called `clips.json`. It will loop through the clip URLs and download each clip
till it reaches the limit specifed in the config. When the limit is reached, which means the video is
long enough it will take all the mp4 files in the game or channel folder and concatenete these clips into one
video (if specified). If time limit given is too big, it will just continue anyways. When the video is
done rendering, it will upload it to YouTube (if specified). When the video is uploaded it will delete
the clips (if specified) and create a new folder for the next game or channel in `LIST` (if any) and
redo the process written above.
Counter-Strike: Global Offensive is currently not supported since folders cannot include colons in their folder name.


## Running
To run the script run this command (must be in the correct folder).
To run the bot, use this command. Has to be in same directory as the `requirements.txt` and `main.py` files are.

```
python main.py
```

## Note
I've only tested this script using Python 3.7.3, but should work with later versions.
I have only tested this bot using Windows 10 and Python 3.7.3, but should work on other operating systems, and Python 3 versions.

## License
MIT License
Expand Down
13 changes: 8 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from twitchtube.logging import Log
from twitchtube.config import *
from twitchtube.upload import upload_video_to_youtube
from twitchtube.upload import Upload
from twitchtube.utils import create_video_config, get_date
from twitchtube.clips import get_clips, download_clips
from twitchtube.video import render
Expand Down Expand Up @@ -54,10 +54,13 @@
dump(config, f, indent=4)

if UPLOAD_TO_YOUTUBE and RENDER_VIDEO:
try:
upload_video_to_youtube(config)
except JSONDecodeError:
log.error("Your client_secret is empty or has wrong syntax")
upload = Upload(ROOT_PROFILE_PATH, config, SLEEP)
was_uploaded, video_id = upload.upload()

if was_uploaded:
log.info(f"{video_id} was successfully uploaded to YouTube")
else:
log.error("Video was not successfully uploaded to YouTube")

if DELETE_CLIPS:
# Get all the mp4 files in the path and delte them
Expand Down
5 changes: 1 addition & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
moviepy==1.0.3
colorama
httplib2
google-auth-oauthlib
google-api-python-client
google-auth
selenium
2 changes: 1 addition & 1 deletion twitchtube/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__title__ = "twitchtube"
__author__ = "offish"
__license__ = "MIT"
__version__ = "1.4.1"
__version__ = "1.5.0"
1 change: 0 additions & 1 deletion twitchtube/client_secret.json

This file was deleted.

11 changes: 9 additions & 2 deletions twitchtube/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
# Twitch OAuth Token
OAUTH_TOKEN = ""

# Path to the Firefox profile were you are logged into YouTube
ROOT_PROFILE_PATH = ""

# How many seconds Firefox should sleep for when uploading
SLEEP = 3

# Paths
PATH = str(pathlib.Path().absolute()).replace("\\", "/")
Expand Down Expand Up @@ -93,10 +98,12 @@
# If empty, it would take the title of the first clip, and add "- *category* Highlights Twitch"
TITLE = ""

# 20 for Gaming
CATEGORY = 20
# Category
# Not supported yet
CATEGORY = 20 # 20 for gaming

# Tags
# Not supported yet
TAGS = {
"Just Chatting": "just chatting, just chatting clips, just chatting twitch clips",
"Team Fortress 2": "tf2, tf2 twitch, tf2 twitch clips",
Expand Down
22 changes: 22 additions & 0 deletions twitchtube/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
YOUTUBE_URL = "https://www.youtube.com"
YOUTUBE_STUDIO_URL = "https://studio.youtube.com"
YOUTUBE_UPLOAD_URL = "https://www.youtube.com/upload"
TIMEOUT = 3

DESCRIPTION_CONTAINER = "/html/body/ytcp-uploads-dialog/paper-dialog/div/ytcp-animatable[1]/ytcp-uploads-details/div/ytcp-uploads-basics/ytcp-mention-textbox[2]"
MORE_OPTIONS_CONTAINER = "/html/body/ytcp-uploads-dialog/paper-dialog/div/ytcp-animatable[1]/ytcp-uploads-details/div/div/ytcp-button/div"
TEXTBOX = "textbox"
TEXT_INPUT = "text-input"
RADIO_LABEL = "radioLabel"
STATUS_CONTAINER = "/html/body/ytcp-uploads-dialog/paper-dialog/div/ytcp-animatable[2]/div/div[1]/ytcp-video-upload-progress/span"
NOT_MADE_FOR_KIDS_LABEL = "NOT_MADE_FOR_KIDS"
NEXT_BUTTON = "next-button"
PUBLIC_BUTTON = "PUBLIC"
VIDEO_URL_CONTAINER = "//span[@class='video-url-fadeable style-scope ytcp-video-info']"
VIDEO_URL_ELEMENT = "//a[@class='style-scope ytcp-video-info']"
HREF = "href"
UPLOADED = "uploaded"
ERROR_CONTAINER = '//*[@id="error-message"]'
VIDEO_NOT_FOUND_ERROR = "Could not find video_id"
DONE_BUTTON = "done-button"
INPUT_FILE_VIDEO = "//input[@type='file']"
Loading

0 comments on commit 2f79280

Please sign in to comment.