adffgdsadfvbghfd

thumbnail averager script

Sep 28th, 2025
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.76 KB | Source Code | 0 0
  1. # Script for averaging the thumbnails of all the videos uploaded by a YouTube
  2. # channel with the YouTube Data API.
  3. # This script can also be used on phones.
  4. #
  5. # --- How to use it ---
  6. #
  7. # Part 1: Getting an API key
  8. #
  9. # 1.  Go to https://console.cloud.google.com/ and sign in to your
  10. #     Google account.
  11. # 2.  Click the "Select a project" button at the top, on phones that.
  12. #     button can be found by pressing the hamburger button on the left.
  13. # 3.  Click "New project", on phones that button can be found by pressing the
  14. #     three dots on the right.
  15. # 4.  Type a name for your project, skip the rest of the page and click
  16. #     "Create".
  17. # 5.  Click the "Select a project" button again and click on the link for.
  18. #     your project.
  19. # 6.  Using the search bar (or button) at the to,p search for
  20. #     "YouTube Data API v3" and click on the top result.
  21. # 7.  Press the enable button.
  22. # 8.  Click on the "Credentials" tab on the left, on phones, it's in the
  23. #     "APIs and services" menu on the top.
  24. # 9.  Click the "Create credentials" menu on the top (press the three dots
  25. #     first on a phone) and select "API key".
  26. # 10. Type a name for your API key and scroll down to the bottom and press
  27. #     "Create" (ignore all the other options).
  28. # 11. Click the copy button.
  29. # 12. Type the API key somewhere (it a text file or your notes app)
  30. #
  31. # Part 2: Setting and using up the script
  32. #
  33. # First, download this file using the "download" button
  34. # From here, it depends on what device you are using,
  35. # Windows is the easiest to use, but this script will also work on Andriod.
  36. # Scroll down to find the operating system you are using.
  37. #
  38. # Method 1: Using on Windows
  39. # 1. Go to "https://www.python.org/downloads/windows/", scroll down and click
  40. #    on "Windows installer (64-bit)"
  41. # 2. Open the installer file and click "Install now", after it installs click
  42. #    on "Disable path length limit" if you have admin privileges.
  43. # 3. Using the start menu, search and open the "Command prompt".
  44. # 4. Type "python -m pip install -U --upgrade pip", then type
  45. #    "pip install -U numpy pillow requests" to install all the necessary
  46. #    software to run the script.
  47. # 5. Move the script to a new folder.
  48. # 6. Double click on the script to run it.
  49. #
  50. # Method 2: Using on Android
  51. # 1. Install Termux from the Play Store (or wherever you get your apps).
  52. # 2. While it's installing, go to the downloads folder in your file manager
  53. #    and create a new folder inside it.
  54. # 3. Find the script you downloaded and move it into that folder, and rename
  55. #    it.
  56. # 4. When the Termux app finishes installing, open it. You should see
  57. #    a prompt that says "~ $", everything before the "$" is what folder
  58. #    you're in, "~" is the home folder, the prompt also means it's
  59. #    ready to recieve commands.
  60. # 5. Type the command "pkg update", and press enter (do it after every command)
  61. #    and once it finishes type "pkg upgrade" and your Termux install will be
  62. #    up to date.
  63. # 6. Run the commands "pkg install python python-pip python-numpy python-pillow"
  64. #    and after that "pip install requests" to install all the things
  65. #    required to run the script.
  66. # 7. Run the command "termux-setup-storage" to allow the app to acces the
  67. #    script and store the images it creates.
  68. # 8. Type "cd '~/storage/downloads/[name of the folder that you created]'"
  69. #    (with 'these' quotes included) to change to the folder with the script
  70. #    inside it.
  71. # 9. Finally, run the command "python '[name of the script file].py'"
  72. #    (also with 'these' quotes included) to run the script.
  73. #
  74. # To cancel the script before it's finished, press the "ctrl" and the Z key.
  75. # To run the script again, press the up arrow and press enter again.
  76. # On a new terminal session (if you're back to the "~ $" prompt), press the
  77. # up arrow to run the commands from step 8 and 9 again.
  78.  
  79. from io import BytesIO
  80. from requests import get
  81. from PIL import Image
  82. from numpy import asarray, uint8, zeros, ndarray, pow, float32, where, less
  83. from pathlib import Path
  84.  
  85. thumbnail_resolution = (1280, 720) # Resolution of the thumbnail
  86. max_thumbnails = 0 # Number of thumbnails averaged, 0 for no limit
  87.  
  88. rescaling_function = Image.BICUBIC # Method used to convert resolution
  89.  
  90. def get_api_key(root_directory: Path) -> str:
  91.     try:
  92.         with open(root_directory.joinpath("api_key.txt"), encoding="utf-8") as f:
  93.             api_key = f.read().rstrip("\r\n")
  94.     except FileNotFoundError:
  95.         api_key = input("No api_key.txt file found, please type key: ")
  96.         with open(root_directory.joinpath("api_key.txt"), mode="w", encoding="utf-8") as f:
  97.             f.write(api_key + "\n")
  98.  
  99.     return api_key
  100.  
  101. def get_full_playlist(api_key: str, playlist_id: str, part: str) -> list:
  102.     max_items = 50
  103.     url = "https://www.googleapis.com/youtube/v3/playlistItems"
  104.     payload = {"key": api_key, "part": part, "playlistId": playlist_id, "maxResults": max_items}
  105.     response = get(url, params=payload)
  106.     json = response.json()
  107.  
  108.     items = json["items"]
  109.  
  110.     totalCount = json["pageInfo"]["totalResults"]
  111.  
  112.     while len(items) < totalCount:
  113.         payload = {"key": api_key, "part": part, "pageToken": json["nextPageToken"], "playlistId": playlist_id, "maxResults": max_items}
  114.         response = get(url, params=payload)
  115.         json = response.json()
  116.  
  117.         items += json["items"]
  118.  
  119.     return items
  120.  
  121. def get_best_thumbnail(thumbnails: "dict[str, dict]") -> "dict":
  122.     return thumbnails.get("maxres") or \
  123.         thumbnails.get("standard") or \
  124.         thumbnails.get("high") or \
  125.         thumbnails.get("medium") or \
  126.         thumbnails.get("default")
  127.  
  128. def gamma_correct(array: ndarray, inverse=False) -> ndarray:
  129.     if inverse:
  130.         return where(less(array, 0.04045), array / 12.92, pow((array + 0.055) / 1.055, 2.4))
  131.     else:
  132.         return where(less(array, 0.0031308), array * 12.92, 1.055 * pow(array, 1 / 2.4) - 0.055)
  133.  
  134. def download_images(playlist: "list[dict]") -> ndarray:
  135.     summed_array = zeros(tuple(reversed(thumbnail_resolution)) + (3,), dtype=float32)
  136.  
  137.     for index, video in enumerate(playlist):
  138.         url = get_best_thumbnail(video["snippet"]["thumbnails"])["url"]
  139.  
  140.         response = get(url)
  141.         image = Image.open(BytesIO(response.content))
  142.         if image.size != thumbnail_resolution:
  143.             suffix = ", resized from " + str(image.size[0]) + "x" + str(image.size[1])
  144.             image = image.resize(thumbnail_resolution, Image.BICUBIC)
  145.         else:
  146.             suffix = ""
  147.  
  148.         array = asarray(image).astype(float32) / 255
  149.         summed_array += gamma_correct(array, inverse=True)
  150.         print(
  151.             "\x1b[1G\x1b[2K" + \
  152.             "Downloading images " + \
  153.             str(index + 1) + \
  154.             "/" + str(len(playlist)) + \
  155.             suffix,
  156.             end="", flush=True
  157.         )
  158.  
  159.     return summed_array
  160.  
  161. def main():
  162.     root_directory = Path(__file__).parent.absolute()
  163.     api_key = get_api_key(root_directory)
  164.     handle = input("Enter channel handle: ")
  165.  
  166.     payload = {"key": api_key, "part": "snippet,contentDetails", "forHandle": handle}
  167.     response = get("https://www.googleapis.com/youtube/v3/channels", params=payload)
  168.     channel = response.json()["items"][0]
  169.  
  170.     print("Retrieving thumbnails for " + channel["snippet"]["title"])
  171.  
  172.     playlist = get_full_playlist(api_key, channel["contentDetails"]["relatedPlaylists"]["uploads"], "snippet")
  173.  
  174.     summed_array = download_images(playlist)
  175.  
  176.     filename = "average-thumbnail-" + handle.lower() + ".png"
  177.     print("\nFinished, saving image as " + filename)
  178.     average_array = (gamma_correct(summed_array / len(playlist)) * 255).astype(uint8)
  179.     image = Image.fromarray(average_array, "RGB")
  180.     image.save(str(root_directory.joinpath(filename)))
  181.  
  182. if __name__ == "__main__":
  183.     main()
Advertisement
Add Comment
Please, Sign In to add comment