You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.2 KiB
Python

import subprocess
import yt_dlp
from typing import Dict
from urllib.error import HTTPError
from botocore.exceptions import ClientError
from yt_dlp_stream_to_s3.client import s3_client, create_presigned_url, get_file_size
from yt_dlp_stream_to_s3.utils import remove_queries_from_url
from yt_dlp_stream_to_s3.config import AWS_S3_BUCKET_NAME
from yt_dlp_stream_to_s3.errors import YtDlpStreamToS3Error
def yt_dlp_stream_to_s3(
url: str,
expiration=86400 * 7, # 7 days
s3_extra_args: dict = (),
) -> Dict[str, str]:
media_url = remove_queries_from_url(url)
ydl_opts = {
"outtmpl": "%(title)s-%(id)s.%(ext)s",
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(media_url, download=False)
video_title = info_dict.get("title", None)
video_id = info_dict.get("id", None)
video_ext = info_dict.get("ext", None)
filename = f"{video_title}-{video_id}.{video_ext}"
yt_dlp_process = subprocess.Popen(
[
"yt-dlp",
media_url,
"--downloader",
"ffmpeg",
"--hls-use-mpegts",
"--no-part",
"-o",
"-",
],
stdout=subprocess.PIPE,
)
s3_client.upload_fileobj(
yt_dlp_process.stdout,
AWS_S3_BUCKET_NAME,
filename,
ExtraArgs=s3_extra_args,
)
yt_dlp_process.wait()
return dict(
presigned_url=create_presigned_url(
AWS_S3_BUCKET_NAME, filename, expiration
),
filesize=get_file_size(AWS_S3_BUCKET_NAME, filename),
)
except HTTPError:
raise YtDlpStreamToS3Error("Could not connect to the media resource.")
except yt_dlp.utils.ExtractorError:
raise YtDlpStreamToS3Error("Could not extra info from media.")
except yt_dlp.utils.DownloadError:
raise YtDlpStreamToS3Error("Could not download media. Check logs.")
except ClientError:
raise YtDlpStreamToS3Error("Error communicating with the S3 service.")