Spark-NF / hls-downloader

Download HLS streams in NodeJS
Apache License 2.0
73 stars 32 forks source link

Progress bar logger #12

Open Dianoga opened 3 years ago

Dianoga commented 3 years ago

If it is of any interest I just threw together a logger that generates a fairly nice progress bar (using the awesome progress package). Feel free to use (or not) as you see fit 😄

API instantiation would be something like:

await download({
   ...,
  logger: new HLSLogger().logger,
  ...
});
import ProgressBar from 'progress';

export class HLSLogger {
    private segmentCount?: number;
    private bar?: ProgressBar;
    private template: string;

    constructor(caption = 'downloading', indent = 0) {
        this.template = `${''.padStart(
            indent,
            ' '
        )}${caption} [:bar] :current/:total (:percent) :etas`;
    }

    logger = (...args: any[]): void => {
        if (typeof args[0] === 'string') {
            // Check if segment count message
            const matches = args[0].match(/Queueing (\d+) segment/);
            if (matches?.[1]) {
                this.segmentCount = parseInt(matches[1]);
                this.bar = new ProgressBar(this.template, {
                    total: this.segmentCount,
                    width: 20,
                    incomplete: ' ',
                });
            }

            if (args[0] === 'Received:') {
                this.bar?.tick();
            }
        }
    };
}
Spark-NF commented 3 years ago

Indeed it's looks quite nice!

I don't think it makes sense to integrate it in the package itself (especially since it would add a dependency on progress) but maybe a separate "progress" logger config could be added, that would be updated for every segment download. That would make your logger even simpler, maybe to the point it could even be added as an example in the README.

Either as single method with (current: number, total?: number) => void (calculating the current might be annoying), or an object like { start: (total?: number) => void, tick: () => void } (total being optional because of live streams).

Do you want to try to make a PR for this, or should I have a go when I have some time?

Dianoga commented 3 years ago

I don't know when I'll have time to build out something in PR form. If I do end up with time I can take a look at doing it if it's not already done.

I like the idea of an object with start and tick. I don't think counting current is necessary unless someone gets really excited about it. I'm not sure what errors are possible but someway to share those with a custom logger would also be good.