Displaying a progress bar for a youtube-dl download by using PHP and some AJAX setinterval. I have covered AJAX setinterval before with an FFmpeg progress bar and a general continuous AJAX get.
Now for a youtube-dl download progress bar, the only real point of difference is the parsing of the youtube-dl output file which has the progress log.
A youtube-dl output line looks like this
[download] 35.5% of 293.09MiB at 9.75MiB/s ETA 00:19
Putting the read last line from file code into a function and splitting it into an array based on the spaces. This makes for a consistent way to split the output into progress %, total video size, download speed and ETA… if you ever needed those values.
get-progress.php:
<?php $log_file_path = 'yt-dl-progress.txt'; function lineAsArray(string $filepath): array { $line = ''; $f = fopen($filepath, 'r'); $cursor = -1; fseek($f, $cursor, SEEK_END); $char = fgetc($f); while ($char === "\n" || $char === "\r") { fseek($f, $cursor--, SEEK_END); $char = fgetc($f); } while ($char !== false && $char !== "\n" && $char !== "\r") { $line = $char . $line; fseek($f, $cursor--, SEEK_END); $char = fgetc($f); } $remove_whitespace = preg_replace('/\s+/', ' ', $line); return explode(" ", $remove_whitespace); } function progress(array $array): string { return str_replace('%', '', $array[1]); } $last_line = lineAsArray($log_file_path); echo progress($last_line);
This simply returns a float for the percentage of the download task completed.
index.html:
<link rel="stylesheet" href="https://write.corbpie.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS8=ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.min.css"/> <script src="https://write.corbpie.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS8=ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script type="text/javascript"> setInterval(function () { $.ajax({ url: 'get-progress.php', success: function (data) { $('#progress-string').html(`${data}%`); $('#progressbar').attr('aria-valuenow', data).css('width', `${data}%`); } }); }, 1000); </script> <div class="container"> <div class="row"> <div class="col-12"> <div class="card"> <div class="progress"> <div id="progressbar" class="progress-bar bg-info" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"><span id="progress-string"></span></div> </div> </div> </div> </div> </div>
This is what fetches every 1 second, the download percent from get-progress.php and then uses its value to fill the progress bar and display the value.
Sample youtube-dl command with output to file :
sudo nohup youtube-dl --merge-output-format mp4 -f best -o savevideas.mp4 'https://www.youtube.com/watch?v=XXXXXX' > yt-dl-progress.txt
This whole operation only works if you’re saving the youtube-dl command to an output file, as the above command does.