Thomas
Thomas

Reputation: 43

How to show downloading progress of youtube video on frontend

I have only worked with console nodejs apps and I am new to express like packages. I want to paste youtube video link to frontend input box, press "convert" what triggers downloading on backend. All works, but I can't wrap my head around how I would show downloading progress real-time on frontend right after clicking "convert" button. Downloading package which I use has event "progress" but I don't know how to show it on frontend.

So I would like to know what is best practice in cases like this and how should I continue. Thank you in advance for all advice's and tips.

Here is template which I use yt.pug

doctype html
html
    head
        title YouTube Downloader
        link(rel='stylesheet', href='css/yt.css')
        script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js')
        script(src='js/yt.js')

    body
        h1.heading My Own YouTube Downloader !
        input.URL-input(placeholder='Video URL e.g. https://www.youtube.com/watch?v=MtN1YnoL46Q')
        button.convert-button Convert

Here is server.js which loads template

const server_start = async function(){
    const app = express()
    app.set('view engine', 'pug')
    app.use(express.static(__dirname + '/public'))
    app.use(cors())

    const server = app.listen(7000, () => {
        console.log(`Express running → PORT ${server.address().port}`)
    })

    app.get('/yt', async (req, res) => {        
        res.render('yt')  
    })

    app.get('/yt/save', function(req, res){
      let file = '/usr/share/nginx/html/downloads/' + req.query.file
      res.download(file)
    })

    app.get('/yt/download', async (req,res) => {
        try{
            var VIDEO_URL = req.query.URL;
            var VIDEO_ID = youtube_parser(req.query.URL);


            var YD = new YoutubeMp3Downloader({
                "ffmpegPath": "/usr/bin/ffmpeg",        // Where is the FFmpeg binary located?
                "outputPath": "/usr/share/nginx/html/downloads",    // Where should the downloaded and encoded files be stored?
                "youtubeVideoQuality": "highest",       // What video quality should be used?
                "queueParallelism": 2,                  // How many parallel downloads/encodes should be started?
                "progressTimeout": 1000                 // How long should be the interval of the progress reports
            })

            //Download video and save as MP3 file
            YD.download(VIDEO_ID)

            YD.on("finished", function(err, data) {
                res.json(JSON.stringify({
                    url: "yt/save?file=" + data.videoTitle + ".mp3"
                }))                                
            });

            YD.on("error", function(error) {
                res.json(JSON.stringify(error))
            });

            YD.on("progress", function(progress) {
                console.log(JSON.stringify(progress))
            });

        }catch(err){
            res.json(JSON.stringify(err))
        }
    })
}

server_start()

And here is yt.js which sends download request on click

$(document).ready(function() {
    $('.convert-button').on('click', () => {
        $.ajax({
            url: '/yt/download',
            method: 'GET',
            data: {
                'URL' : $('.URL-input').val()
            },
            success: function(data) {
                console.log("Video was downloaded");
            }
        })
    });
});

Upvotes: 1

Views: 822

Answers (1)

Alexander
Alexander

Reputation: 36

I would suggest to use Socket.io to send the progress data to the client. Im not sure if this is the best way to do it, but its my initial idea of solving your problem.

Created a sample enviroment demonstrating my idea.

https://codesandbox.io/embed/busy-hill-hlemy

Would like to see what other methods others come up with.

Upvotes: 1

Related Questions