|
import streamlit as st |
|
import requests |
|
import re |
|
|
|
def download_youtube_video(url: str, output_path: str = "./videos") -> str: |
|
""" |
|
Download a YouTube video using requests library and save it to the local file system. |
|
|
|
:param url: The URL of the YouTube video to download. |
|
:param output_path: The path where the downloaded video will be saved. |
|
:return: The absolute path of the downloaded video file. |
|
""" |
|
|
|
video_id = url.split("v=")[1] |
|
|
|
|
|
video_info_url = f"https://www.youtube.com/get_video_info?video_id={video_id}" |
|
video_info_response = requests.get(video_info_url) |
|
video_info = video_info_response.text |
|
|
|
|
|
title_search = re.search(r"title=([^&]+)", video_info) |
|
title = title_search.group(1) if title_search else "video" |
|
stream_map_search = re.search(r"url_encoded_fmt_stream_map=([^&]+)", video_info) |
|
stream_map = stream_map_search.group(1) if stream_map_search else None |
|
|
|
if not stream_map: |
|
raise Exception("Could not extract video streams") |
|
|
|
|
|
stream_map = requests.utils.unquote(stream_map) |
|
streams = stream_map.split(",") |
|
urls = [re.search(r"url=([^&]+)", stream).group(1) for stream in streams] |
|
|
|
|
|
url = urls[0] |
|
|
|
|
|
response = requests.get(url, stream=True) |
|
filename = f"{output_path}/{title}.mp4" |
|
with open(filename, "wb") as f: |
|
for chunk in response.iter_content(chunk_size=1024): |
|
if chunk: |
|
f.write(chunk) |
|
|
|
|
|
return filename |
|
|
|
st.title("YouTube Video Downloader") |
|
|
|
url = st.text_input("Enter a YouTube URL:") |
|
|
|
if url: |
|
st.write(f"Downloading video from {url}...") |
|
try: |
|
video_path = download_youtube_video(url) |
|
st.success(f"Downloaded video to: {video_path}") |
|
st.video(video_path) |
|
except Exception as e: |
|
st.error(f"Failed to download video: {e}") |