nnilayy commited on
Commit
a17935c
·
1 Parent(s): 0dbea46

Add yt-audio gradio app

Browse files
Files changed (5) hide show
  1. .gitignore +1 -0
  2. Dockerfile +23 -0
  3. app.py +82 -0
  4. requirements.txt +54 -0
  5. sample.py +72 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ venv
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.10 base image
2
+ FROM python:3.10-slim
3
+
4
+ # Create a non-root user for security
5
+ RUN useradd -m -u 1000 user
6
+ USER user
7
+ ENV PATH="/home/user/.local/bin:${PATH}"
8
+
9
+ # Set working directory
10
+ WORKDIR /app
11
+
12
+ # Install Python dependencies first for layer caching
13
+ COPY --chown=user requirements.txt .
14
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
15
+
16
+ # Copy application code
17
+ COPY --chown=user . .
18
+
19
+ # Expose Gradio's default port
20
+ EXPOSE 7860
21
+
22
+ # Launch the application with Spaces-compatible settings
23
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from pytubefix import YouTube
3
+ import tempfile
4
+ import base64
5
+ from io import BytesIO
6
+
7
+ def download_audio(url):
8
+ try:
9
+ # Initialize YouTube object
10
+ yt = YouTube(url, 'WEB')
11
+ title = yt.title
12
+
13
+ # Get best audio stream
14
+ audio_stream = yt.streams.filter(only_audio=True).order_by('abr').desc().first()
15
+ if not audio_stream:
16
+ return ["Error: No audio stream found", None, None]
17
+
18
+ # Download to in-memory buffer
19
+ buffer = BytesIO()
20
+ audio_stream.stream_to_buffer(buffer)
21
+ buffer.seek(0)
22
+
23
+ # Create temporary file
24
+ with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp_file:
25
+ tmp_file.write(buffer.read())
26
+ tmp_path = tmp_file.name
27
+
28
+ # Create HTML audio player with base64 encoding
29
+ with open(tmp_path, "rb") as f:
30
+ audio_bytes = f.read()
31
+ audio_base64 = base64.b64encode(audio_bytes).decode("utf-8")
32
+ audio_html = f"""
33
+ <audio controls autoplay style="width: 100%">
34
+ <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
35
+ Your browser does not support the audio element.
36
+ </audio>
37
+ """
38
+
39
+ return [
40
+ f"Success: {title}",
41
+ tmp_path,
42
+ audio_html
43
+ ]
44
+
45
+ except Exception as e:
46
+ return [f"Error: {str(e)}", None, None]
47
+
48
+ with gr.Blocks(title="YouTube Audio Downloader") as demo:
49
+ gr.Markdown("# YouTube Audio Downloader")
50
+
51
+ with gr.Row():
52
+ url_input = gr.Textbox(label="YouTube URL", placeholder="Enter YouTube URL here...")
53
+
54
+ with gr.Column(scale=0.3):
55
+ clear_btn = gr.Button("Clear")
56
+ submit_btn = gr.Button("Submit")
57
+
58
+ status_output = gr.Textbox(label="Status", interactive=False)
59
+ file_download = gr.File(label="Audio File")
60
+ audio_player = gr.HTML(label="Audio Player")
61
+
62
+ def clear():
63
+ return [None, None, None, None]
64
+
65
+ clear_btn.click(
66
+ fn=clear,
67
+ outputs=[url_input, status_output, file_download, audio_player]
68
+ )
69
+
70
+ submit_btn.click(
71
+ fn=download_audio,
72
+ inputs=url_input,
73
+ outputs=[status_output, file_download, audio_player]
74
+ )
75
+
76
+ if __name__ == "__main__":
77
+ demo.launch(
78
+ server_name="0.0.0.0",
79
+ server_port=7860,
80
+ show_error=True,
81
+ allowed_paths=["*"]
82
+ )
requirements.txt ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ annotated-types==0.7.0
3
+ anyio==4.8.0
4
+ certifi==2024.12.14
5
+ charset-normalizer==3.4.1
6
+ click==8.1.8
7
+ colorama==0.4.6
8
+ exceptiongroup==1.2.2
9
+ fastapi==0.115.6
10
+ ffmpy==0.5.0
11
+ filelock==3.17.0
12
+ fsspec==2024.12.0
13
+ gradio==5.12.0
14
+ gradio-client==1.5.4
15
+ h11==0.14.0
16
+ httpcore==1.0.7
17
+ httpx==0.28.1
18
+ huggingface-hub==0.27.1
19
+ idna==3.10
20
+ jinja2==3.1.5
21
+ markdown-it-py==3.0.0
22
+ markupsafe==2.1.5
23
+ mdurl==0.1.2
24
+ numpy==2.2.2
25
+ orjson==3.10.15
26
+ packaging==24.2
27
+ pandas==2.2.3
28
+ pillow==11.1.0
29
+ pydantic==2.10.5
30
+ pydantic-core==2.27.2
31
+ pydub==0.25.1
32
+ pygments==2.19.1
33
+ python-dateutil==2.9.0.post0
34
+ python-multipart==0.0.20
35
+ pytubefix==8.12.0
36
+ pytz==2024.2
37
+ pyyaml==6.0.2
38
+ requests==2.32.3
39
+ rich==13.9.4
40
+ ruff==0.9.2
41
+ safehttpx==0.1.6
42
+ semantic-version==2.10.0
43
+ shellingham==1.5.4
44
+ six==1.17.0
45
+ sniffio==1.3.1
46
+ starlette==0.41.3
47
+ tomlkit==0.13.2
48
+ tqdm==4.67.1
49
+ typer==0.15.1
50
+ typing-extensions==4.12.2
51
+ tzdata==2025.1
52
+ urllib3==2.3.0
53
+ uvicorn==0.34.0
54
+ websockets==14.2
sample.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import yt_dlp
3
+ import os
4
+ import browser_cookie3
5
+ from huggingface_hub import hf_hub_download, login
6
+
7
+
8
+
9
+ if "cookies.txt" not in os.listdir("."):
10
+ hf_hub_download("not-lain/secrets","cookies.txt",local_dir=".",repo_type="dataset")
11
+
12
+
13
+ def get_cookies():
14
+ try:
15
+ # Try to get cookies from multiple browsers
16
+ cookies = []
17
+ for get_cookies in [
18
+ browser_cookie3.firefox,
19
+ browser_cookie3.chrome,
20
+ browser_cookie3.brave,
21
+ ]:
22
+ try:
23
+ cookies.extend([c for c in get_cookies(domain_name=".youtube.com")])
24
+ except:
25
+ continue
26
+ return cookies
27
+ except:
28
+ return None
29
+
30
+
31
+ def download_video(url):
32
+ try:
33
+ downloads_dir = "/downloads"
34
+ if not os.path.exists(downloads_dir):
35
+ os.makedirs(downloads_dir, exist_ok=True)
36
+
37
+ # Use a pre-provided cookies file
38
+ cookie_file = "cookies.txt"
39
+ cookie_args = {}
40
+ if os.path.exists(cookie_file):
41
+ cookie_args["cookiefile"] = cookie_file
42
+
43
+ ydl_opts = {
44
+ "outtmpl": os.path.join(downloads_dir, "%(title)s.%(ext)s"),
45
+ "format": "mp4/bestvideo+bestaudio/best",
46
+ "merge_output_format": "mp4",
47
+ **cookie_args,
48
+ "paths": {"home": "/downloads", "temp": "/tmp"},
49
+ }
50
+
51
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
52
+ info = ydl.extract_info(url, download=True)
53
+ video_path = ydl.prepare_filename(info)
54
+ if os.path.exists(video_path):
55
+ return f"Successfully downloaded: {info['title']}", video_path
56
+ else:
57
+ return f"Download completed but file not found: {info['title']}", None
58
+ except Exception as e:
59
+ return f"Error: {str(e)}", None
60
+
61
+
62
+ iface = gr.Interface(
63
+ fn=download_video,
64
+ inputs=gr.Textbox(label="YouTube URL"),
65
+ outputs=[gr.Textbox(label="Status"), gr.Video(label="Downloaded Video")],
66
+ title="YouTube Video Downloader",
67
+ description="Cookies created using the following extension : https://chromewebstore.google.com/detail/get-cookiestxt-clean/ahmnmhfbokciafffnknlekllgcnafnie?hl=en \n\nEnter a YouTube URL to download and view the video",
68
+ examples=["https://www.youtube.com/watch?v=UiyDmqO59QE"],
69
+ )
70
+
71
+ if __name__ == "__main__":
72
+ iface.launch(server_name="0.0.0.0", allowed_paths=["/"], server_port=7860)