[FIXED] Call python's object method from flask jinja2 html file

Issue

I am trying to create youtube video downloader application using pytube and flask. All is done, except that a want to call pytube’s stream download method from within the html script tag. How can i do it.

Here’s my flask code


    from flask import Flask, render_template, request
    from pytube import YouTube
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        return render_template("index.html", data=None)
        
    @app.route("/download", methods=["POST", "GET"])
    def downloadVideo():
        if request.method == "POST":
            url = request.form["videourl"]
            if url:
                yt = YouTube(url)
                title = yt.title
                thumbnail = yt.thumbnail_url
                streams = yt.streams.filter(file_extension='mp4')
                data = [title, thumbnail, streams, yt]
                
                return render_template("index.html", data=data)
        
    if __name__ == "__main__":
        app.run(debug=True)

and here’s my html code


    <!DOCTYPE html>
    <html>
        <head>
            <title> Youtube Downloader </title>
            <meta name="viewport" content="width=device-width,initial-scale=1.0">
            <link rel="stylesheet" href="static/css/style.css">
        </head>
        <body>
            <div class="main">
                <div class="header">
                        <div>
                            <img src="static/img/icon.png" width="48" height="48">
                            <h2> Youtube Downloader </h2>
                        </div>
                        <div>
                            <p> Convert and download youtube videos </p>
                            <p> in MP4 for free </p>
                        </div>
                </div>
                
                {% if not data %}
                    <div class="dform">
                        <form action="http://127.0.0.1:5000/download", method="POST">
                            <div class="inputfield">
                                <input type="input" name="videourl" placeholder="Search or Paste youtube link here" autocomplete="off">
                                <button type="submit"> Download </button>
                            </div>
                        </form>
                    </div>
                {% else %}
                    <div class="videoinfo">
                        <img src="" class="thumbnail">
                        <h2> {{data[0]}} </h2>
                    </div>
                    <div class="quality">
                        <select id="streams">
                            {% for stream in data[2][:3] %} 
                                <option value="{{stream.itag}}"> {{stream.resolution}} </option>
                            {% endfor %}
                        </select>
                    </div>
                {% endif %}
            </div>
    
                <script type="text/javascript">
                    const image = document.querySelector(".thumbnail");
                    const select = document.querySelector("select");
    
                    let url = `{{data[1]}}`;
                        if (image) {
                            image.src = `${url}`;
    
                            window.addEventListener('change', function() {
                                var option = select.options[select.selectedIndex].value;
                                console.log(option);
                                {% set stream = data[3].get_by_itag(option) %}
                                {% stream.download() %}
                        });
                    }
                </script>
        </body>
    </html>

I am trying to download the video using itag when a user clicks an option in the select element by using pytube get_by_itag() method.

Solution

From what I understand you want to do two things. You want to create a route on your flask app that will let serve up the youtube video based on an itag, and you want to be able to call that route from javascript.

This answer shows how to create a route to download the video.

To call a url that starts a file download from javascript you’ll need to use the fetch method and open that link into an iFrame. This answer covers it.

Let me know if that covers your question.

Answered By – barryodev

Answer Checked By – Dawn Plyler (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published