Module sws.youtube
Provides functionality for working with YouTube videos such as:
- Downloading youtube videos
- Pulling video metadata
Examples
Download youtube video to current folder
from sws.youtube import download
download("https://www.youtube.com/watch?v=6j1I3mC0BR0", ".") # Downloads video in current folder
Expand source code
"""Provides functionality for working with YouTube videos such as:
- Downloading youtube videos
- Pulling video metadata
Examples
--------
### Download youtube video to current folder
```
from sws.youtube import download
download("https://www.youtube.com/watch?v=6j1I3mC0BR0", ".") # Downloads video in current folder
```
"""
# Standard library Dependencies
import os # Used for path validation
import logging # Used in logging debug and info messages
import tkinter as tk # Used to setup a gui for selecting files
from typing import Union # Used for type hints with multiple types
from tkinter import filedialog # Used to setup a gui for selecting files
# External Dependencies
from pytube import YouTube # Used to download and get youtube video info
import pytube.exceptions
def _request_path():
"""Prompts user for the link to a youtube video, and path of where to download the video to"""
logging.info("Entering _request_path()")
root = tk.Tk()
root.withdraw()
file_path = str(filedialog.askdirectory(
title="Select Video Output directory",
mustexist=False))
return file_path
def get_video_metadata(video_url:str) -> dict:
"""Gets the metadata of a youtube video
Parameters
----------
video_url : str
The URL of the video
Notes
-----
- Keys include:
- title; The title of the video
- id; The id of the video
- publish_date; The publishing date of the video (as a `datetime.datetime` object)
- age_restricted; A boolean that is True if the video is age restricted
- creator; A string representation of the channel name
- metadata; A raw `pytube.metadata.YouTubeMetadata` object of video metadata
Returns
-------
dict
A dictionary of results (see notes for keys)
Raises
------
ValueError
If the video is inaccessible for any reason
"""
logging.info(f"Entering get_video_metadata(video_url={video_url})")
result = {}
try:
logging.info("Getting video metadata")
video_data = YouTube(video_url)
result["title"] = video_data.title
result["id"] = video_data.video_id
result["publish_date"] = video_data.publish_date
result["age_restricted"] = video_data.age_restricted
result["creator"] = video_data.author
result["metadata"] = video_data.metadata
except pytube.exceptions.RegexMatchError:
raise ValueError(f"Video URL {video_url} does not exist")
except pytube.exceptions.VideoPrivate:
raise ValueError(f"Video URL {video_url} is private")
except pytube.exceptions.MembersOnly:
raise ValueError(f"Video URL {video_url} is Members Only")
except pytube.exceptions.RecordingUnavailable:
raise ValueError(f"Video URL {video_url} does not have a recording for the livestream")
except pytube.exceptions.VideoUnavailable:
raise ValueError(f"Video URL {video_url} does not have an available video")
except pytube.exceptions.LiveStreamError:
raise ValueError(f"Video URL {video_url} is a livestream and cannot be downloaded")
logging.info(f"Exiting get_video_metadata() and returning {result}")
return result
def download(video_url: str, path: Union[str, bool]) -> str:
"""Downloads specified video_url to path
Parameters
----------
video_url : (str)
The full URL you want to download i.e. https://www.youtube.com/watch?v=6j1I3mC0BR0
path : (str or bool)
The path on your system to download the video to, or False to start pathfinding function
Raises
------
ValueError:
If the video is inaccessible for any reason
Returns
-------
str:
A string with 'Downloaded <video title> to <path> as <video_title>.mp4' if file was downloaded, or message 'File <filepath> already exists' if file already existed
Examples
--------
Download youtube video to current folder
```
from sws.youtube import download
download("https://www.youtube.com/watch?v=6j1I3mC0BR0", ".") # Downloads video in current folder
```
"""
logging.info(f"Entering download(video_url={video_url}, path={path})")
if not path:
logging.info("No path found, entering _request_path()")
path = os.path.realpath(f"{_request_path()}")
else:
logging.info(f"Path found {path}, converting to abspath {os.path.abspath(path)}")
path = os.path.abspath(path)
# Get video title if video exists
try:
logging.info("Requesting video data")
video_title = str(YouTube(video_url).title)
except pytube.exceptions.RegexMatchError:
raise ValueError(f"Video URL {video_url} does not exist")
except pytube.exceptions.VideoPrivate:
raise ValueError(f"Video URL {video_url} is private")
except pytube.exceptions.MembersOnly:
raise ValueError(f"Video URL {video_url} is Members Only")
except pytube.exceptions.RecordingUnavailable:
raise ValueError(f"Video URL {video_url} does not have a recording for the livestream")
except pytube.exceptions.VideoUnavailable:
raise ValueError(f"Video URL {video_url} does not have an available video")
except pytube.exceptions.LiveStreamError:
raise ValueError(f"Video URL {video_url} is a livestream and cannot be downloaded")
logging.info("Checking if ouput file already exists")
if os.path.exists(os.path.join(path, video_title)):
logging.info(f"Found existing output file, exiting download() and returning 'File {os.path.join(path, video_title)} already exists'")
return f"File {os.path.join(path, video_title)} already exists"
print(f"Downloading {video_title} to {path}")
YouTube(video_url).streams.get_highest_resolution().download(path)
logging.info(f"Found existing output file, exiting download() and returning 'Downloaded {video_title} to {path} as {video_title}.mp4'")
return f"Downloaded {video_title} to {path} as {video_title}.mp4"
Functions
def download(video_url: str, path: Union[bool, str]) ‑> str
-
Downloads specified video_url to path
Parameters
video_url
:(str)
- The full URL you want to download i.e. https://www.youtube.com/watch?v=6j1I3mC0BR0
path
:(str
orbool)
- The path on your system to download the video to, or False to start pathfinding function
Raises
Valueerror
If the video is inaccessible for any reason
Returns
str:
- A string with 'Downloaded
Examples
Download youtube video to current folder
from sws.youtube import download download("https://www.youtube.com/watch?v=6j1I3mC0BR0", ".") # Downloads video in current folder
Expand source code
def download(video_url: str, path: Union[str, bool]) -> str: """Downloads specified video_url to path Parameters ---------- video_url : (str) The full URL you want to download i.e. https://www.youtube.com/watch?v=6j1I3mC0BR0 path : (str or bool) The path on your system to download the video to, or False to start pathfinding function Raises ------ ValueError: If the video is inaccessible for any reason Returns ------- str: A string with 'Downloaded <video title> to <path> as <video_title>.mp4' if file was downloaded, or message 'File <filepath> already exists' if file already existed Examples -------- Download youtube video to current folder ``` from sws.youtube import download download("https://www.youtube.com/watch?v=6j1I3mC0BR0", ".") # Downloads video in current folder ``` """ logging.info(f"Entering download(video_url={video_url}, path={path})") if not path: logging.info("No path found, entering _request_path()") path = os.path.realpath(f"{_request_path()}") else: logging.info(f"Path found {path}, converting to abspath {os.path.abspath(path)}") path = os.path.abspath(path) # Get video title if video exists try: logging.info("Requesting video data") video_title = str(YouTube(video_url).title) except pytube.exceptions.RegexMatchError: raise ValueError(f"Video URL {video_url} does not exist") except pytube.exceptions.VideoPrivate: raise ValueError(f"Video URL {video_url} is private") except pytube.exceptions.MembersOnly: raise ValueError(f"Video URL {video_url} is Members Only") except pytube.exceptions.RecordingUnavailable: raise ValueError(f"Video URL {video_url} does not have a recording for the livestream") except pytube.exceptions.VideoUnavailable: raise ValueError(f"Video URL {video_url} does not have an available video") except pytube.exceptions.LiveStreamError: raise ValueError(f"Video URL {video_url} is a livestream and cannot be downloaded") logging.info("Checking if ouput file already exists") if os.path.exists(os.path.join(path, video_title)): logging.info(f"Found existing output file, exiting download() and returning 'File {os.path.join(path, video_title)} already exists'") return f"File {os.path.join(path, video_title)} already exists" print(f"Downloading {video_title} to {path}") YouTube(video_url).streams.get_highest_resolution().download(path) logging.info(f"Found existing output file, exiting download() and returning 'Downloaded {video_title} to {path} as {video_title}.mp4'") return f"Downloaded {video_title} to {path} as {video_title}.mp4"
def get_video_metadata(video_url: str) ‑> dict
-
Gets the metadata of a youtube video
Parameters
video_url
:str
- The URL of the video
Notes
- Keys include:
- title; The title of the video
- id; The id of the video
- publish_date; The publishing date of the video (as a
datetime.datetime
object) - age_restricted; A boolean that is True if the video is age restricted
- creator; A string representation of the channel name
- metadata; A raw
pytube.metadata.YouTubeMetadata
object of video metadata
Returns
dict
- A dictionary of results (see notes for keys)
Raises
ValueError
- If the video is inaccessible for any reason
Expand source code
def get_video_metadata(video_url:str) -> dict: """Gets the metadata of a youtube video Parameters ---------- video_url : str The URL of the video Notes ----- - Keys include: - title; The title of the video - id; The id of the video - publish_date; The publishing date of the video (as a `datetime.datetime` object) - age_restricted; A boolean that is True if the video is age restricted - creator; A string representation of the channel name - metadata; A raw `pytube.metadata.YouTubeMetadata` object of video metadata Returns ------- dict A dictionary of results (see notes for keys) Raises ------ ValueError If the video is inaccessible for any reason """ logging.info(f"Entering get_video_metadata(video_url={video_url})") result = {} try: logging.info("Getting video metadata") video_data = YouTube(video_url) result["title"] = video_data.title result["id"] = video_data.video_id result["publish_date"] = video_data.publish_date result["age_restricted"] = video_data.age_restricted result["creator"] = video_data.author result["metadata"] = video_data.metadata except pytube.exceptions.RegexMatchError: raise ValueError(f"Video URL {video_url} does not exist") except pytube.exceptions.VideoPrivate: raise ValueError(f"Video URL {video_url} is private") except pytube.exceptions.MembersOnly: raise ValueError(f"Video URL {video_url} is Members Only") except pytube.exceptions.RecordingUnavailable: raise ValueError(f"Video URL {video_url} does not have a recording for the livestream") except pytube.exceptions.VideoUnavailable: raise ValueError(f"Video URL {video_url} does not have an available video") except pytube.exceptions.LiveStreamError: raise ValueError(f"Video URL {video_url} is a livestream and cannot be downloaded") logging.info(f"Exiting get_video_metadata() and returning {result}") return result