Please need urgent help!

so i have this program that should be able to download mp3 from various source, and it does work when i boot it locally but when i boot it on render or heroku, only the soundcloud works and the upload video to mp3 conversion doesnt work.

this is the code that im running

import os
import subprocess
from flask import Flask, request, render_template, send_file, redirect, url_for, session
from werkzeug.utils import secure_filename
from pytube import YouTube
from ytsearch import YTSearch  # Assuming this is your custom module
from sclib import SoundcloudAPI, Track
from flask.helpers import send_file
import re

app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

 Directories
UPLOAD_DIRECTORY = r'C:\Users\Calvin\Downloads\yesmp3\uploads'
CONVERTED_DIRECTORY = r'C:\Users\Calvin\Downloads\yesmp3\converted'

os.makedirs(UPLOAD_DIRECTORY, exist_ok=True)
os.makedirs(CONVERTED_DIRECTORY, exist_ok=True)

# SoundCloud API client
api = SoundcloudAPI()

# Function to sanitize filenames
def sanitize_filename(filename):
    # Remove characters that are not allowed in Windows filenames
    return re.sub(r'[<>:"/\\|?*]', '_', filename)

# Function to convert a video file to MP3 using ffmpeg
def convert_to_mp3(video_file):
    try:
        input_file_path = os.path.join(UPLOAD_DIRECTORY, secure_filename(video_file.filename))
        video_file.save(input_file_path)

        output_file_path = os.path.join(CONVERTED_DIRECTORY, os.path.splitext(video_file.filename)[0] + '.mp3')

        # Convert using ffmpeg
        cmd = ['ffmpeg', '-i', input_file_path, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', output_file_path]
        subprocess.run(cmd, capture_output=True, check=True)

        os.remove(input_file_path)  # Remove the uploaded video file

         return output_file_path
         except Exception as e:
        print(f"Error converting video to MP3: {e}")
        return None

# Function to download a song from Spotify, YouTube, or SoundCloud
def download_song(url):
    try:
        clear_downloaded_song()

        if 'spotify.xxx' in url:
            # Spotify URL detected
            spotdl_command = [
                'spotdl',
                url,
                '--format', 'mp3',
                '--overwrite', 'skip',
                '--output', UPLOAD_DIRECTORY  # Specify the output directory
            ]

            process = subprocess.Popen(spotdl_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = process.communicate()

            if process.returncode != 0:
                print(f"Error downloading song: {stderr.decode('utf-8')}")
                return None

            mp3_files = [f for f in os.listdir(UPLOAD_DIRECTORY) if f.endswith('.mp3')]
            if mp3_files:
                downloaded_song = os.path.join(UPLOAD_DIRECTORY, mp3_files[0])
                session['downloaded_song'] = downloaded_song
                return downloaded_song
            else:
                return None

        elif 'youtube.xxx' in url or 'youtu.be' in url:
            # YouTube URL detected
            yt = YouTube(url)
            video = yt.streams.filter(only_audio=True).first()
            if video:
                print(f"Downloading '{yt.title}'...")
                audio_file = video.download(output_path=UPLOAD_DIRECTORY, filename=yt.title)
                mp3_file = os.path.join(CONVERTED_DIRECTORY, os.path.splitext(os.path.basename(audio_file))[0] + '.mp3')

                cmd = ['ffmpeg', '-i', audio_file, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', mp3_file]
                subprocess.run(cmd, capture_output=True, check=True)

                os.remove(audio_file)

                print('Download and conversion to MP3 successful!')
                session['downloaded_song'] = mp3_file
                return mp3_file
            else:
                print(f"No audio stream available for '{yt.title}'.")
                return None

        elif 'soundcloud.xxx' in url:
            # SoundCloud URL detected
            track = api.resolve(url)
            if isinstance(track, Track):
                title = sanitize_filename(track.title)
                print(f"Downloading '{title}'...")
                audio_file_path = os.path.join(UPLOAD_DIRECTORY, secure_filename(title) + '.mp3')
                with open(audio_file_path, 'wb+') as f:
                    track.write_mp3_to(f)
                print('Download from SoundCloud successful!')
                session['downloaded_song'] = audio_file_path
                return audio_file_path
            else:
                print('Failed to resolve track from SoundCloud')
                return None

        elif 'youtube.xxx' not in url and 'youtu.be' not in url:
            # Assume it's a YouTube search term
            try:
                search_engine = YTSearch()
                video_info = search_engine.search_by_term(url, max_results=1)

                if video_info:
                    video_url = f"xxx://www.youtube.xxx{video_info[0]['url_suffix']}"
                    yt = YouTube(video_url)
                    video = yt.streams.filter(only_audio=True).first()
                    if video:
                        print(f"Downloading '{yt.title}'...")
                        audio_file = video.download(output_path=UPLOAD_DIRECTORY, filename=yt.title)
                        mp3_file = os.path.join(CONVERTED_DIRECTORY, os.path.splitext(os.path.basename(audio_file))[0] + '.mp3')

                        cmd = ['ffmpeg', '-i', audio_file, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', mp3_file]
                        subprocess.run(cmd, capture_output=True, check=True)

                        os.remove(audio_file)

                        print('Download and conversion to MP3 successful!')
                        session['downloaded_song'] = mp3_file
                        return mp3_file
                    else:
                        print(f"No audio stream available for '{yt.title}'.")
                        return None
                else:
                    print("No videos found for the search term.")
                    return None

            except Exception as e:
                print(f"An error occurred during YouTube download: {str(e)}")
                return None

        print("Unsupported URL or unable to download.")
        return None

    except Exception as e:
        print(f"Error downloading song: {str(e)}")
        return None

# Function to clear the downloaded song
def clear_downloaded_song():
    if session.get('downloaded_song'):
        try:
            if os.path.exists(session['downloaded_song']):
                os.remove(session['downloaded_song'])
        except Exception as e:
            print(f"Error deleting downloaded song: {str(e)}")
        session['downloaded_song'] = None

# Route to render the main page with the form
@app.route('/')
def index():
    return render_template('index.html')

# Route to handle file upload and conversion
@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return redirect(request.url)

    file = request.files['file']

    if file.filename == '':
        return redirect(request.url)

    if file:
        try:
            converted_file = convert_to_mp3(file)
            if converted_file:
                return send_file(converted_file, as_attachment=True)
            else:
                return "Failed to convert file"
        except Exception as e:
            print(f"Error serving converted file: {str(e)}")
            return "Error serving converted file"

    return "Failed to convert file"

# Route to handle form submission and download song
@app.route('/download', methods=['POST'])
def download():
    search_input = request.form.get('search_input')

    if search_input:
        downloaded_song = download_song(search_input)
        if downloaded_song:
            try:
                return send_file(downloaded_song, as_attachment=True)
            except Exception as e:
                print(f"Error serving song: {str(e)}")
                return redirect(url_for('index'))

    return redirect(url_for('index'))

if __name__ == "__main__":
    app.run(debug=True)

and the error that im getting is:
2024-06-12T06:46:57.192169+00:00 app[web.1]: Error downloading song: HTTP Error 400: Bad Request
2024-06-12T06:46:57.193006+00:00 app[web.1]: 10.1.28.125 - - [12/Jun/2024:06:46:57 +0000] “POST /download HTTP/1.1” 302 208 “xxx://getmp3-3fb53f7f1780.herokuapp.xxx/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36”
2024-06-12T06:46:57.482006+00:00 heroku[router]: at=info method=GET path=“/” host=getmp3-3fb53f7f1780.herokuapp.xxxrequest_id=b7ddff97-6b40-4c0b-8e32-cc7e98cd8451 fwd=“51.158.237.58” dyno=web.1 connect=0ms service=1ms status=200 bytes=9963 protocol=https
2024-06-12T06:46:57.481648+00:00 app[web.1]: 10.1.28.125 - - [12/Jun/2024:06:46:57 +0000] “GET / HTTP/1.1” 200 9808 “xxx://getmp3-3fb53f7f1780.herokuapp.xxx/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36”

for youtube


2024-06-12T06:56:02.022003+00:00 app[web.1]: Error downloading song: usage: spotdl [-h] [–version] [–debug-termination] [–output OUTPUT]
2024-06-12T06:56:02.022100+00:00 app[web.1]: [–output-format {mp3,m4a,flac,opus,wav,ogg}] [–user-auth]
2024-06-12T06:56:02.022100+00:00 app[web.1]: [–use-youtube] [–lyrics-provider {genius,musixmatch}]
2024-06-12T06:56:02.022100+00:00 app[web.1]: [-p PATH_TEMPLATE] [-f FFMPEG] [–ignore-ffmpeg-version]
2024-06-12T06:56:02.022101+00:00 app[web.1]: [–download-threads DOWNLOAD_THREADS]
2024-06-12T06:56:02.022101+00:00 app[web.1]: [–search-threads SEARCH_THREADS] [–generate-m3u]
2024-06-12T06:56:02.022102+00:00 app[web.1]: query [query …]
2024-06-12T06:56:02.022102+00:00 app[web.1]: spotdl: error: unrecognized arguments: --format mp3 --overwrite skip
2024-06-12T06:56:02.022103+00:00 app[web.1]:
2024-06-12T06:56:02.022103+00:00 app[web.1]: 10.1.40.144 - - [12/Jun/2024:06:56:02 +0000] “POST /download HTTP/1.1” 302 208 “xxx://getmp3-3fb53f7f1780.herokuapp.xxx/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36”
2024-06-12T06:56:02.311259+00:00 heroku[router]: at=info method=GET path=“/” host=getmp3-3fb53f7f1780.herokuapp.xxxrequest_id=9727a015-3892-4e3c-b219-dc0da02681e8 fwd=“51.158.237.58” dyno=web.1 connect=0ms service=1ms status=200 bytes=9963 protocol=https
2024-06-12T06:56:02.311318+00:00 app[web.1]: 10.1.40.144 - - [12/Jun/2024:06:56:02 +0000] “GET / HTTP/1.1” 200 9808 “xxx://getmp3-3fb53f7f1780.herokuapp.xxx/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36”

for spotify


2024-06-12T06:57:04.957039+00:00 app[web.1]: Error converting video to MP3: [Errno 2] No such file or directory: ‘ffmpeg’
2024-06-12T06:57:04.958023+00:00 app[web.1]: 10.1.40.144 - - [12/Jun/2024:06:57:04 +0000] “POST /upload HTTP/1.1” 200 22 “xxx://getmp3-3fb53f7f1780.herokuapp.xxx/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36”

for the drag n drop video to mp3 conversion

please can anyone help me clear up these issues, im really clueless of how i can fix these since i don’t understand much of python and used chatgpt to get this far in these couple of days
obs: i replaced all the".com" and “https” to “xxx” because new users are only allowed to post 2 links per topic

That’s where the problem is. ChatGPT is NOT a good source of code. I recommend starting with your requirements, and figuring out how to achieve each step. The code you have may be of some value, but it’s also quite probably easier to throw it out and start over. I’m sorry you’ve wasted so much time with ChatGPT that this problem is now urgent, but the best solution is to start from a solid foundation and build from there.

9 Likes

I haven’t looked in detail at your code, since you didn’t format it in a very readable way, but this clearly implies that there is no problem as such with the code. The code as such seems to be fine, and ChatGPT apparently did an excellent job with that. If so, then the problem is with how this code is being deployed on a particular platform.

Running on a local host or running on a remote web host may be different for all kinds of reasons. If you ask ChatGPT about this, it will be able to come up with some valid hints what those might be (for instance, the python install could be limited in capabilities, access to the local filesystem may be non-existent or extremely limited - limits needed because of security concerns which don’t necessarily apply in the same way on a local host; heroku may also be wrapping the code in particular ways that have the effect of limiting the capabilities; heroku may not have been configured appropriately for your script). (Another likely cause of at least some errors is very simple: required runtime dependencies may be either missing or not accessible due to different OS env variables on the web host.)

Regulars on this site are mostly hypercritical of ChatGPT for various good reasons. But I assume, given what you write, that you would never have gotten this far (as fast as you have) without having used it - whatever ChatGPTs demerits may be. One way to proceed is to learn how to do things by yourself - this is the hard, time-consuming, traditional and proper way. (“Throw those crutches away and start walking on your own legs!” Good advise, if you don’t mind crawling through the dust for quite a while.) Another way is to use ChatGPT more effectively by asking it smaller, more precise questions which you can test/verify/falsify more easily. You could start, for instance, by asking it to explain each of the error messages you are getting, making sure to mention that you are running on different kinds of platforms. So, use it to learn (more about) how to debug the program.

It might actually also be able to come up with a valid analysis if you just dump the problem as a whole in its lap (including the stack trace and errors) and ask it what’s up. The problem with that approach is that you would then probably not be in a position to evaluate its replies. So, imo, it’s important to use a piecemeal approach in which at each step you can both learn and verify that what it replies is valid/usable.

3 Likes

Help us help you. Read this first and learn how to format code so we can help you better. About the Python Help category You will get more help this way.

4 Likes

I was debugging it futher using chatgpt, came as far to change pytube for yt-dlp but the file always came corrupted and the .crdownload was always there too.
switched up ngrok for now

thanks everyone for the replies!

I also recommend changing your app.secret_key. That should be secret, and not hardcoded into the source code.

  1. Your code looks much better now. In some cases we might copy your code and run it to see the error and find a possible solution.
  2. Don’t put your app.secret_key right in the code, put the secret key in a .env file. Or on Azure use a Key Vault. python-dotenv · PyPI
# How to use a .env file.
# Example .env file: 
secret_key=12345677
username=julio

# Python code
from dotenv import dotenv_values
# config will be a dictionary of values.
config = dotenv_values(".env")  # config = {"USER": "foo", "EMAIL": "foo@example.org"}

Note that this works only when the .env file isn’t shared. So you need some other mechanism for sending that file to your deployment.

(This is generally a good idea anyway though - it means you can have different credentials and secrets on prod and on dev. For example, if I’m hosting something on Heroku and it needs a database, I need to use valid database credentials for my Heroku-hosted app; but when I’m running it on my own PC for initial dev/debugging, my Postgres database is on localhost.)

1 Like

Correct, I just didn’t mention that. I have a function to get my secrets, usernames, smtp email server, and stuff and the function will determine if I’m in the local dev environment on my PC or in my production environment in Azure.

We also have 2 versions of an app and databases which my Python program need to talk to. One is for production, one is for testing. They are on 2 different IP addresses.

1 Like

did you get to run it? i got a requirement.txt at:

  1. Heroku doesn’t have a file system (or rather, it deletes anything that your code uploads to it), so your script is not going to work on Heroku.
  2. You do realize you are using a path for UPLOAD_DIRECTORY that only exists on your machine, don’t you?
1 Like

Yes, the thing is i don’t know how i can change the code that it will be delivered as a browser attachment only since the dls saves the files on the local machine.
Could you help me with that?

Ok so as it is now, i got it to work using the io module

You also need the ffmpeg utility in your path statement so the program can call it. Did you do that part too? One of the errors says it cannot find “ffmpeg”.

2024-06-12T06:57:04.957039+00:00 app[web.1]: Error converting video to MP3: [Errno 2] No such file or directory: ‘ffmpeg’

haven’t checked here for a while so better late then never:
i have fixed the ffmpeg error by importing it to the project