jeudi 16 juin 2016

Find the speed of download for a progressbar

I'm writing a script to download videos from a website. I've added a report hook to get download progress. So, far it shows the percentage and size of the downloaded data. I thought it'd be interesting to add download speed and eta.
Problem is, if I use a simple speed = chunk_size/time the speeds shown are accurate enough but jump around like crazy. So, I've used the history of time taken to download individual chunks. Something like, speed = chunk_size*n/sum(n_time_history).
Now it shows a stable download speed, but it is most certainly wrong because its value is in a few bits/s, while the downloaded file visibly grows at a faster pace.
Can somebody tell me where I'm going wrong?

Here's my code.

def dlProgress(count, blockSize, totalSize):
    global init_count
    global time_history
    try:
        time_history.append(time.monotonic())
    except NameError:
        time_history = [time.monotonic()]
    try:
        init_count
    except NameError:
        init_count = count
    percent = count*blockSize*100/totalSize
    dl, dlu = unitsize(count*blockSize)             #returns size in kB, MB, GB, etc.
    tdl, tdlu = unitsize(totalSize)
    count -= init_count                             #because continuation of partial downloads is supported
    if count > 0:
        n = 5                                       #length of time history to consider
        _count = n if count > n else count
        time_history = time_history[-_count:]
        time_diff = [i-j for i,j in zip(time_history[1:],time_history[:-1])]
        speed = blockSize*_count / sum(time_diff)
    else: speed = 0
    n = int(percent//4)
    try:
        eta = format_time((totalSize-blockSize*(count+1))//speed)
    except:
        eta = '>1 day'
    speed, speedu = unitsize(speed, True)           #returns speed in B/s, kB/s, MB/s, etc.
    sys.stdout.write("r" + percent + "% |" + "#"*n + " "*(25-n) + "| " + dl + dlu  + "/" + tdl + tdlu + speed + speedu + eta)
    sys.stdout.flush()

Edit:
Corrected the logic. Download speed shown is now much better.
As I increase the length of history used to calculate the speed, the stability increases but sudden changes in speed (if download stops, etc.) aren't shown.
How do I make it stable, yet sensitive to large changes?

I realize the question is now more math oriented, but it'd be great if somebody could help me out or point me in the right direction.
Also, please do tell me if there's a more efficient way to accomplish this.

Aucun commentaire:

Enregistrer un commentaire