JuanBindez / pytubefix

Python3 library for downloading YouTube Videos.
http://pytubefix.rtfd.io/
MIT License
714 stars 100 forks source link

Download in the same directory for a code #339

Open ExyXyz opened 2 hours ago

ExyXyz commented 2 hours ago

:exclamation: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE :exclamation:

lack of information will lead to closure of the issue


Describe the bug I've never asked about this so i will right now so when i download it it supposed to be downloading inside the 'download' folder but idk why it saved outside the download folder and saved as 'downloadvideo_9333.mp4.mp4' or 'downloadaudio_9333.m4a.m4a' it works fine with version 7.0.0 but it doesnt work on the newer after version 7.0.0 it saved like that like doesnt want to save inside the download folder it just save as the folder was the filename and double extension


code that was used that resulted in the bug

import os
import random
import subprocess
from flask import Flask, request, jsonify, send_file
from pytubefix import YouTube
from pytubefix.cli import on_progress

app = Flask(__name__)

@app.route('/api/youtube3', methods=['GET'])
def download_vid():
    video_url = request.args.get('url')

    if not video_url:
        return jsonify({"error": "No video URL provided | Link nya manah?"}), 400

    try:
        yt = YouTube(video_url, 'IOS', use_oauth=True, allow_oauth_cache=True, on_progress_callback=on_progress)

        random_number = random.randint(1, 10000)
        video_filename = f'download/video_{random_number}.mp4'
        audio_filename = f'download/audio_{random_number}.m4a'
        output_filename = f'download/ytdl_{random_number}.mp4'

        os.makedirs('download', exist_ok=True)

        video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True).order_by('resolution').desc().first()

        if video_stream.resolution not in ['720p', '480p', '360p']:
            video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True, resolution='720p').first()

        audio_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_audio=True).order_by('abr').desc().first()

        video_stream.download(filename=video_filename)
        audio_stream.download(filename=audio_filename)

        subprocess.run([
            'ffmpeg', '-i', video_filename, '-i', audio_filename,
            '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental',
            output_filename
        ])

        download_link = f'http://localhost/download/{os.path.basename(output_filename)}'

        os.remove(video_filename)
        os.remove(audio_filename)

        return jsonify({
            "title": yt.title,
            "thumbnail": yt.thumbnail_url,
            "artist": yt.author,
            "views": yt.views,
            "duration": yt.length,
            "url": yt.watch_url,
            "download_link": download_link
        })

    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/download/<filename>', methods=['GET'])
def download_file(filename):
    file_path = os.path.join('download', filename)
    if not os.path.exists(file_path):
        return jsonify({"message": "More than 100 sec has passed | Sudah lewat dari 100 detik"}), 404
    return send_file(file_path, as_attachment=True, mimetype='video/mp4')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

Expected behavior It download succesfully inside the folder


Screenshots image


Desktop (please complete the following information):


Additional context Idk if its my code problem or the package problem i'm still a high school student so i don't really focused on coding since coding it's just my hobby my school doesn't teach how to code

JuanBindez commented 2 hours ago

remove .mp4 and .m4a, pytubefix already does this, otherwise it will be duplicated

ExyXyz commented 1 hour ago

remove .mp4 and .m4a, pytubefix already does this, otherwise it will be duplicated

well yap that one of my problem the main problem is it act like the i set the download folder instead it saved on download folder it saved like outside the download folder and the download folder act like filename it works perfectly in version 7.0.0 after that idk why it doing that

JuanBindez commented 32 minutes ago

Flask's send_file should already do this job, test without using output_path

ExyXyz commented 19 minutes ago

Flask's send_file should already do this job, test without using output_path

i updated it like this it always work on version 7.0.0 without any issue but on newer version well that happen

import os
import random
import subprocess
from flask import Flask, request, jsonify, send_file
from pytubefix import YouTube
from pytubefix.cli import on_progress

app = Flask(__name__)

@app.route('/api/youtube3', methods=['GET'])
def download_vid():
    video_url = request.args.get('url')

    if not video_url:
        return jsonify({"error": "No video URL provided | Link nya manah?"}), 400

    try:
        yt = YouTube(video_url, 'IOS', use_oauth=True, allow_oauth_cache=True, on_progress_callback=on_progress)

        random_number = random.randint(1, 10000)
        video_filename = f'download/video_{random_number}'
        audio_filename = f'download/audio_{random_number}'

        os.makedirs('download', exist_ok=True)

        video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True).order_by('resolution').desc().first()

        if video_stream.resolution not in ['720p', '480p', '360p']:
            video_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_video=True, resolution='720p').first()

        audio_stream = yt.streams.filter(adaptive=True, file_extension='mp4', only_audio=True).order_by('abr').desc().first()

        video_stream.download(filename=video_filename)
        audio_stream.download(filename=audio_filename)

        combined_filename = f'download/ytdl_{random_number}.mp4'
        subprocess.run([
            'ffmpeg', '-i', video_filename, '-i', audio_filename,
            '-c:v', 'copy', '-c:a', 'aac', '-strict', 'experimental',
            combined_filename
        ])

        download_link = f'http://localhost/download/{os.path.basename(combined_filename)}'

        os.remove(video_filename)
        os.remove(audio_filename)

        return jsonify({
            "title": yt.title,
            "thumbnail": yt.thumbnail_url,
            "artist": yt.author,
            "views": yt.views,
            "duration": yt.length,
            "url": yt.watch_url,
            "download_link": download_link
        })

    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/download/<filename>', methods=['GET'])
def download_file(filename):
    file_path = os.path.join('download', filename)
    if not os.path.exists(file_path):
        return jsonify({"message": "More than 100 sec has passed | Sudah lewat dari 100 detik"}), 404
    return send_file(file_path, as_attachment=True, mimetype='video/mp4')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

still it save file outside the download folder could you maybe try it?