File size: 4,202 Bytes
4a9476d
 
 
 
 
 
5e4c4a2
 
4a9476d
 
 
 
e9f3f94
4a9476d
e9f3f94
d04c97a
4a9476d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6952355
0f82bd3
7cad919
38a10c9
8a06433
 
7cad919
83340a5
7cad919
4a9476d
 
 
 
 
 
 
 
 
7cad919
4a9476d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a068717
4a9476d
 
 
 
 
256396c
4a9476d
 
 
 
 
256396c
4a9476d
a068717
4a9476d
 
 
 
 
 
e7b9dd8
4a9476d
 
e7b9dd8
4a9476d
 
e9f3f94
4a9476d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a068717
4a9476d
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import os
import tempfile
import subprocess
import streamlit as st
from pydub import AudioSegment
import shutil
import base64
import uuid

AudioSegment.converter = shutil.which("ffmpeg")

# -------------------------------
# Download audio from a Video url
# -------------------------------


def download_audio_as_wav(url, max_filesize_mb=70):
    """
    Downloads audio from a URL using yt-dlp, then converts it to WAV using ffmpeg.
    Supports fallback formats (.m4a, .webm, .opus) if .mp3 not found.
    Cleans up temporary files after use.
    Returns path to .wav file or None on failure.
    """
    audio_path = None
    temp_wav = None

    try:
        with tempfile.TemporaryDirectory() as temp_dir:
            max_bytes = max_filesize_mb * 1024 * 1024
            output_template = os.path.join(temp_dir, "audio.%(ext)s")

            temp_cookie_path = tempfile.NamedTemporaryFile(delete=False, suffix=".txt").name
            cookies_b64 = os.getenv("cookies")
            if not cookies_b64:
                raise EnvironmentError("cookies environment variable not set.")

                    # Decode and write cookies.txt
            with open(temp_cookie_path, "wb") as f:
                f.write(base64.b64decode(cookies_b64))

            # yt-dlp download command
            download_cmd = [
                "yt-dlp",
                "-f", f"bestaudio[filesize<={max_bytes}]",
                "--extract-audio",
                "--audio-format", "mp3",
                "--no-playlist",
                "--no-cache-dir",
                "--restrict-filenames",
                "--cookies", temp_cookie_path,
                "-o", output_template,
                url
            ]

            subprocess.run(download_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)

            # Try to locate audio file (mp3 or fallback)
            common_exts = [".mp3", ".m4a", ".webm", ".opus"]
            for ext in common_exts:
                matches = [f for f in os.listdir(temp_dir) if f.endswith(ext)]
                if matches:
                    audio_path = os.path.join(temp_dir, matches[0])
                    break

            if not audio_path or not os.path.exists(audio_path):
                st.error("No supported audio file found after download.")
                return None

            # Convert to WAV (outside temp_dir so it persists)
            temp_wav = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
            convert_cmd = ["ffmpeg", "-y", "-i", audio_path, temp_wav.name]
            subprocess.run(convert_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)

            # Return WAV file path; temp_dir and downloaded audio cleaned automatically
            return temp_wav.name

    except subprocess.CalledProcessError as e:
        error_msg =  e.stderr.decode("utf-8", errors="replace") if e.stderr else str(e)
        if "st" in globals():
            st.error("Audio download or conversion failed.")
            st.code(error_msg)
        else:
            print("Error during processing:", error_msg)
        # Cleanup wav if created
        if temp_wav is not None and os.path.exists(temp_wav.name):
            os.remove(temp_wav.name)
        st.stop()
        return None

    
    
# --------------------------
# Trim audios to 2 minutes
# --------------------------
def trim_audio(input_wav_path, max_duration_sec=120):
    """
    Trims the input .wav file to the first `max_duration_sec` seconds.
    Returns the path to the trimmed .wav file.
    """
    try:
        # Load audio using pydub
        audio = AudioSegment.from_wav(input_wav_path)
        
        # Trim to max_duration_sec
        trimmed_audio = audio[:max_duration_sec * 1000]  # pydub uses milliseconds
        # Save to a new temporary .wav file
        trimmed_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
        trimmed_audio.export(trimmed_file.name, format="wav")

        return trimmed_file.name

    except Exception as e:
        st.error(f"Error trimming audio: {e}")
        if trimmed_file and os.path.exists(trimmed_file.name):
            os.remove(trimmed_file.name)
        return None