代码之家  ›  专栏  ›  技术社区  ›  SvbZ3r0

查找进度条的下载速度

  •  0
  • SvbZ3r0  · 技术社区  · 10 年前

    我正在写一个脚本,从网站下载视频。我添加了一个报告挂钩来获取下载进度。到目前为止,它显示了下载数据的百分比和大小。我想添加下载速度和eta会很有趣。
    问题是,如果我使用一个简单的 speed = chunk_size/time 显示的速度足够精确,但跳跃得很疯狂。因此,我使用了下载单个块所花费的时间历史。比如, speed = chunk_size*n/sum(n_time_history) .
    现在它显示了稳定的下载速度,但它肯定是错误的,因为它的值是几位/秒,而下载的文件显然增长得更快。
    谁能告诉我哪里出错了?

    这是我的密码。

    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()
    

    编辑:
    更正了逻辑。现在显示的下载速度好多了。
    当我增加用于计算速度的历史长度时,稳定性会增加,但速度的突然变化(如果下载停止等)不会显示出来。
    我如何使它稳定,但对大的变化敏感?

    我意识到现在这个问题更倾向于数学,但如果有人能帮我解决问题或为我指出正确的方向,那就太好了。
    另外,请告诉我是否有更有效的方法来实现这一点。

    1 回复  |  直到 10 年前
        1
  •  1
  •   Tomasz Plaskota    10 年前
    _count = n if count > n else count
    time_history = time_history[-_count:]
    time_weights = list(range(1,len(time_history))) #just a simple linear weights
    time_diff = [(i-j)*k for i,j in zip(time_history[1:], time_history[:-1],time_weights)]
    speed = blockSize*(sum(time_weights)) / sum(time_diff)
    

    为了使其更稳定,并且在下载高峰时不会做出反应,您还可以添加以下内容:

    _count = n if count > n else count
    time_history = time_history[-_count:]
    time_history.remove(min(time_history))
    time_history.remove(max(time_history))
    time_weights = list(range(1, len(time_history))) #just a simple linear weights
    time_diff = [(i-j)*k for i,j in zip(time_history[1:], time_history[:-1],time_weights)]
    speed = blockSize*(sum(time_weights)) / sum(time_diff)
    

    这将移除中的最高和最低峰值 time_history 这将使数字显示更加稳定。如果您想挑剔,可以在移除之前生成权重,然后使用 time_diff.index(min(time_diff)) .

    也使用非线性函数(如 sqrt() )权重生成会给你更好的结果。哦,正如我在评论中所说:在过滤时间中添加统计方法应该会稍微好一些,但我怀疑它不值得增加开销。