dash.js 吞吐量计算模式(Throughput Calculation)完全指南:八种均值算法、配置参数与源码剖析

📅 发布时间:2026/10/12 3:12:06
dash.js 吞吐量计算模式(Throughput Calculation)完全指南:八种均值算法、配置参数与源码剖析
音视频前端【免费下载链接】dash.jsA reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.项目地址https://gitcode.com/gh_mirrors/da/dash.js点击查看免费下载dash.js 提供了多种可配置的当前平均吞吐量average throughput计算方法该计算结果是一系列 ABR自适应码率规则——如 ThroughputRule——决策下一段媒体码率的核心输入。本文将完整梳理 dash.js 支持的 8 种吞吐量计算模式及其统计含义逐一解释settings.abr.throughput下所有配置参数与默认值并结合仓库源码ThroughputController、ThroughputModel、单元测试剖析每种算法的真实实现、样本采集流程与适用场景帮助你为 VOD / Live / 低延迟流选择并调优合适的计算策略。吞吐量计算在 ABR 体系中的位置在 dash.js 中ThroughputController单例工厂见 src/streaming/controllers/ThroughputController.js负责维护每个媒体类型video / audio的吞吐量与延迟样本并提供按指定计算模式求取均值的能力。它通过监听METRIC_ADDED事件在每次 HTTP 请求完成MPD 或音视频分片时把新样本写入底层模型ThroughputModel。大多数 ABR 规则都会消费这一均值最典型的 ThroughputRule.js 核心逻辑只有两行const throughput throughputController.getSafeAverageThroughput(mediaType); switchRequest.representation abrController.getOptimalRepresentationForBitrate(mediaInfo, throughput, true);getSafeAverageThroughput()在平均吞吐量基础上乘以bandwidthSafetyFactor默认 0.9作为安全余量返回单位是 kbit/sAbrController.getOptimalRepresentationForBitrate()见 src/streaming/controllers/AbrController.js则从当前媒体信息中筛选出码率不高于该吞吐量的 Representations并返回其中absoluteIndex最大的一个即在带宽允许范围内尽量选最高码率。此外InsufficientBufferRulesrc/streaming/rules/abr/InsufficientBufferRule.js也通过getAverageThroughput(mediaType, null, NaN)获取均值并乘以自身的throughputSafetyFactor来压低码率以应对缓冲不足L2ARulesrc/streaming/rules/abr/L2ARule.js则在评估时显式指定使用ARITHMETIC_MEAN且仅取 1 个样本。可以看到平均吞吐量的算法选择会直接传导到所有下游 ABR 规则的码率决策。八种吞吐量计算模式所有模式由dashjs.Constants.THROUGHPUT_CALCULATION_MODES枚举定义源码见 src/streaming/constants/Constants.js。下表为 dash.js 支持的完整模式清单及其统计定义计算模式THROUGHPUT_CALCULATION_MODES枚举值说明EWMA指数加权移动平均Exponential Weighted Moving Average。对历史数据点赋予指数递减的权重越新的样本影响越大旧样本的影响逐渐衰减。其参数由settings.abr.throughput.ewma对象配置。ZLEMA零滞后指数移动平均Zero-Lag Exponential Moving Average。目标是降低甚至消除传统指数移动平均的滞后性通过对数据点权重进行调整来最小化延迟。ARITHMETIC_MEAN算术平均一组数值之和除以数值个数。BYTE_SIZE_WEIGHTED_ARITHMETIC_MEAN按字节大小加权的算术平均每个值乘以其对应的字节大小后求和再除以总字节数。DATE_WEIGHTED_ARITHMETIC_MEAN按时间顺序加权的算术平均每个值按日期/先后顺序赋予权重加权求和后除以总权重。HARMONIC_MEAN调和平均数值个数除以各数值倒数的和。由于涉及取倒数极端值会对计算结果产生显著影响。BYTE_SIZE_WEIGHTED_HARMONIC_MEAN类似调和平均但按各样本的字节大小分配权重。DATE_WEIGHTED_HARMONIC_MEAN类似调和平均但按日期/先后顺序分配权重最近的样本比之前的样本拥有更高权重。默认模式为EWMA。除EWMA外其余多数模式基于固定数量的吞吐量样本滑动窗口进行计算样本数量由settings.abr.throughput.sampleSettings配置。源码中的算法公式ThroughputController中每个模式都有对应实现src/streaming/controllers/ThroughputController.js可直接对照理解算术平均getArithmeticMeanL209-L222取最近sampleSize个样本Σ value / n。字节加权算术平均getByteSizeWeightedArithmeticMeanL231-L248权重为weight Math.sqrt(entry.downloadedBytes)即Σ(value × √bytes) / Σ√bytes。取平方根而非原始字节数是为了削弱大分片对结果的主导作用。日期加权算术平均getDateWeightedArithmeticMeanL257-L274对窗口内样本按先后位置赋权weight index 1越新的样本权重越大。调和平均getHarmonicMeanL283-L298n / Σ(1/value)。由于取倒数较小的吞吐量样本而非大样本会放大分母、压低均值因此结果通常比算术平均更保守——这与单元测试结果一致见下文测试验证。字节加权调和平均getByteSizeWeightedHarmonicMeanL307-L326Σ√bytes / Σ((1/value) × √bytes)。日期加权调和平均getDateWeightedHarmonicMeanL336-L355Σweight / Σ((1/value) × weight)weight index 1。EWMAgetEwmaL365-L376维护fastEstimate与slowEstimate两组状态带宽计算时取Math.min(fast, slow)useMin true更保守延迟计算时取Math.max。为纠正启动阶段从 0 开始的低估问题最终结果除以1 - Math.pow(0.5, totalWeight / halfLife)。ZLEMAgetZlemaL384-L403alpha 2 / (n 1)对最近 n 个样本先做一次 EMA、再对 EMA 结果做一次 EMA双重平滑以此补偿滞后。配置入口与完整参数清单吞吐量计算相关的全部配置位于streaming.abr.throughput命名空间下可通过player.updateSettings()动态修改。默认值定义于 src/core/Settings.js参数语义的完整 JSDoc 注释见 src/core/Settings.js。// Settings.js 中的默认配置节选 throughput: { averageCalculationMode: Constants.THROUGHPUT_CALCULATION_MODES.EWMA, lowLatencyDownloadTimeCalculationMode: Constants.LOW_LATENCY_DOWNLOAD_TIME_CALCULATION_MODE.MOOF_PARSING, useResourceTimingApi: true, useNetworkInformationApi: { xhr: false, fetch: false }, useDeadTimeLatency: true, bandwidthSafetyFactor: 0.9, sampleSettings: { live: 3, vod: 4, enableSampleSizeAdjustment: true, decreaseScale: 0.7, increaseScale: 1.3, maxMeasurementsToKeep: 20, averageLatencySampleAmount: 4 }, ewma: { throughputSlowHalfLifeSeconds: 8, throughputFastHalfLifeSeconds: 3, latencySlowHalfLifeCount: 2, latencyFastHalfLifeCount: 1, weightDownloadTimeMultiplicationFactor: 0.0015 } }各参数含义与取值建议如下参数默认值说明averageCalculationModeEWMA默认吞吐量计算模式取值为Constants.THROUGHPUT_CALCULATION_MODES中任一枚举。sampleSettings.live3Live动态流使用的吞吐量样本数滑动窗口大小。sampleSettings.vod4VOD点播流使用的吞吐量样本数。sampleSettings.enableSampleSizeAdjustmenttrue是否启用样本数自适应当最近吞吐量样本波动较大时自动扩大样本窗口。sampleSettings.decreaseScale0.7相邻样本比值当前值/前一个值小于或等于该值时样本数 1吞吐量骤降需要更宽的窗口平滑。sampleSettings.increaseScale1.3相邻样本比值大于或等于该值时样本数 1吞吐量骤升同样需要平滑。sampleSettings.maxMeasurementsToKeep20内存中最多保留的样本数超出后最旧的样本被移出滑动窗口上限。sampleSettings.averageLatencyAmount4延迟均值计算使用的样本数。ewma.throughputFastHalfLifeSeconds3快速吞吐量 EWMA 的半衰期秒数值越小对新样本响应越快。ewma.throughputSlowHalfLifeSeconds8慢速吞吐量 EWMA 的半衰期秒。ewma.latencyFastHalfLifeCount1快速延迟 EWMA 半衰期按样本条数计。ewma.latencySlowHalfLifeCount2慢速延迟 EWMA 半衰期按样本条数计。ewma.weightDownloadTimeMultiplicationFactor0.0015与下载耗时毫秒相乘得到 EWMA 权重weight factor × downloadTimeInMs。bandwidthSafetyFactor0.9标准 ABR 规则对吞吐量乘以的安全系数取值应介于 0 和 1 之间值越小越不容易缓冲但码率也更保守。useResourceTimingApitrue是否使用 Resource Timing API 获取下载字节数与下载耗时更精确。对低延迟流无效其下载时间与分片时长几乎相等无法提供可靠值。useNetworkInformationApi.xhr / fetchfalse是否使用 Network Information APInavigator.connection.downlink直接取当前带宽估计值分别作用于标准 XHR 请求与低延迟 Fetch 请求。浏览器支持有限目前仅 Chrome、Edge。useDeadTimeLatencytrue为true时仅把实际下载阶段计入吞吐量延迟视为静态部分为false时使用整个传输时间含延迟的倒数。lowLatencyDownloadTimeCalculationModeMOOF_PARSING低延迟流Fetch API 分块传输的有效下载时间估算方式另有DOWNLOADED_DATA、AAST可选。实战示例切换到字节加权调和平均模式官方示例 samples/abr/average-calculation-mode.html 演示了完整用法把默认模式改为BYTE_SIZE_WEIGHTED_HARMONIC_MEAN将样本数改为 5并关闭样本数自适应随后每秒轮询一次player.getAverageThroughput()并把结果实时显示在页面上。原文档给出的配置代码如下player.updateSettings({ streaming: { abr: { throughput: { averageCalculationMode: dashjs.Constants.THROUGHPUT_CALCULATION_MODES.BYTE_SIZE_WEIGHTED_HARMONIC_MEAN, sampleSettings: { vod: 5, enableSampleSizeAdjustment: false } }, } } });说明dashjs.Constants.THROUGHPUT_CALCULATION_MODES枚举对象在 src/streaming/constants/Constants.js 中定义枚举值为字符串如throughputCalculationModeByteSizeWeightedHarmonicMean因此也可以在配置中直接写字符串。通过updateSettings()传入的配置会与默认配置深度合并未提及的字段如ewma、live、bandwidthSafetyFactor等保持默认值不变。sampleSettings是运行时按播放场景选择的ThroughputController._getAverage()src/streaming/controllers/ThroughputController.js在未显式指定sampleSize时会根据playbackController.getIsDynamic()自动取sampleSettings.live或sampleSettings.vod。本示例只改vod意味着对点播生效而 Live 仍沿用默认的 3 个样本。示例页面还演示了如何读取结果player.getAverageThroughput(video)/(audio)返回值已由ThroughputController.getAverageThroughput()src/streaming/controllers/ThroughputController.js四舍五入单位为 kbit/s。源码级原理样本从采集到均值计算1. 样本采集ThroughputModel每次 HTTP 请求完成后ThroughputController通过METRIC_ADDED事件把请求对象交给ThroughputModel.addEntry()src/streaming/models/ThroughputModel.js其中只有MPD请求以及 mediaType 为audio/video的媒体分片请求会被计入src/streaming/controllers/ThroughputController.js。吞吐量以 kbit/s 存储延迟以毫秒存储。XHR 路径_calculateThroughputValuesForXhrL188-L227优先用 Resource Timing API 的transferSize与responseEnd - responseStart否则要求trace至少 2 条记录用第 2 条之后的增量计算首条记录包含请求延迟需剔除公式为Math.round((8 × bytes) / time)bits/ms 即 kbits/s。useDeadTimeLatency决定时间基准是否包含延迟。Fetch 路径低延迟流_calculateThroughputValuesForFetchL161-L179累加trace中的字节与耗时计算。缓存响应会被剔除_isCachedResponseL251-L265基于cacheLoadThresholdsvideo/audio 各自的阈值按请求发起到完成的耗时判断或 Resource Timing 的transferSize 0 decodedBodySize 0识别避免缓存瞬时响应扭曲带宽估计。若启用 Network Information API则直接使用navigator.connection.downlink × 1000作为吞吐量_deriveThroughputFromNetworkApiL234-L241。样本写入后由_cleanupDict()L295-L303按maxMeasurementsToKeep修剪旧样本。同时_updateEwmaValues()L275-L288用fastAlpha 0.5^(weight/halfLife)增量维护 fast/slow 两组 EWMA 状态权重为weightDownloadTimeMultiplicationFactor × downloadTimeInMs。2. 样本数选择与自适应调整ThroughputController._getAdjustedSampleSize()src/streaming/controllers/ThroughputController.js负责确定最终使用的样本窗口若sampleSize dict.length直接使用全部可用样本若带宽类型且enableSampleSizeAdjustment true则从最近样本开始向前逐对比较相邻比值当当前值/前值 ≥ increaseScale (1.3)或≤ decreaseScale (0.7)时sampleSize 1最多扩展到样本总数。这意味着当网络波动剧烈时窗口会自动加宽以换取更平滑的均值反之波动小时保持小窗口、响应更快。3. 延迟计算getAverageLatency()L442-L446走LATENCY分支样本数取averageLatencySampleAmount且 EWMA 模式对延迟使用Math.max(fast, slow)与带宽相反倾向于估计更差的延迟。测试验证模式差异的可复现证据仓库单元测试 test/unit/test/streaming/streaming.controllers.ThroughputController.js 对每种均值算法都给出了带期望值的断言可以直接验证上述公式getArithmeticMean([{value:6},{value:2},{value:3},{value:1}]) 3getByteSizeWeightedArithmeticMean([{value:10,downloadedBytes:9},{value:5,downloadedBytes:16},{value:20,downloadedBytes:9}]) 11getDateWeightedArithmeticMean([{value:6},{value:2},{value:3},{value:5}]) 3.9getHarmonicMean([{value:6},{value:2},{value:3}]) 3getByteSizeWeightedHarmonicMean同上三组数据 8getZlema([{value:100},{value:100},{value:80},{value:2},{value:2},{value:2}]) ≈ 31基于同一批 Resource Timing API 样本getAverageThroughput()在不同模式下返回算术平均120000kbit/s、调和平均72000kbit/s、字节加权算术平均148949kbit/s、字节加权调和平均83768kbit/s。可见调和族模式结果显著低于算术族——因为吞吐量波动较大时调和平均对低值样本更敏感、更保守这有助于在带宽抖动时避免虚高估计导致选码过激进。选型建议场景推荐模式理由默认/大多数 VOD 场景EWMA默认对历史数据指数衰减兼顾稳定性与对新样本的响应且有 fast/slow 双半衰期 min保守化处理。带宽频繁波动、追求更少卡顿HARMONIC_MEAN或BYTE_SIZE_WEIGHTED_HARMONIC_MEAN结果更保守低值样本主导避免高估带宽。大分片与小块差异明显的流BYTE_SIZE_WEIGHTED_*系列用√downloadedBytes加权降低分片体积差异对均值的扭曲。需要更激进、快速追码率ZLEMA双重 EMA 平滑以消除滞后对新趋势反应更快代价是可能更易受噪声影响。网络突降需要迅速刹车开启enableSampleSizeAdjustment默认开启比值跌破decreaseScale 0.7时自动扩大窗口让均值更快反映带宽恶化。注意averageCalculationMode是全局默认模式但个别规则如L2ARule会显式指定自己的模式与样本数调用getAverageThroughput()因此实际选码时不同规则可能采用不同算法最终由 ABR 规则调度汇总各规则的SwitchRequest决定。延伸阅读ThroughputRule 详解吞吐量均值最直接的消费方ABR 设置总览streaming.abr下全部规则与参数完整默认配置源码src/core/Settings.js计算实现src/streaming/controllers/ThroughputController.js、src/streaming/models/ThroughputModel.js可运行示例samples/abr/average-calculation-mode.html单元测试test/unit/test/streaming/streaming.controllers.ThroughputController.js。赞分享音视频前端【免费下载链接】dash.jsA reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.项目地址https://gitcode.com/gh_mirrors/da/dash.js点击查看免费下载相关推荐Surprise 协同聚类 CoClustering 算法完全指南预测公式、参数配置与源码实现剖析Surprise 协同聚类 CoClustering 算法完全指南预测公式、参数配置与源码实现剖析 导读 本文以 Surprise 推荐系统库的 CoClus机器学习人工智能autocannon请求合并算法提高API吞吐量的设计模式autocannon请求合并算法提高API吞吐量的设计模式 什么是请求合并算法 在现代Web应用中API请求的处理效率直接影响用户体验和系统稳定性。当大量并性能测试测试开发工具CubiFS存储网络带宽规划吞吐量计算完全指南CubiFS存储网络带宽规划吞吐量计算完全指南 在当今数据驱动的时代 CubiFS分布式文件系统 已成为企业级存储解决方案的重要选择。作为一款开源的高性能分存储分布式文件系统对象存储云原生上一篇如何5分钟完成Windows系统全面优化免费工具终极指南下一篇Koel Plus 自定义主题Custom Themes实战指南从创建表单到 CSS 变量生效的完整链路创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考