Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Script for averaging the thumbnails of all the videos uploaded by a YouTube
- # channel with the YouTube Data API.
- # This script can also be used on phones.
- #
- # --- How to use it ---
- #
- # Part 1: Getting an API key
- #
- # 1. Go to https://console.cloud.google.com/ and sign in to your
- # Google account.
- # 2. Click the "Select a project" button at the top, on phones that.
- # button can be found by pressing the hamburger button on the left.
- # 3. Click "New project", on phones that button can be found by pressing the
- # three dots on the right.
- # 4. Type a name for your project, skip the rest of the page and click
- # "Create".
- # 5. Click the "Select a project" button again and click on the link for.
- # your project.
- # 6. Using the search bar (or button) at the to,p search for
- # "YouTube Data API v3" and click on the top result.
- # 7. Press the enable button.
- # 8. Click on the "Credentials" tab on the left, on phones, it's in the
- # "APIs and services" menu on the top.
- # 9. Click the "Create credentials" menu on the top (press the three dots
- # first on a phone) and select "API key".
- # 10. Type a name for your API key and scroll down to the bottom and press
- # "Create" (ignore all the other options).
- # 11. Click the copy button.
- # 12. Type the API key somewhere (it a text file or your notes app)
- #
- # Part 2: Setting and using up the script
- #
- # First, download this file using the "download" button
- # From here, it depends on what device you are using,
- # Windows is the easiest to use, but this script will also work on Andriod.
- # Scroll down to find the operating system you are using.
- #
- # Method 1: Using on Windows
- # 1. Go to "https://www.python.org/downloads/windows/", scroll down and click
- # on "Windows installer (64-bit)"
- # 2. Open the installer file and click "Install now", after it installs click
- # on "Disable path length limit" if you have admin privileges.
- # 3. Using the start menu, search and open the "Command prompt".
- # 4. Type "python -m pip install -U --upgrade pip", then type
- # "pip install -U numpy pillow requests" to install all the necessary
- # software to run the script.
- # 5. Move the script to a new folder.
- # 6. Double click on the script to run it.
- #
- # Method 2: Using on Android
- # 1. Install Termux from the Play Store (or wherever you get your apps).
- # 2. While it's installing, go to the downloads folder in your file manager
- # and create a new folder inside it.
- # 3. Find the script you downloaded and move it into that folder, and rename
- # it.
- # 4. When the Termux app finishes installing, open it. You should see
- # a prompt that says "~ $", everything before the "$" is what folder
- # you're in, "~" is the home folder, the prompt also means it's
- # ready to recieve commands.
- # 5. Type the command "pkg update", and press enter (do it after every command)
- # and once it finishes type "pkg upgrade" and your Termux install will be
- # up to date.
- # 6. Run the commands "pkg install python python-pip python-numpy python-pillow"
- # and after that "pip install requests" to install all the things
- # required to run the script.
- # 7. Run the command "termux-setup-storage" to allow the app to acces the
- # script and store the images it creates.
- # 8. Type "cd '~/storage/downloads/[name of the folder that you created]'"
- # (with 'these' quotes included) to change to the folder with the script
- # inside it.
- # 9. Finally, run the command "python '[name of the script file].py'"
- # (also with 'these' quotes included) to run the script.
- #
- # To cancel the script before it's finished, press the "ctrl" and the Z key.
- # To run the script again, press the up arrow and press enter again.
- # On a new terminal session (if you're back to the "~ $" prompt), press the
- # up arrow to run the commands from step 8 and 9 again.
- from io import BytesIO
- from requests import get
- from PIL import Image
- from numpy import asarray, uint8, zeros, ndarray, pow, float32, where, less
- from pathlib import Path
- thumbnail_resolution = (1280, 720) # Resolution of the thumbnail
- max_thumbnails = 0 # Number of thumbnails averaged, 0 for no limit
- rescaling_function = Image.BICUBIC # Method used to convert resolution
- def get_api_key(root_directory: Path) -> str:
- try:
- with open(root_directory.joinpath("api_key.txt"), encoding="utf-8") as f:
- api_key = f.read().rstrip("\r\n")
- except FileNotFoundError:
- api_key = input("No api_key.txt file found, please type key: ")
- with open(root_directory.joinpath("api_key.txt"), mode="w", encoding="utf-8") as f:
- f.write(api_key + "\n")
- return api_key
- def get_full_playlist(api_key: str, playlist_id: str, part: str) -> list:
- max_items = 50
- url = "https://www.googleapis.com/youtube/v3/playlistItems"
- payload = {"key": api_key, "part": part, "playlistId": playlist_id, "maxResults": max_items}
- response = get(url, params=payload)
- json = response.json()
- items = json["items"]
- totalCount = json["pageInfo"]["totalResults"]
- while len(items) < totalCount:
- payload = {"key": api_key, "part": part, "pageToken": json["nextPageToken"], "playlistId": playlist_id, "maxResults": max_items}
- response = get(url, params=payload)
- json = response.json()
- items += json["items"]
- return items
- def get_best_thumbnail(thumbnails: "dict[str, dict]") -> "dict":
- return thumbnails.get("maxres") or \
- thumbnails.get("standard") or \
- thumbnails.get("high") or \
- thumbnails.get("medium") or \
- thumbnails.get("default")
- def gamma_correct(array: ndarray, inverse=False) -> ndarray:
- if inverse:
- return where(less(array, 0.04045), array / 12.92, pow((array + 0.055) / 1.055, 2.4))
- else:
- return where(less(array, 0.0031308), array * 12.92, 1.055 * pow(array, 1 / 2.4) - 0.055)
- def download_images(playlist: "list[dict]") -> ndarray:
- summed_array = zeros(tuple(reversed(thumbnail_resolution)) + (3,), dtype=float32)
- for index, video in enumerate(playlist):
- url = get_best_thumbnail(video["snippet"]["thumbnails"])["url"]
- response = get(url)
- image = Image.open(BytesIO(response.content))
- if image.size != thumbnail_resolution:
- suffix = ", resized from " + str(image.size[0]) + "x" + str(image.size[1])
- image = image.resize(thumbnail_resolution, Image.BICUBIC)
- else:
- suffix = ""
- array = asarray(image).astype(float32) / 255
- summed_array += gamma_correct(array, inverse=True)
- print(
- "\x1b[1G\x1b[2K" + \
- "Downloading images " + \
- str(index + 1) + \
- "/" + str(len(playlist)) + \
- suffix,
- end="", flush=True
- )
- return summed_array
- def main():
- root_directory = Path(__file__).parent.absolute()
- api_key = get_api_key(root_directory)
- handle = input("Enter channel handle: ")
- payload = {"key": api_key, "part": "snippet,contentDetails", "forHandle": handle}
- response = get("https://www.googleapis.com/youtube/v3/channels", params=payload)
- channel = response.json()["items"][0]
- print("Retrieving thumbnails for " + channel["snippet"]["title"])
- playlist = get_full_playlist(api_key, channel["contentDetails"]["relatedPlaylists"]["uploads"], "snippet")
- summed_array = download_images(playlist)
- filename = "average-thumbnail-" + handle.lower() + ".png"
- print("\nFinished, saving image as " + filename)
- average_array = (gamma_correct(summed_array / len(playlist)) * 255).astype(uint8)
- image = Image.fromarray(average_array, "RGB")
- image.save(str(root_directory.joinpath(filename)))
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment