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.