SegmentTemplate@endNumber is treated as a segment count, ignoring startNumber

オープン 初心者向け
#193 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
85/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
javascript
領域
backend

調査の方向性

まず src/segment/durationTimeParser.js、特に segmentRange.static、segmentRange.dynamic、parseByDuration を確認してください。issue には、返される範囲がどのように使われるかが記載されています。次に、"parseByDuration uses endNumber and has correct duration" という名前のテストを見つけ、デフォルト以外の startNumber のケースをカバーするテストを追加してください。このケースで、生成されるセグメント数と最初および最後のセグメント番号が期待される結果と一致すれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Description

segmentRange.static and segmentRange.dynamic (src/segment/durationTimeParser.js) return
end: endNumber. parseByDuration then generates range(start, end) and numbers each segment
startNumber + i.

DASH defines @endNumber as the number of the last segment, so the segment count is
endNumber - startNumber + 1. With a non-default startNumber, the parser generates the wrong
number of segments. With a large startNumber, it generates far too many.

The behaviour came in with endNumber support in #120. Its tests only use the default
startNumber of 1, where endNumber happens to equal the count.

Real-world impact: our packager numbers a thumbnail track in epoch seconds
(startNumber="179120790" endNumber="179121419", 630 segments). The parser tries to build 179
million segments.

  • Firefox: the page freezes for about 20 s and then the script dies from running out of memory.
  • Chrome: a RangeError is thrown.

We hit this through a third-party SDK that bundles mpd-parser.

Steps to reproduce

mpd-parser 1.4.0:

const { parse } = require('mpd-parser');
const mpd = (start, end) => `<?xml version="1.0"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" type="static" mediaPresentationDuration="PT100S" profiles="urn:mpeg:dash:profile:isoff-live:2011">
  <Period id="1" start="PT0S">
    <AdaptationSet mimeType="video/mp4" contentType="video">
      <SegmentTemplate timescale="1" duration="10" media="seg-$Number$.m4s" initialization="init.mp4" startNumber="${start}" endNumber="${end}"/>
      <Representation id="v1" bandwidth="1000000" width="640" height="360" codecs="avc1.4d401e"/>
    </AdaptationSet>
  </Period>
</MPD>`;
for (const [s, e] of [[1, 10], [1000, 1009]]) {
  const segs = parse(mpd(s, e), { manifestUri: 'https://example.com/manifest.mpd' }).playlists[0].segments;
  console.log(`startNumber=${s} endNumber=${e}: ${segs.length} segments, ${segs[0].uri} .. ${segs.at(-1).uri}`);
}

Results

Expected:

startNumber=1 endNumber=10: 10 segments, seg-1.m4s .. seg-10.m4s
startNumber=1000 endNumber=1009: 10 segments, seg-1000.m4s .. seg-1009.m4s

Actual:

startNumber=1 endNumber=10: 10 segments, seg-1.m4s .. seg-10.m4s
startNumber=1000 endNumber=1009: 1009 segments, seg-1000.m4s .. seg-2008.m4s

Suggested fix

static(attributes) {
  const { duration, timescale = 1, sourceDuration, periodDuration, startNumber = 1 } = attributes;
  const endNumber = parseEndNumber(attributes.endNumber);
  // ...
  if (typeof endNumber === 'number') {
    return { start: 0, end: endNumber - startNumber + 1 };
  }

Apply the same change in dynamic:
end: typeof endNumber === 'number' ? endNumber - startNumber + 1 : Math.min(...).

Also add a test with a non-default startNumber next to "parseByDuration uses endNumber and has
correct duration". Happy to open a PR.

主要言語
JavaScript
スター
89
フォーク
60
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

videojs/mpd-parser のほかの issue

videojs/mpd-parser の issue をすべて見る

似ている issue

JavaScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。