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://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.min.css"/>
<script src="https://cdnjs.cloudflare.com/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.
A drained and empty Kennington reservoir images from a drone in early July 2024. The…
Merrimu Reservoir from drone. Click images to view larger.
Using FTP and PHP to get an array of file details such as size and…
Creating and using Laravel form requests to create cleaner code, separation and reusability for your…
Improving the default Laravel login and register views in such a simple manner but making…
Laravel validation for checking if a field value exists in the database. The validation rule…