mirror of
https://github.com/videojs/m3u8-parser.git
synced 2026-06-06 08:22:33 +00:00
Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6869ee6fa |
195 changed files with 8159 additions and 11258 deletions
77
.github/workflows/ci.yml
vendored
77
.github/workflows/ci.yml
vendored
|
|
@ -1,77 +0,0 @@
|
|||
name: ci
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
should-skip:
|
||||
continue-on-error: true
|
||||
runs-on: ubuntu-latest
|
||||
# Map a step output to a job output
|
||||
outputs:
|
||||
should-skip-job: ${{steps.skip-check.outputs.should_skip}}
|
||||
steps:
|
||||
- id: skip-check
|
||||
uses: fkirc/skip-duplicate-actions@v2.1.0
|
||||
with:
|
||||
github_token: ${{github.token}}
|
||||
|
||||
ci:
|
||||
needs: should-skip
|
||||
if: ${{needs.should-skip.outputs.should-skip-job != 'true'}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
env:
|
||||
BROWSER_STACK_USERNAME: ${{secrets.BROWSER_STACK_USERNAME}}
|
||||
BROWSER_STACK_ACCESS_KEY: ${{secrets.BROWSER_STACK_ACCESS_KEY}}
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.npm
|
||||
**/node_modules
|
||||
key: ${{runner.os}}-npm-${{hashFiles('**/package-lock.json')}}
|
||||
restore-keys: |
|
||||
${{runner.os}}-npm-
|
||||
${{runner.os}}-
|
||||
|
||||
- name: read node version from .nvmrc
|
||||
run: echo ::set-output name=NVMRC::$(cat .nvmrc)
|
||||
shell: bash
|
||||
id: nvm
|
||||
|
||||
- name: update apt cache on linux w/o browserstack
|
||||
run: sudo apt-get update
|
||||
if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
|
||||
|
||||
- name: install ffmpeg/pulseaudio for firefox on linux w/o browserstack
|
||||
run: sudo apt-get install ffmpeg pulseaudio
|
||||
if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
|
||||
|
||||
- name: start pulseaudio for firefox on linux w/o browserstack
|
||||
run: pulseaudio -D
|
||||
if: ${{startsWith(matrix.os, 'ubuntu') && !env.BROWSER_STACK_USERNAME}}
|
||||
|
||||
- name: setup node
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '${{steps.nvm.outputs.NVMRC}}'
|
||||
|
||||
# turn off the default setup-node problem watchers...
|
||||
- run: echo "::remove-matcher owner=eslint-compact::"
|
||||
- run: echo "::remove-matcher owner=eslint-stylish::"
|
||||
- run: echo "::remove-matcher owner=tsc::"
|
||||
|
||||
- name: npm install
|
||||
run: npm i --prefer-offline --no-audit
|
||||
|
||||
- name: run npm test
|
||||
uses: GabrielBB/xvfb-action@v1
|
||||
with:
|
||||
run: npm run test
|
||||
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
10
|
||||
lts/carbon
|
||||
|
|
|
|||
16
.travis.yml
Normal file
16
.travis.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
sudo: false
|
||||
dist: trusty
|
||||
language: node_js
|
||||
# node version is specified using the .nvmrc file
|
||||
before_install:
|
||||
- npm install -g greenkeeper-lockfile@1
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- greenkeeper-lockfile-update
|
||||
after_script:
|
||||
- greenkeeper-lockfile-upload
|
||||
addons:
|
||||
firefox: latest
|
||||
chrome: stable
|
||||
|
||||
162
CHANGELOG.md
162
CHANGELOG.md
|
|
@ -1,165 +1,3 @@
|
|||
<a name="7.2.0"></a>
|
||||
# [7.2.0](https://github.com/videojs/m3u8-parser/compare/v7.1.0...v7.2.0) (2024-08-21)
|
||||
|
||||
### Features
|
||||
|
||||
* add support for #EXT-X-DEFINE ([#185](https://github.com/videojs/m3u8-parser/issues/185)) ([ba6e7cb](https://github.com/videojs/m3u8-parser/commit/ba6e7cb))
|
||||
* add support for #EXT-X-I-FRAME-STREAM-INF ([#171](https://github.com/videojs/m3u8-parser/issues/171)) ([990c6ce](https://github.com/videojs/m3u8-parser/commit/990c6ce)), closes [/datatracker.ietf.org/doc/html/rfc8216#section-4](https://github.com//datatracker.ietf.org/doc/html/rfc8216/issues/section-4) [/datatracker.ietf.org/doc/html/rfc8216#section-4](https://github.com//datatracker.ietf.org/doc/html/rfc8216/issues/section-4)
|
||||
* add support for #EXT-X-I-FRAMES-ONLY ([#173](https://github.com/videojs/m3u8-parser/issues/173)) ([e5dbdb6](https://github.com/videojs/m3u8-parser/commit/e5dbdb6)), closes [/datatracker.ietf.org/doc/html/rfc8216#section-4](https://github.com//datatracker.ietf.org/doc/html/rfc8216/issues/section-4) [#171](https://github.com/videojs/m3u8-parser/issues/171)
|
||||
|
||||
### Chores
|
||||
|
||||
* add content-steering tag to readme ([#177](https://github.com/videojs/m3u8-parser/issues/177)) ([f8c9817](https://github.com/videojs/m3u8-parser/commit/f8c9817))
|
||||
* update vhs-utils dependency ([#182](https://github.com/videojs/m3u8-parser/issues/182)) ([c060bc7](https://github.com/videojs/m3u8-parser/commit/c060bc7))
|
||||
|
||||
<a name="7.1.0"></a>
|
||||
# [7.1.0](https://github.com/videojs/m3u8-parser/compare/v7.0.0...v7.1.0) (2023-08-07)
|
||||
|
||||
### Features
|
||||
|
||||
* parse content steering tags and attributes ([#176](https://github.com/videojs/m3u8-parser/issues/176)) ([42472c5](https://github.com/videojs/m3u8-parser/commit/42472c5))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add dateTimeObject and dateTimeString for backward compatibility ([#174](https://github.com/videojs/m3u8-parser/issues/174)) ([6944bb1](https://github.com/videojs/m3u8-parser/commit/6944bb1))
|
||||
* merge dateRange tags with same IDs and no conflicting attributes ([#175](https://github.com/videojs/m3u8-parser/issues/175)) ([73d934c](https://github.com/videojs/m3u8-parser/commit/73d934c))
|
||||
|
||||
### Chores
|
||||
|
||||
* update v7.0.0 documentation ([#172](https://github.com/videojs/m3u8-parser/issues/172)) ([72da994](https://github.com/videojs/m3u8-parser/commit/72da994))
|
||||
|
||||
<a name="7.0.0"></a>
|
||||
# [7.0.0](https://github.com/videojs/m3u8-parser/compare/v6.2.0...v7.0.0) (2023-07-10)
|
||||
|
||||
### Features
|
||||
|
||||
* Add PDT to each segment ([#168](https://github.com/videojs/m3u8-parser/issues/168)) ([e7c683f](https://github.com/videojs/m3u8-parser/commit/e7c683f))
|
||||
* output segment title from EXTINF ([#158](https://github.com/videojs/m3u8-parser/issues/158)) ([4adaa2c](https://github.com/videojs/m3u8-parser/commit/4adaa2c))
|
||||
|
||||
### Documentation
|
||||
|
||||
* correct `customType` option name ([#147](https://github.com/videojs/m3u8-parser/issues/147)) ([4d3e6ce](https://github.com/videojs/m3u8-parser/commit/4d3e6ce))
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* rename `daterange` to `dateRanges`
|
||||
* remove `dateTimeObject` and `dateTimeString` from parsed segment and replaces it with `programDateTime` which represents the timestamp in milliseconds
|
||||
|
||||
<a name="6.2.0"></a>
|
||||
# [6.2.0](https://github.com/videojs/m3u8-parser/compare/v6.1.0...v6.2.0) (2023-05-25)
|
||||
|
||||
### Features
|
||||
|
||||
* add independent-segments support ([#165](https://github.com/videojs/m3u8-parser/issues/165)) ([8c47d81](https://github.com/videojs/m3u8-parser/commit/8c47d81))
|
||||
|
||||
<a name="6.1.0"></a>
|
||||
# [6.1.0](https://github.com/videojs/m3u8-parser/compare/v6.0.0...v6.1.0) (2023-05-12)
|
||||
|
||||
<a name="6.0.0"></a>
|
||||
# [6.0.0](https://github.com/videojs/m3u8-parser/compare/v5.0.0...v6.0.0) (2022-09-27)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* non standard tag match ([#156](https://github.com/videojs/m3u8-parser/issues/156)) ([8d56f30](https://github.com/videojs/m3u8-parser/commit/8d56f30)), closes [#22](https://github.com/videojs/m3u8-parser/issues/22)
|
||||
|
||||
### Chores
|
||||
|
||||
* don't run tests on version ([b84575f](https://github.com/videojs/m3u8-parser/commit/b84575f))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Missing colon (:) tag delimiters are no longer supported
|
||||
|
||||
<a name="5.0.0"></a>
|
||||
# [5.0.0](https://github.com/videojs/m3u8-parser/compare/v4.7.1...v5.0.0) (2022-08-19)
|
||||
|
||||
### Features
|
||||
|
||||
* parse FRAME-RATE as a number ([#150](https://github.com/videojs/m3u8-parser/issues/150)) ([d51e93f](https://github.com/videojs/m3u8-parser/commit/d51e93f))
|
||||
|
||||
### Chores
|
||||
|
||||
* do not run es-check on publish ([#153](https://github.com/videojs/m3u8-parser/issues/153)) ([4e0bc63](https://github.com/videojs/m3u8-parser/commit/4e0bc63))
|
||||
* remove IE11 support ([#152](https://github.com/videojs/m3u8-parser/issues/152)) ([fc12241](https://github.com/videojs/m3u8-parser/commit/fc12241))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Internet Explorer is no longer supported.
|
||||
* parser changes an output type for 'FRAME-RATE'
|
||||
attribute from a string to a number.
|
||||
|
||||
<a name="4.7.1"></a>
|
||||
## [4.7.1](https://github.com/videojs/m3u8-parser/compare/v4.7.0...v4.7.1) (2022-04-05)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* EXT-X-KEY support playready keyformat ([#143](https://github.com/videojs/m3u8-parser/issues/143)) ([4e7c9eb](https://github.com/videojs/m3u8-parser/commit/4e7c9eb))
|
||||
* update vhs-utils to 3.0.5 for tizen 2.4 support ([#149](https://github.com/videojs/m3u8-parser/issues/149)) ([efce797](https://github.com/videojs/m3u8-parser/commit/efce797))
|
||||
|
||||
<a name="4.7.0"></a>
|
||||
# [4.7.0](https://github.com/videojs/m3u8-parser/compare/v4.6.0...v4.7.0) (2021-05-19)
|
||||
|
||||
### Features
|
||||
|
||||
* add key property to init segment/map ([#141](https://github.com/videojs/m3u8-parser/issues/141)) ([ae5fa64](https://github.com/videojs/m3u8-parser/commit/ae5fa64))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ignore fairplay content protection ([#140](https://github.com/videojs/m3u8-parser/issues/140)) ([9f62c85](https://github.com/videojs/m3u8-parser/commit/9f62c85))
|
||||
|
||||
<a name="4.6.0"></a>
|
||||
# [4.6.0](https://github.com/videojs/m3u8-parser/compare/v4.5.2...v4.6.0) (2021-03-04)
|
||||
|
||||
### Features
|
||||
|
||||
* add support for #EXT-X-PART ([#127](https://github.com/videojs/m3u8-parser/issues/127)) ([9f5a224](https://github.com/videojs/m3u8-parser/commit/9f5a224)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3282436](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3282436) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add support for #EXT-X-PART-INF ([#126](https://github.com/videojs/m3u8-parser/issues/126)) ([985ab68](https://github.com/videojs/m3u8-parser/commit/985ab68)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3282434](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3282434) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add support for #EXT-X-PRELOAD-HINT ([#123](https://github.com/videojs/m3u8-parser/issues/123)) ([4fd693a](https://github.com/videojs/m3u8-parser/commit/4fd693a)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3526694](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3526694) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add support for #EXT-X-RENDITION-REPORT ([#124](https://github.com/videojs/m3u8-parser/issues/124)) ([03f4345](https://github.com/videojs/m3u8-parser/commit/03f4345)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3282435](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3282435) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add support for #EXT-X-SERVER-CONTROL ([#121](https://github.com/videojs/m3u8-parser/issues/121)) ([7f82f53](https://github.com/videojs/m3u8-parser/commit/7f82f53)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3281374](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3281374) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add support for #EXT-X-SKIP ([#122](https://github.com/videojs/m3u8-parser/issues/122)) ([9cebc86](https://github.com/videojs/m3u8-parser/commit/9cebc86)), closes [/developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls#3282433](https://github.com//developer.apple.com/documentation/http_live_streaming/enabling_low-latency_hls/issues/3282433) [/tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-4](https://github.com//tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08/issues/section-4)
|
||||
* add version parsing and remove totalduration ([#135](https://github.com/videojs/m3u8-parser/issues/135)) ([98f0421](https://github.com/videojs/m3u8-parser/commit/98f0421))
|
||||
* add warn/info triggers and defaults for ll-hls tags ([#131](https://github.com/videojs/m3u8-parser/issues/131)) ([4f4da3d](https://github.com/videojs/m3u8-parser/commit/4f4da3d))
|
||||
* **llhls:** preloadSegment, associate parts/preloadHints with segments, unify byterange handling ([#137](https://github.com/videojs/m3u8-parser/issues/137)) ([2c2dffe](https://github.com/videojs/m3u8-parser/commit/2c2dffe))
|
||||
|
||||
### Chores
|
||||
|
||||
* lint fixtures ([#134](https://github.com/videojs/m3u8-parser/issues/134)) ([e09c7ed](https://github.com/videojs/m3u8-parser/commit/e09c7ed))
|
||||
* remove unused and non-standard tag #ZEN-TOTAL-DURATION ([#133](https://github.com/videojs/m3u8-parser/issues/133)) ([fb3b629](https://github.com/videojs/m3u8-parser/commit/fb3b629))
|
||||
* switch to rollup-plugin-data-files ([#130](https://github.com/videojs/m3u8-parser/issues/130)) ([8f69b45](https://github.com/videojs/m3u8-parser/commit/8f69b45))
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* llhls attributes to camel case ([#138](https://github.com/videojs/m3u8-parser/issues/138)) ([31ed052](https://github.com/videojs/m3u8-parser/commit/31ed052))
|
||||
|
||||
### Tests
|
||||
|
||||
* add llhls manifests for incoming features ([#125](https://github.com/videojs/m3u8-parser/issues/125)) ([0823ea8](https://github.com/videojs/m3u8-parser/commit/0823ea8))
|
||||
* move tests around ([#129](https://github.com/videojs/m3u8-parser/issues/129)) ([e86dcae](https://github.com/videojs/m3u8-parser/commit/e86dcae))
|
||||
|
||||
<a name="4.5.2"></a>
|
||||
## [4.5.2](https://github.com/videojs/m3u8-parser/compare/v4.5.1...v4.5.2) (2021-01-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* cjs dist should import only cjs ([#120](https://github.com/videojs/m3u8-parser/issues/120)) ([a58149d](https://github.com/videojs/m3u8-parser/commit/a58149d))
|
||||
|
||||
<a name="4.5.1"></a>
|
||||
## [4.5.1](https://github.com/videojs/m3u8-parser/compare/v4.5.0...v4.5.1) (2021-01-11)
|
||||
|
||||
### Chores
|
||||
|
||||
* update to vhs-utils[@3](https://github.com/3) ([#118](https://github.com/videojs/m3u8-parser/issues/118)) ([f701c0f](https://github.com/videojs/m3u8-parser/commit/f701c0f))
|
||||
|
||||
<a name="4.5.0"></a>
|
||||
# [4.5.0](https://github.com/videojs/m3u8-parser/compare/v4.4.3...v4.5.0) (2020-11-03)
|
||||
|
||||
### Chores
|
||||
|
||||
* **package:** update to vhs-utils[@2](https://github.com/2) ([#117](https://github.com/videojs/m3u8-parser/issues/117)) ([57ac9d2](https://github.com/videojs/m3u8-parser/commit/57ac9d2))
|
||||
|
||||
<a name="4.4.3"></a>
|
||||
## [4.4.3](https://github.com/videojs/m3u8-parser/compare/v4.4.2...v4.4.3) (2020-08-12)
|
||||
|
||||
|
|
|
|||
35
README.md
35
README.md
|
|
@ -13,13 +13,12 @@ m3u8 parser
|
|||
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Constructor Options](#constructor-options)
|
||||
- [Parsed Output](#parsed-output)
|
||||
- [Supported Tags](#supported-tags)
|
||||
- [Basic Playlist Tags](#basic-playlist-tags)
|
||||
- [Media Segment Tags](#media-segment-tags)
|
||||
- [Media Playlist Tags](#media-playlist-tags)
|
||||
- [Main Playlist Tags](#main-playlist-tags)
|
||||
- [Master Playlist Tags](#master-playlist-tags)
|
||||
- [Experimental Tags](#experimental-tags)
|
||||
- [EXT-X-CUE-OUT](#ext-x-cue-out)
|
||||
- [EXT-X-CUE-OUT-CONT](#ext-x-cue-out-cont)
|
||||
|
|
@ -58,7 +57,6 @@ var manifest = [
|
|||
'0.ts',
|
||||
'#EXTINF:6,',
|
||||
'1.ts',
|
||||
'#EXT-X-PROGRAM-DATE-TIME:2019-02-14T02:14:00.106Z'
|
||||
'#EXTINF:6,',
|
||||
'2.ts',
|
||||
'#EXT-X-ENDLIST'
|
||||
|
|
@ -71,21 +69,6 @@ parser.end();
|
|||
|
||||
var parsedManifest = parser.manifest;
|
||||
```
|
||||
### Constructor Options
|
||||
|
||||
The constructor optinally takes an options object with two properties. These are needed when using `#EXT-X-DEFINE` for variable replacement.
|
||||
|
||||
```js
|
||||
var parser = new m3u8Parser.Parser({
|
||||
url: 'https://exmaple.com/video.m3u8?param_a=34¶m_b=abc',
|
||||
mainDefinitions: {
|
||||
param_c: 'def'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
* `options.url` _string_ The URL from which the playlist was fetched. If the request was redirected this should be the final URL. This is required if using `QUERYSTRING` rules with `#EXT-X-DEFINE`.
|
||||
* `options.mainDefinitions` _object_ An object of definitions from the main playlist. This is required if using `IMPORT` rules with `#EXT-X-DEFINE`.
|
||||
|
||||
### Parsed Output
|
||||
|
||||
|
|
@ -96,7 +79,6 @@ Manifest {
|
|||
allowCache: boolean,
|
||||
endList: boolean,
|
||||
mediaSequence: number,
|
||||
dateRanges: [],
|
||||
discontinuitySequence: number,
|
||||
playlistType: string,
|
||||
custom: {},
|
||||
|
|
@ -131,13 +113,11 @@ Manifest {
|
|||
discontinuityStarts: [number],
|
||||
segments: [
|
||||
{
|
||||
title: string,
|
||||
byterange: {
|
||||
length: number,
|
||||
offset: number
|
||||
},
|
||||
duration: number,
|
||||
programDateTime: number,
|
||||
attributes: {},
|
||||
discontinuity: number,
|
||||
uri: string,
|
||||
|
|
@ -178,8 +158,6 @@ Manifest {
|
|||
* [EXT-X-KEY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.4)
|
||||
* [EXT-X-MAP](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.5)
|
||||
* [EXT-X-PROGRAM-DATE-TIME](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.6)
|
||||
* [EXT-X-DATERANGE](https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming-23#section-4.3.2.7)
|
||||
* [EXT-X-I-FRAMES-ONLY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.6)
|
||||
|
||||
### Media Playlist Tags
|
||||
|
||||
|
|
@ -189,16 +167,11 @@ Manifest {
|
|||
* [EXT-X-ENDLIST](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.4)
|
||||
* [EXT-X-PLAYLIST-TYPE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.5)
|
||||
* [EXT-X-START](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.5.2)
|
||||
* [EXT-X-INDEPENDENT-SEGMENTS](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.5.1)
|
||||
* [EXT-X-DEFINE](https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.2.3)
|
||||
|
||||
### Main Playlist Tags
|
||||
### Master Playlist Tags
|
||||
|
||||
* [EXT-X-MEDIA](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.1)
|
||||
* [EXT-X-STREAM-INF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.2)
|
||||
* [EXT-X-I-FRAME-STREAM-INF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.3)
|
||||
* [EXT-X-CONTENT-STEERING](https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.6.6)
|
||||
* [EXT-X-DEFINE](https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.2.3)
|
||||
|
||||
### Experimental Tags
|
||||
|
||||
|
|
@ -263,8 +236,12 @@ Example media playlist using `EXT-X-CUE-` tags.
|
|||
|
||||
### Not Yet Supported
|
||||
|
||||
* [EXT-X-DATERANGE](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.2.7)
|
||||
* [EXT-X-I-FRAMES-ONLY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.3.6)
|
||||
* [EXT-X-I-FRAME-STREAM-INF](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.3)
|
||||
* [EXT-X-SESSION-DATA](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.4)
|
||||
* [EXT-X-SESSION-KEY](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.4.5)
|
||||
* [EXT-X-INDEPENDENT-SEGMENTS](http://tools.ietf.org/html/draft-pantos-http-live-streaming#section-4.3.5.1)
|
||||
|
||||
### Custom Parsers
|
||||
|
||||
|
|
|
|||
8458
package-lock.json
generated
8458
package-lock.json
generated
File diff suppressed because it is too large
Load diff
46
package.json
46
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "m3u8-parser",
|
||||
"version": "7.2.0",
|
||||
"version": "4.4.3",
|
||||
"description": "m3u8 parser",
|
||||
"main": "dist/m3u8-parser.cjs.js",
|
||||
"module": "dist/m3u8-parser.es.js",
|
||||
|
|
@ -25,17 +25,19 @@
|
|||
"scripts": {
|
||||
"build-test": "cross-env-shell TEST_BUNDLE_ONLY=1 'npm run build'",
|
||||
"build-prod": "cross-env-shell NO_TEST_BUNDLE=1 'npm run build'",
|
||||
"build": "npm-run-all -s clean -p build:*",
|
||||
"build-test-data": "node scripts/m3u8.js",
|
||||
"build": "npm-run-all -s clean build-test-data -p build:*",
|
||||
"build:js": "rollup -c scripts/rollup.config.js",
|
||||
"clean": "shx rm -rf ./dist ./test/dist && shx mkdir -p ./dist ./test/dist",
|
||||
"lint": "vjsstandard",
|
||||
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose --skip-es-check",
|
||||
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose",
|
||||
"start": "npm-run-all -p server watch",
|
||||
"server": "karma start scripts/karma.conf.js --singleRun=false --auto-watch",
|
||||
"test": "npm-run-all lint build-test test:*",
|
||||
"test:browser": "karma start scripts/karma.conf.js",
|
||||
"test:node": "qunit test/dist/bundle.js",
|
||||
"posttest": "shx cat test/dist/coverage/text.txt",
|
||||
"preversion": "npm test",
|
||||
"version": "is-prerelease || npm run update-changelog && git add CHANGELOG.md",
|
||||
"update-changelog": "conventional-changelog -p videojs -i CHANGELOG.md -s",
|
||||
"watch": "npm-run-all -p watch:*",
|
||||
|
|
@ -64,32 +66,40 @@
|
|||
"test/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@videojs/vhs-utils": "^4.1.1",
|
||||
"global": "^4.4.0"
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@videojs/vhs-utils": "^1.1.0",
|
||||
"global": "^4.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-replace": "^2.3.4",
|
||||
"@videojs/generator-helpers": "~2.0.1",
|
||||
"karma": "^5.2.3",
|
||||
"rollup": "^2.38.0",
|
||||
"rollup-plugin-data-files": "^0.1.0",
|
||||
"sinon": "^9.2.3",
|
||||
"videojs-generate-karma-config": "^8.0.1",
|
||||
"videojs-generate-rollup-config": "~7.0.0",
|
||||
"videojs-generator-verify": "~3.0.1",
|
||||
"videojs-standard": "^8.0.4"
|
||||
"rollup": "^1.19.4",
|
||||
"@videojs/generator-helpers": "~1.2.0",
|
||||
"karma": "^4.0.0",
|
||||
"sinon": "^7.2.2",
|
||||
"videojs-generate-karma-config": "~5.3.1",
|
||||
"videojs-generator-verify": "~2.0.0",
|
||||
"videojs-generate-rollup-config": "~5.0.1",
|
||||
"videojs-standard": "^8.0.3"
|
||||
},
|
||||
"generator-videojs-plugin": {
|
||||
"version": "7.7.3"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults",
|
||||
"ie 11"
|
||||
],
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": "vjsstandard --fix",
|
||||
"README.md": "doctoc --notitle"
|
||||
"*.js": [
|
||||
"vjsstandard --fix",
|
||||
"git add"
|
||||
],
|
||||
"README.md": [
|
||||
"doctoc --notitle",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
83
scripts/export-m3u8s.js
Normal file
83
scripts/export-m3u8s.js
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
'use strict';
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const basePath = path.resolve(__dirname, '..');
|
||||
const testDataDir = path.join(basePath, 'test');
|
||||
const manifestDir = path.join(basePath, 'test', 'fixtures', 'm3u8');
|
||||
const manifestFilepath = path.join(testDataDir, 'dist', 'test-manifests.js');
|
||||
const expectedFilepath = path.join(testDataDir, 'dist', 'test-expected.js');
|
||||
|
||||
const build = function() {
|
||||
let manifests = 'export default {\n';
|
||||
let expected = 'export default {\n';
|
||||
|
||||
const files = fs.readdirSync(manifestDir);
|
||||
|
||||
while (files.length > 0) {
|
||||
const file = path.resolve(manifestDir, files.shift());
|
||||
const extname = path.extname(file);
|
||||
|
||||
if (extname === '.m3u8') {
|
||||
// translate this manifest
|
||||
manifests += ' \'' + path.basename(file, '.m3u8') + '\': ';
|
||||
manifests += fs.readFileSync(file, 'utf8')
|
||||
.split(/\r\n|\n/)
|
||||
// quote and concatenate
|
||||
.map(function(line) {
|
||||
return ' \'' + line + '\\n\' +\n';
|
||||
}).join('')
|
||||
// strip leading spaces and the trailing '+'
|
||||
.slice(4, -3);
|
||||
manifests += ',\n';
|
||||
} else if (extname === '.json') {
|
||||
// append the expected parse
|
||||
expected += ' "' + path.basename(file, '.json') + '": ';
|
||||
expected += fs.readFileSync(file, 'utf8');
|
||||
expected += ',\n';
|
||||
} else {
|
||||
console.log('Unknown file ' + file + ' found in manifest dir ' + manifestDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// clean up and close the objects
|
||||
manifests = manifests.slice(0, -2);
|
||||
manifests += '\n};\n';
|
||||
expected = expected.slice(0, -2);
|
||||
expected += '\n};\n';
|
||||
|
||||
fs.writeFileSync(manifestFilepath, manifests);
|
||||
fs.writeFileSync(expectedFilepath, expected);
|
||||
console.log('Wrote test data file ' + manifestFilepath);
|
||||
console.log('Wrote test data file ' + expectedFilepath);
|
||||
};
|
||||
|
||||
const watch = function() {
|
||||
build();
|
||||
fs.watch(manifestDir, function(event, filename) {
|
||||
console.log('files in manifest dir were changed rebuilding manifest data');
|
||||
build();
|
||||
});
|
||||
};
|
||||
|
||||
const clean = function() {
|
||||
try {
|
||||
fs.unlinkSync(manifestFilepath);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
try {
|
||||
fs.unlinkSync(expectedFilepath);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
build,
|
||||
watch,
|
||||
clean
|
||||
};
|
||||
22
scripts/m3u8.js
Normal file
22
scripts/m3u8.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
'use strict';
|
||||
const m3u8 = require('./export-m3u8s.js');
|
||||
|
||||
const args = require('minimist')(process.argv.slice(2), {
|
||||
boolean: ['watch', 'clean', 'build'],
|
||||
default: {
|
||||
build: true
|
||||
},
|
||||
alias: {
|
||||
b: 'build',
|
||||
c: 'clean',
|
||||
w: 'watch'
|
||||
}
|
||||
});
|
||||
|
||||
if (args.w) {
|
||||
m3u8.watch();
|
||||
} else if (args.c) {
|
||||
m3u8.clean();
|
||||
} else if (args.b) {
|
||||
m3u8.build();
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
const generate = require('videojs-generate-rollup-config');
|
||||
const replace = require('@rollup/plugin-replace');
|
||||
const dataFiles = require('rollup-plugin-data-files');
|
||||
|
||||
// see https://github.com/videojs/videojs-generate-rollup-config
|
||||
// for options
|
||||
|
|
@ -9,29 +7,6 @@ const options = {
|
|||
externals(defaults) {
|
||||
defaults.module.push('@videojs/vhs-utils');
|
||||
|
||||
return defaults;
|
||||
},
|
||||
primedPlugins(defaults) {
|
||||
// when using "require" rather than import
|
||||
// require cjs module
|
||||
defaults.replace = replace({
|
||||
// single quote replace
|
||||
"require('@videojs/vhs-utils/es": "require('@videojs/vhs-utils/cjs",
|
||||
// double quote replace
|
||||
'require("@videojs/vhs-utils/es': 'require("@videojs/vhs-utils/cjs'
|
||||
});
|
||||
|
||||
defaults.dataFiles = dataFiles({
|
||||
expecteds: {include: 'test/fixtures/integration/*.js', transform: 'js', extensions: false},
|
||||
manifests: {include: 'test/fixtures/integration/*.m3u8', transform: 'string', extensions: false}
|
||||
});
|
||||
|
||||
return defaults;
|
||||
},
|
||||
plugins(defaults) {
|
||||
defaults.module.unshift('replace');
|
||||
defaults.test.unshift('dataFiles');
|
||||
|
||||
return defaults;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @file m3u8/line-stream.js
|
||||
*/
|
||||
import Stream from '@videojs/vhs-utils/es/stream.js';
|
||||
import Stream from '@videojs/vhs-utils/dist/stream.js';
|
||||
|
||||
/**
|
||||
* A stream that buffers string input and generates a `data` event for each
|
||||
|
|
|
|||
|
|
@ -1,26 +1,7 @@
|
|||
/**
|
||||
* @file m3u8/parse-stream.js
|
||||
*/
|
||||
import Stream from '@videojs/vhs-utils/es/stream.js';
|
||||
|
||||
const TAB = String.fromCharCode(0x09);
|
||||
|
||||
const parseByterange = function(byterangeString) {
|
||||
// optionally match and capture 0+ digits before `@`
|
||||
// optionally match and capture 0+ digits after `@`
|
||||
const match = /([0-9.]*)?@?([0-9.]*)?/.exec(byterangeString || '');
|
||||
const result = {};
|
||||
|
||||
if (match[1]) {
|
||||
result.length = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
if (match[2]) {
|
||||
result.offset = parseInt(match[2], 10);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
import Stream from '@videojs/vhs-utils/dist/stream.js';
|
||||
|
||||
/**
|
||||
* "forgiving" attribute list psuedo-grammar:
|
||||
|
|
@ -43,14 +24,9 @@ const attributeSeparator = function() {
|
|||
* @param {string} attributes the attribute line to parse
|
||||
*/
|
||||
const parseAttributes = function(attributes) {
|
||||
const result = {};
|
||||
|
||||
if (!attributes) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// split the string using attributes as the separator
|
||||
const attrs = attributes.split(attributeSeparator());
|
||||
const result = {};
|
||||
let i = attrs.length;
|
||||
let attr;
|
||||
|
||||
|
|
@ -71,29 +47,6 @@ const parseAttributes = function(attributes) {
|
|||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a string into a resolution object
|
||||
*
|
||||
* @param {string} resolution a string such as 3840x2160
|
||||
*
|
||||
* @return {Object} An object representing the resolution
|
||||
*
|
||||
*/
|
||||
const parseResolution = (resolution) => {
|
||||
const split = resolution.split('x');
|
||||
const result = {};
|
||||
|
||||
if (split[0]) {
|
||||
result.width = parseInt(split[0], 10);
|
||||
}
|
||||
|
||||
if (split[1]) {
|
||||
result.height = parseInt(split[1], 10);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* A line-level M3U8 parser event stream. It expects to receive input one
|
||||
* line at a time and performs a context-free parse of its contents. A stream
|
||||
|
|
@ -192,7 +145,7 @@ export default class ParseStream extends Stream {
|
|||
});
|
||||
return;
|
||||
}
|
||||
match = (/^#EXTINF:([0-9\.]*)?,?(.*)?$/).exec(newLine);
|
||||
match = (/^#EXTINF:?([0-9\.]*)?,?(.*)?$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -207,7 +160,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-TARGETDURATION:([0-9.]*)?/).exec(newLine);
|
||||
match = (/^#EXT-X-TARGETDURATION:?([0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -219,7 +172,19 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-VERSION:([0-9.]*)?/).exec(newLine);
|
||||
match = (/^#ZEN-TOTAL-DURATION:?([0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'totalduration'
|
||||
};
|
||||
if (match[1]) {
|
||||
event.duration = parseInt(match[1], 10);
|
||||
}
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -231,7 +196,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine);
|
||||
match = (/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -243,7 +208,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine);
|
||||
match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -255,7 +220,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-PLAYLIST-TYPE:(.*)?$/).exec(newLine);
|
||||
match = (/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -267,16 +232,22 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-BYTERANGE:(.*)?$/).exec(newLine);
|
||||
match = (/^#EXT-X-BYTERANGE:?([0-9.]*)?@?([0-9.]*)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = Object.assign(parseByterange(match[1]), {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'byterange'
|
||||
});
|
||||
};
|
||||
if (match[1]) {
|
||||
event.length = parseInt(match[1], 10);
|
||||
}
|
||||
if (match[2]) {
|
||||
event.offset = parseInt(match[2], 10);
|
||||
}
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-ALLOW-CACHE:(YES|NO)?/).exec(newLine);
|
||||
match = (/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -288,7 +259,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-MAP:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-MAP:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -302,14 +273,22 @@ export default class ParseStream extends Stream {
|
|||
event.uri = attributes.URI;
|
||||
}
|
||||
if (attributes.BYTERANGE) {
|
||||
event.byterange = parseByterange(attributes.BYTERANGE);
|
||||
const [length, offset] = attributes.BYTERANGE.split('@');
|
||||
|
||||
event.byterange = {};
|
||||
if (length) {
|
||||
event.byterange.length = parseInt(length, 10);
|
||||
}
|
||||
if (offset) {
|
||||
event.byterange.offset = parseInt(offset, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-STREAM-INF:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-STREAM-INF:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -319,14 +298,20 @@ export default class ParseStream extends Stream {
|
|||
event.attributes = parseAttributes(match[1]);
|
||||
|
||||
if (event.attributes.RESOLUTION) {
|
||||
event.attributes.RESOLUTION = parseResolution(event.attributes.RESOLUTION);
|
||||
const split = event.attributes.RESOLUTION.split('x');
|
||||
const resolution = {};
|
||||
|
||||
if (split[0]) {
|
||||
resolution.width = parseInt(split[0], 10);
|
||||
}
|
||||
if (split[1]) {
|
||||
resolution.height = parseInt(split[1], 10);
|
||||
}
|
||||
event.attributes.RESOLUTION = resolution;
|
||||
}
|
||||
if (event.attributes.BANDWIDTH) {
|
||||
event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
|
||||
}
|
||||
if (event.attributes['FRAME-RATE']) {
|
||||
event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
|
||||
}
|
||||
if (event.attributes['PROGRAM-ID']) {
|
||||
event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
|
||||
}
|
||||
|
|
@ -334,7 +319,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-MEDIA:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-MEDIA:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -362,7 +347,7 @@ export default class ParseStream extends Stream {
|
|||
});
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-PROGRAM-DATE-TIME:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -375,7 +360,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-KEY:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-KEY:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -400,7 +385,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-START:(.*)$/).exec(newLine);
|
||||
match = (/^#EXT-X-START:?(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -415,7 +400,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-CUE-OUT-CONT:(.*)?$/).exec(newLine);
|
||||
match = (/^#EXT-X-CUE-OUT-CONT:?(.*)?$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -429,7 +414,7 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-CUE-OUT:(.*)?$/).exec(newLine);
|
||||
match = (/^#EXT-X-CUE-OUT:?(.*)?$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
|
|
@ -457,252 +442,6 @@ export default class ParseStream extends Stream {
|
|||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-SKIP:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'skip'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
|
||||
if (event.attributes.hasOwnProperty('SKIPPED-SEGMENTS')) {
|
||||
event.attributes['SKIPPED-SEGMENTS'] = parseInt(event.attributes['SKIPPED-SEGMENTS'], 10);
|
||||
}
|
||||
|
||||
if (event.attributes.hasOwnProperty('RECENTLY-REMOVED-DATERANGES')) {
|
||||
event.attributes['RECENTLY-REMOVED-DATERANGES'] =
|
||||
event.attributes['RECENTLY-REMOVED-DATERANGES'].split(TAB);
|
||||
}
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-PART:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'part'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['DURATION'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseFloat(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
|
||||
['INDEPENDENT', 'GAP'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = (/YES/).test(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
|
||||
if (event.attributes.hasOwnProperty('BYTERANGE')) {
|
||||
event.attributes.byterange = parseByterange(event.attributes.BYTERANGE);
|
||||
}
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-SERVER-CONTROL:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'server-control'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['CAN-SKIP-UNTIL', 'PART-HOLD-BACK', 'HOLD-BACK'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseFloat(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
|
||||
['CAN-SKIP-DATERANGES', 'CAN-BLOCK-RELOAD'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = (/YES/).test(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-PART-INF:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'part-inf'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['PART-TARGET'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseFloat(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
|
||||
match = (/^#EXT-X-PRELOAD-HINT:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'preload-hint'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['BYTERANGE-START', 'BYTERANGE-LENGTH'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseInt(event.attributes[key], 10);
|
||||
|
||||
const subkey = key === 'BYTERANGE-LENGTH' ? 'length' : 'offset';
|
||||
|
||||
event.attributes.byterange = event.attributes.byterange || {};
|
||||
event.attributes.byterange[subkey] = event.attributes[key];
|
||||
// only keep the parsed byterange object.
|
||||
delete event.attributes[key];
|
||||
}
|
||||
});
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-RENDITION-REPORT:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'rendition-report'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['LAST-MSN', 'LAST-PART'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseInt(event.attributes[key], 10);
|
||||
}
|
||||
});
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-DATERANGE:(.*)$/).exec(newLine);
|
||||
if (match && match[1]) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'daterange'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
['ID', 'CLASS'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = String(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
['START-DATE', 'END-DATE'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = new Date(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
['DURATION', 'PLANNED-DURATION'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = parseFloat(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
['END-ON-NEXT'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = (/YES/i).test(event.attributes[key]);
|
||||
}
|
||||
});
|
||||
['SCTE35-CMD', ' SCTE35-OUT', 'SCTE35-IN'].forEach(function(key) {
|
||||
if (event.attributes.hasOwnProperty(key)) {
|
||||
event.attributes[key] = event.attributes[key].toString(16);
|
||||
}
|
||||
});
|
||||
|
||||
const clientAttributePattern = /^X-([A-Z]+-)+[A-Z]+$/;
|
||||
|
||||
for (const key in event.attributes) {
|
||||
if (!clientAttributePattern.test(key)) {
|
||||
continue;
|
||||
}
|
||||
const isHexaDecimal = (/[0-9A-Fa-f]{6}/g).test(event.attributes[key]);
|
||||
const isDecimalFloating = (/^\d+(\.\d+)?$/).test(event.attributes[key]);
|
||||
|
||||
event.attributes[key] = isHexaDecimal ? event.attributes[key].toString(16) : isDecimalFloating ? parseFloat(event.attributes[key]) : String(event.attributes[key]);
|
||||
|
||||
}
|
||||
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-INDEPENDENT-SEGMENTS/).exec(newLine);
|
||||
if (match) {
|
||||
this.trigger('data', {
|
||||
type: 'tag',
|
||||
tagType: 'independent-segments'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
match = (/^#EXT-X-I-FRAMES-ONLY/).exec(newLine);
|
||||
if (match) {
|
||||
this.trigger('data', {
|
||||
type: 'tag',
|
||||
tagType: 'i-frames-only'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
match = (/^#EXT-X-CONTENT-STEERING:(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'content-steering'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
this.trigger('data', event);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
match = (/^#EXT-X-I-FRAME-STREAM-INF:(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'i-frame-playlist'
|
||||
};
|
||||
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
|
||||
if (event.attributes.URI) {
|
||||
event.uri = event.attributes.URI;
|
||||
}
|
||||
|
||||
if (event.attributes.BANDWIDTH) {
|
||||
event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
|
||||
}
|
||||
|
||||
if (event.attributes.RESOLUTION) {
|
||||
event.attributes.RESOLUTION = parseResolution(event.attributes.RESOLUTION);
|
||||
}
|
||||
|
||||
if (event.attributes['AVERAGE-BANDWIDTH']) {
|
||||
event.attributes['AVERAGE-BANDWIDTH'] = parseInt(event.attributes['AVERAGE-BANDWIDTH'], 10);
|
||||
}
|
||||
|
||||
if (event.attributes['FRAME-RATE']) {
|
||||
event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
|
||||
}
|
||||
|
||||
this.trigger('data', event);
|
||||
|
||||
return;
|
||||
}
|
||||
match = (/^#EXT-X-DEFINE:(.*)$/).exec(newLine);
|
||||
if (match) {
|
||||
event = {
|
||||
type: 'tag',
|
||||
tagType: 'define'
|
||||
};
|
||||
event.attributes = parseAttributes(match[1]);
|
||||
this.trigger('data', event);
|
||||
return;
|
||||
}
|
||||
|
||||
// unknown tag type
|
||||
this.trigger('data', {
|
||||
|
|
@ -720,8 +459,9 @@ export default class ParseStream extends Stream {
|
|||
* @param {string} options.customType the custom type to register to the output
|
||||
* @param {Function} [options.dataParser] function to parse the line into an object
|
||||
* @param {boolean} [options.segment] should tag data be attached to the segment object
|
||||
* @param {boolean} [options.multiple] does the tag appear multiple times
|
||||
*/
|
||||
addParser({expression, customType, dataParser, segment}) {
|
||||
addParser({expression, customType, dataParser, segment, multiple}) {
|
||||
if (typeof dataParser !== 'function') {
|
||||
dataParser = (line) => line;
|
||||
}
|
||||
|
|
@ -733,7 +473,8 @@ export default class ParseStream extends Stream {
|
|||
type: 'custom',
|
||||
data: dataParser(line),
|
||||
customType,
|
||||
segment
|
||||
segment,
|
||||
multiple
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
574
src/parser.js
574
src/parser.js
|
|
@ -1,74 +1,11 @@
|
|||
/**
|
||||
* @file m3u8/parser.js
|
||||
*/
|
||||
import Stream from '@videojs/vhs-utils/es/stream.js';
|
||||
import decodeB64ToUint8Array from '@videojs/vhs-utils/es/decode-b64-to-uint8-array.js';
|
||||
import Stream from '@videojs/vhs-utils/dist/stream.js';
|
||||
import decodeB64ToUint8Array from '@videojs/vhs-utils/dist/decode-b64-to-uint8-array.js';
|
||||
import LineStream from './line-stream';
|
||||
import ParseStream from './parse-stream';
|
||||
|
||||
const camelCase = (str) => str
|
||||
.toLowerCase()
|
||||
.replace(/-(\w)/g, (a) => a[1].toUpperCase());
|
||||
|
||||
const camelCaseKeys = function(attributes) {
|
||||
const result = {};
|
||||
|
||||
Object.keys(attributes).forEach(function(key) {
|
||||
result[camelCase(key)] = attributes[key];
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// set SERVER-CONTROL hold back based upon targetDuration and partTargetDuration
|
||||
// we need this helper because defaults are based upon targetDuration and
|
||||
// partTargetDuration being set, but they may not be if SERVER-CONTROL appears before
|
||||
// target durations are set.
|
||||
const setHoldBack = function(manifest) {
|
||||
const {serverControl, targetDuration, partTargetDuration} = manifest;
|
||||
|
||||
if (!serverControl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = '#EXT-X-SERVER-CONTROL';
|
||||
const hb = 'holdBack';
|
||||
const phb = 'partHoldBack';
|
||||
const minTargetDuration = targetDuration && targetDuration * 3;
|
||||
const minPartDuration = partTargetDuration && partTargetDuration * 2;
|
||||
|
||||
if (targetDuration && !serverControl.hasOwnProperty(hb)) {
|
||||
serverControl[hb] = minTargetDuration;
|
||||
this.trigger('info', {
|
||||
message: `${tag} defaulting HOLD-BACK to targetDuration * 3 (${minTargetDuration}).`
|
||||
});
|
||||
}
|
||||
|
||||
if (minTargetDuration && serverControl[hb] < minTargetDuration) {
|
||||
this.trigger('warn', {
|
||||
message: `${tag} clamping HOLD-BACK (${serverControl[hb]}) to targetDuration * 3 (${minTargetDuration})`
|
||||
});
|
||||
serverControl[hb] = minTargetDuration;
|
||||
}
|
||||
|
||||
// default no part hold back to part target duration * 3
|
||||
if (partTargetDuration && !serverControl.hasOwnProperty(phb)) {
|
||||
serverControl[phb] = partTargetDuration * 3;
|
||||
this.trigger('info', {
|
||||
message: `${tag} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${serverControl[phb]}).`
|
||||
});
|
||||
}
|
||||
|
||||
// if part hold back is too small default it to part target duration * 2
|
||||
if (partTargetDuration && serverControl[phb] < (minPartDuration)) {
|
||||
this.trigger('warn', {
|
||||
message: `${tag} clamping PART-HOLD-BACK (${serverControl[phb]}) to partTargetDuration * 2 (${minPartDuration}).`
|
||||
});
|
||||
|
||||
serverControl[phb] = minPartDuration;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A parser for M3U8 files. The current interpretation of the input is
|
||||
* exposed as a property `manifest` on parser objects. It's just two lines to
|
||||
|
|
@ -88,20 +25,14 @@ const setHoldBack = function(manifest) {
|
|||
* requires some property of the manifest object to be defaulted.
|
||||
*
|
||||
* @class Parser
|
||||
* @param {Object} [opts] Options for the constructor, needed for substitutions
|
||||
* @param {string} [opts.uri] URL to check for query params
|
||||
* @param {Object} [opts.mainDefinitions] Definitions on main playlist that can be imported
|
||||
* @extends Stream
|
||||
*/
|
||||
export default class Parser extends Stream {
|
||||
constructor(opts = {}) {
|
||||
constructor() {
|
||||
super();
|
||||
this.lineStream = new LineStream();
|
||||
this.parseStream = new ParseStream();
|
||||
this.lineStream.pipe(this.parseStream);
|
||||
this.mainDefinitions = opts.mainDefinitions || {};
|
||||
this.params = new URL(opts.uri, 'https://a.com').searchParams;
|
||||
this.lastProgramDateTime = null;
|
||||
|
||||
/* eslint-disable consistent-this */
|
||||
const self = this;
|
||||
|
|
@ -112,7 +43,6 @@ export default class Parser extends Stream {
|
|||
let currentMap;
|
||||
// if specified, the active decryption key
|
||||
let key;
|
||||
let hasParts = false;
|
||||
const noop = function() {};
|
||||
const defaultMediaGroups = {
|
||||
'AUDIO': {},
|
||||
|
|
@ -130,69 +60,22 @@ export default class Parser extends Stream {
|
|||
this.manifest = {
|
||||
allowCache: true,
|
||||
discontinuityStarts: [],
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
segments: []
|
||||
};
|
||||
// keep track of the last seen segment's byte range end, as segments are not required
|
||||
// to provide the offset, in which case it defaults to the next byte after the
|
||||
// previous segment
|
||||
let lastByterangeEnd = 0;
|
||||
// keep track of the last seen part's byte range end.
|
||||
let lastPartByterangeEnd = 0;
|
||||
const dateRangeTags = {};
|
||||
|
||||
this.on('end', () => {
|
||||
// only add preloadSegment if we don't yet have a uri for it.
|
||||
// and we actually have parts/preloadHints
|
||||
if (currentUri.uri || (!currentUri.parts && !currentUri.preloadHints)) {
|
||||
return;
|
||||
}
|
||||
if (!currentUri.map && currentMap) {
|
||||
currentUri.map = currentMap;
|
||||
}
|
||||
|
||||
if (!currentUri.key && key) {
|
||||
currentUri.key = key;
|
||||
}
|
||||
|
||||
if (!currentUri.timeline && typeof currentTimeline === 'number') {
|
||||
currentUri.timeline = currentTimeline;
|
||||
}
|
||||
|
||||
this.manifest.preloadSegment = currentUri;
|
||||
});
|
||||
|
||||
// update the manifest with the m3u8 entry from the parse stream
|
||||
this.parseStream.on('data', function(entry) {
|
||||
let mediaGroup;
|
||||
let rendition;
|
||||
|
||||
// Replace variables in uris and attributes as defined in #EXT-X-DEFINE tags
|
||||
if (self.manifest.definitions) {
|
||||
for (const def in self.manifest.definitions) {
|
||||
if (entry.uri) {
|
||||
entry.uri = entry.uri.replace(`{$${def}}`, self.manifest.definitions[def]);
|
||||
}
|
||||
if (entry.attributes) {
|
||||
for (const attr in entry.attributes) {
|
||||
if (typeof entry.attributes[attr] === 'string') {
|
||||
entry.attributes[attr] = entry.attributes[attr].replace(`{$${def}}`, self.manifest.definitions[def]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
({
|
||||
tag() {
|
||||
// switch based on the tag type
|
||||
(({
|
||||
version() {
|
||||
if (entry.version) {
|
||||
this.manifest.version = entry.version;
|
||||
}
|
||||
},
|
||||
'allow-cache'() {
|
||||
this.manifest.allowCache = entry.allowed;
|
||||
if (!('allowed' in entry)) {
|
||||
|
|
@ -245,11 +128,6 @@ export default class Parser extends Stream {
|
|||
message: 'defaulting discontinuity sequence to zero'
|
||||
});
|
||||
}
|
||||
|
||||
if (entry.title) {
|
||||
currentUri.title = entry.title;
|
||||
}
|
||||
|
||||
if (entry.duration > 0) {
|
||||
currentUri.duration = entry.duration;
|
||||
}
|
||||
|
|
@ -282,28 +160,6 @@ export default class Parser extends Stream {
|
|||
return;
|
||||
}
|
||||
|
||||
if (entry.attributes.KEYFORMAT === 'com.apple.streamingkeydelivery') {
|
||||
this.manifest.contentProtection = this.manifest.contentProtection || {};
|
||||
|
||||
// TODO: add full support for this.
|
||||
this.manifest.contentProtection['com.apple.fps.1_0'] = {
|
||||
attributes: entry.attributes
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
|
||||
this.manifest.contentProtection = this.manifest.contentProtection || {};
|
||||
|
||||
// TODO: add full support for this.
|
||||
this.manifest.contentProtection['com.microsoft.playready'] = {
|
||||
uri: entry.attributes.URI
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the content is encrypted for Widevine
|
||||
// Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
|
||||
if (entry.attributes.KEYFORMAT === widevineUuid) {
|
||||
|
|
@ -338,15 +194,16 @@ export default class Parser extends Stream {
|
|||
|
||||
// if Widevine key attributes are valid, store them as `contentProtection`
|
||||
// on the manifest to emulate Widevine tag structure in a DASH mpd
|
||||
this.manifest.contentProtection = this.manifest.contentProtection || {};
|
||||
this.manifest.contentProtection['com.widevine.alpha'] = {
|
||||
attributes: {
|
||||
schemeIdUri: entry.attributes.KEYFORMAT,
|
||||
// remove '0x' from the key id string
|
||||
keyId: entry.attributes.KEYID.substring(2)
|
||||
},
|
||||
// decode the base64-encoded PSSH box
|
||||
pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])
|
||||
this.manifest.contentProtection = {
|
||||
'com.widevine.alpha': {
|
||||
attributes: {
|
||||
schemeIdUri: entry.attributes.KEYFORMAT,
|
||||
// remove '0x' from the key id string
|
||||
keyId: entry.attributes.KEYID.substring(2)
|
||||
},
|
||||
// decode the base64-encoded PSSH box
|
||||
pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])
|
||||
}
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
|
@ -403,10 +260,6 @@ export default class Parser extends Stream {
|
|||
if (entry.byterange) {
|
||||
currentMap.byterange = entry.byterange;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
currentMap.key = key;
|
||||
}
|
||||
},
|
||||
'stream-inf'() {
|
||||
this.manifest.playlists = uris;
|
||||
|
|
@ -488,24 +341,9 @@ export default class Parser extends Stream {
|
|||
this.manifest.dateTimeString = entry.dateTimeString;
|
||||
this.manifest.dateTimeObject = entry.dateTimeObject;
|
||||
}
|
||||
|
||||
currentUri.dateTimeString = entry.dateTimeString;
|
||||
currentUri.dateTimeObject = entry.dateTimeObject;
|
||||
|
||||
const { lastProgramDateTime } = this;
|
||||
|
||||
this.lastProgramDateTime = new Date(entry.dateTimeString).getTime();
|
||||
|
||||
// We should extrapolate Program Date Time backward only during first program date time occurrence.
|
||||
// Once we have at least one program date time point, we can always extrapolate it forward using lastProgramDateTime reference.
|
||||
if (lastProgramDateTime === null) {
|
||||
// Extrapolate Program Date Time backward
|
||||
// Since it is first program date time occurrence we're assuming that
|
||||
// all this.manifest.segments have no program date time info
|
||||
this.manifest.segments.reduceRight((programDateTime, segment) => {
|
||||
segment.programDateTime = programDateTime - (segment.duration * 1000);
|
||||
return segment.programDateTime;
|
||||
}, this.lastProgramDateTime);
|
||||
}
|
||||
},
|
||||
targetduration() {
|
||||
if (!isFinite(entry.duration) || entry.duration < 0) {
|
||||
|
|
@ -515,8 +353,15 @@ export default class Parser extends Stream {
|
|||
return;
|
||||
}
|
||||
this.manifest.targetDuration = entry.duration;
|
||||
|
||||
setHoldBack.call(this, this.manifest);
|
||||
},
|
||||
totalduration() {
|
||||
if (!isFinite(entry.duration) || entry.duration < 0) {
|
||||
this.trigger('warn', {
|
||||
message: 'ignoring invalid total duration: ' + entry.duration
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.manifest.totalDuration = entry.duration;
|
||||
},
|
||||
start() {
|
||||
if (!entry.attributes || isNaN(entry.attributes['TIME-OFFSET'])) {
|
||||
|
|
@ -538,333 +383,7 @@ export default class Parser extends Stream {
|
|||
},
|
||||
'cue-in'() {
|
||||
currentUri.cueIn = entry.data;
|
||||
},
|
||||
'skip'() {
|
||||
this.manifest.skip = camelCaseKeys(entry.attributes);
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
'#EXT-X-SKIP',
|
||||
entry.attributes,
|
||||
['SKIPPED-SEGMENTS']
|
||||
);
|
||||
},
|
||||
'part'() {
|
||||
hasParts = true;
|
||||
// parts are always specifed before a segment
|
||||
const segmentIndex = this.manifest.segments.length;
|
||||
const part = camelCaseKeys(entry.attributes);
|
||||
|
||||
currentUri.parts = currentUri.parts || [];
|
||||
currentUri.parts.push(part);
|
||||
|
||||
if (part.byterange) {
|
||||
if (!part.byterange.hasOwnProperty('offset')) {
|
||||
part.byterange.offset = lastPartByterangeEnd;
|
||||
}
|
||||
lastPartByterangeEnd = part.byterange.offset + part.byterange.length;
|
||||
}
|
||||
|
||||
const partIndex = currentUri.parts.length - 1;
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
`#EXT-X-PART #${partIndex} for segment #${segmentIndex}`,
|
||||
entry.attributes,
|
||||
['URI', 'DURATION']
|
||||
);
|
||||
|
||||
if (this.manifest.renditionReports) {
|
||||
this.manifest.renditionReports.forEach((r, i) => {
|
||||
if (!r.hasOwnProperty('lastPart')) {
|
||||
this.trigger('warn', {
|
||||
message: `#EXT-X-RENDITION-REPORT #${i} lacks required attribute(s): LAST-PART`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
'server-control'() {
|
||||
const attrs = this.manifest.serverControl = camelCaseKeys(entry.attributes);
|
||||
|
||||
if (!attrs.hasOwnProperty('canBlockReload')) {
|
||||
attrs.canBlockReload = false;
|
||||
this.trigger('info', {
|
||||
message: '#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false'
|
||||
});
|
||||
}
|
||||
setHoldBack.call(this, this.manifest);
|
||||
|
||||
if (attrs.canSkipDateranges && !attrs.hasOwnProperty('canSkipUntil')) {
|
||||
this.trigger('warn', {
|
||||
message: '#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set'
|
||||
});
|
||||
}
|
||||
},
|
||||
'preload-hint'() {
|
||||
// parts are always specifed before a segment
|
||||
const segmentIndex = this.manifest.segments.length;
|
||||
const hint = camelCaseKeys(entry.attributes);
|
||||
const isPart = hint.type && hint.type === 'PART';
|
||||
|
||||
currentUri.preloadHints = currentUri.preloadHints || [];
|
||||
currentUri.preloadHints.push(hint);
|
||||
|
||||
if (hint.byterange) {
|
||||
|
||||
if (!hint.byterange.hasOwnProperty('offset')) {
|
||||
// use last part byterange end or zero if not a part.
|
||||
hint.byterange.offset = isPart ? lastPartByterangeEnd : 0;
|
||||
if (isPart) {
|
||||
lastPartByterangeEnd = hint.byterange.offset + hint.byterange.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
const index = currentUri.preloadHints.length - 1;
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
`#EXT-X-PRELOAD-HINT #${index} for segment #${segmentIndex}`,
|
||||
entry.attributes,
|
||||
['TYPE', 'URI']
|
||||
);
|
||||
|
||||
if (!hint.type) {
|
||||
return;
|
||||
}
|
||||
// search through all preload hints except for the current one for
|
||||
// a duplicate type.
|
||||
for (let i = 0; i < currentUri.preloadHints.length - 1; i++) {
|
||||
const otherHint = currentUri.preloadHints[i];
|
||||
|
||||
if (!otherHint.type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (otherHint.type === hint.type) {
|
||||
this.trigger('warn', {
|
||||
message: `#EXT-X-PRELOAD-HINT #${index} for segment #${segmentIndex} has the same TYPE ${hint.type} as preload hint #${i}`
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
'rendition-report'() {
|
||||
const report = camelCaseKeys(entry.attributes);
|
||||
|
||||
this.manifest.renditionReports = this.manifest.renditionReports || [];
|
||||
this.manifest.renditionReports.push(report);
|
||||
const index = this.manifest.renditionReports.length - 1;
|
||||
const required = ['LAST-MSN', 'URI'];
|
||||
|
||||
if (hasParts) {
|
||||
required.push('LAST-PART');
|
||||
}
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
`#EXT-X-RENDITION-REPORT #${index}`,
|
||||
entry.attributes,
|
||||
required
|
||||
);
|
||||
},
|
||||
'part-inf'() {
|
||||
this.manifest.partInf = camelCaseKeys(entry.attributes);
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
'#EXT-X-PART-INF',
|
||||
entry.attributes,
|
||||
['PART-TARGET']
|
||||
);
|
||||
if (this.manifest.partInf.partTarget) {
|
||||
this.manifest.partTargetDuration = this.manifest.partInf.partTarget;
|
||||
}
|
||||
|
||||
setHoldBack.call(this, this.manifest);
|
||||
},
|
||||
'daterange'() {
|
||||
this.manifest.dateRanges.push(camelCaseKeys(entry.attributes));
|
||||
const index = this.manifest.dateRanges.length - 1;
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
`#EXT-X-DATERANGE #${index}`,
|
||||
entry.attributes,
|
||||
['ID', 'START-DATE']
|
||||
);
|
||||
const dateRange = this.manifest.dateRanges[index];
|
||||
|
||||
if (dateRange.endDate && dateRange.startDate && new Date(dateRange.endDate) < new Date(dateRange.startDate)) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE'
|
||||
});
|
||||
}
|
||||
if (dateRange.duration && dateRange.duration < 0) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE DURATION must not be negative'
|
||||
});
|
||||
}
|
||||
if (dateRange.plannedDuration && dateRange.plannedDuration < 0) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE PLANNED-DURATION must not be negative'
|
||||
});
|
||||
}
|
||||
const endOnNextYes = !!dateRange.endOnNext;
|
||||
|
||||
if (endOnNextYes && !dateRange.class) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute'
|
||||
});
|
||||
}
|
||||
if (endOnNextYes && (dateRange.duration || dateRange.endDate)) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes'
|
||||
});
|
||||
}
|
||||
if (dateRange.duration && dateRange.endDate) {
|
||||
const startDate = dateRange.startDate;
|
||||
const newDateInSeconds = startDate.getTime() + (dateRange.duration * 1000);
|
||||
|
||||
this.manifest.dateRanges[index].endDate = new Date(newDateInSeconds);
|
||||
}
|
||||
if (!dateRangeTags[dateRange.id]) {
|
||||
dateRangeTags[dateRange.id] = dateRange;
|
||||
} else {
|
||||
for (const attribute in dateRangeTags[dateRange.id]) {
|
||||
if (!!dateRange[attribute] && JSON.stringify(dateRangeTags[dateRange.id][attribute]) !== JSON.stringify(dateRange[attribute])) {
|
||||
this.trigger('warn', {
|
||||
message: 'EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if tags with the same ID do not have conflicting attributes, merge them
|
||||
const dateRangeWithSameId = this.manifest.dateRanges.findIndex((dateRangeToFind) => dateRangeToFind.id === dateRange.id);
|
||||
|
||||
this.manifest.dateRanges[dateRangeWithSameId] = Object.assign(this.manifest.dateRanges[dateRangeWithSameId], dateRange);
|
||||
dateRangeTags[dateRange.id] = Object.assign(dateRangeTags[dateRange.id], dateRange);
|
||||
// after merging, delete the duplicate dateRange that was added last
|
||||
this.manifest.dateRanges.pop();
|
||||
}
|
||||
},
|
||||
'independent-segments'() {
|
||||
this.manifest.independentSegments = true;
|
||||
},
|
||||
'i-frames-only'() {
|
||||
this.manifest.iFramesOnly = true;
|
||||
|
||||
this.requiredCompatibilityversion(this.manifest.version, 4);
|
||||
},
|
||||
'content-steering'() {
|
||||
this.manifest.contentSteering = camelCaseKeys(entry.attributes);
|
||||
this.warnOnMissingAttributes_(
|
||||
'#EXT-X-CONTENT-STEERING',
|
||||
entry.attributes,
|
||||
['SERVER-URI']
|
||||
);
|
||||
},
|
||||
|
||||
/** @this {Parser} */
|
||||
define() {
|
||||
this.manifest.definitions = this.manifest.definitions || { };
|
||||
|
||||
const addDef = (n, v) => {
|
||||
if (n in this.manifest.definitions) {
|
||||
// An EXT-X-DEFINE tag MUST NOT specify the same Variable Name as any other
|
||||
// EXT-X-DEFINE tag in the same Playlist. Parsers that encounter duplicate
|
||||
// Variable Name declarations MUST fail to parse the Playlist.
|
||||
this.trigger('error', {
|
||||
message: `EXT-X-DEFINE: Duplicate name ${n}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.manifest.definitions[n] = v;
|
||||
};
|
||||
|
||||
if ('QUERYPARAM' in entry.attributes) {
|
||||
if ('NAME' in entry.attributes || 'IMPORT' in entry.attributes) {
|
||||
// An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a
|
||||
// QUERYPARAM attribute, but only one of the three. Otherwise, the
|
||||
// client MUST fail to parse the Playlist.
|
||||
this.trigger('error', {
|
||||
message: 'EXT-X-DEFINE: Invalid attributes'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const val = this.params.get(entry.attributes.QUERYPARAM);
|
||||
|
||||
if (!val) {
|
||||
// If the QUERYPARAM attribute value does not match any query parameter in
|
||||
// the URI or the matching parameter has no associated value, the parser
|
||||
// MUST fail to parse the Playlist. If more than one parameter matches,
|
||||
// any of the associated values MAY be used.
|
||||
this.trigger('error', {
|
||||
message: `EXT-X-DEFINE: No query param ${entry.attributes.QUERYPARAM}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
addDef(entry.attributes.QUERYPARAM, decodeURIComponent(val));
|
||||
return;
|
||||
}
|
||||
|
||||
if ('NAME' in entry.attributes) {
|
||||
if ('IMPORT' in entry.attributes) {
|
||||
// An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a
|
||||
// QUERYPARAM attribute, but only one of the three. Otherwise, the
|
||||
// client MUST fail to parse the Playlist.
|
||||
this.trigger('error', {
|
||||
message: 'EXT-X-DEFINE: Invalid attributes'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!('VALUE' in entry.attributes) || typeof entry.attributes.VALUE !== 'string') {
|
||||
// This attribute is REQUIRED if the EXT-X-DEFINE tag has a NAME attribute.
|
||||
// The quoted-string MAY be empty.
|
||||
this.trigger('error', {
|
||||
message: `EXT-X-DEFINE: No value for ${entry.attributes.NAME}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
addDef(entry.attributes.NAME, entry.attributes.VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if ('IMPORT' in entry.attributes) {
|
||||
if (!this.mainDefinitions[entry.attributes.IMPORT]) {
|
||||
// Covers two conditions, as mainDefinitions will always be empty on main
|
||||
//
|
||||
// EXT-X-DEFINE tags containing the IMPORT attribute MUST NOT occur in
|
||||
// Multivariant Playlists; they are only allowed in Media Playlists.
|
||||
//
|
||||
// If the IMPORT attribute value does not match any Variable Name in the
|
||||
// Multivariant Playlist, or if the Media Playlist loaded from a
|
||||
// Multivariant Playlist, the parser MUST fail the Playlist.
|
||||
this.trigger('error', {
|
||||
message: `EXT-X-DEFINE: No value ${entry.attributes.IMPORT} to import, or IMPORT used on main playlist`
|
||||
});
|
||||
return;
|
||||
}
|
||||
addDef(entry.attributes.IMPORT, this.mainDefinitions[entry.attributes.IMPORT]);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// An EXT-X-DEFINE tag MUST contain either a NAME, an IMPORT, or a QUERYPARAM
|
||||
// attribute, but only one of the three. Otherwise, the client MUST fail to
|
||||
// parse the Playlist.
|
||||
this.trigger('error', {
|
||||
message: 'EXT-X-DEFINE: No attribute'
|
||||
});
|
||||
},
|
||||
|
||||
'i-frame-playlist'() {
|
||||
this.manifest.iFramePlaylists.push({
|
||||
attributes: entry.attributes,
|
||||
uri: entry.uri,
|
||||
timeline: currentTimeline
|
||||
});
|
||||
|
||||
this.warnOnMissingAttributes_(
|
||||
'#EXT-X-I-FRAME-STREAM-INF',
|
||||
entry.attributes,
|
||||
['BANDWIDTH', 'URI']
|
||||
);
|
||||
}
|
||||
|
||||
})[entry.tagType] || noop).call(self);
|
||||
},
|
||||
uri() {
|
||||
|
|
@ -888,15 +407,6 @@ export default class Parser extends Stream {
|
|||
currentUri.map = currentMap;
|
||||
}
|
||||
|
||||
// reset the last byterange end as it needs to be 0 between parts
|
||||
lastPartByterangeEnd = 0;
|
||||
|
||||
// Once we have at least one program date time we can always extrapolate it forward
|
||||
if (this.lastProgramDateTime !== null) {
|
||||
currentUri.programDateTime = this.lastProgramDateTime;
|
||||
this.lastProgramDateTime += currentUri.duration * 1000;
|
||||
}
|
||||
|
||||
// prepare for the next URI
|
||||
currentUri = {};
|
||||
},
|
||||
|
|
@ -908,7 +418,11 @@ export default class Parser extends Stream {
|
|||
if (entry.segment) {
|
||||
currentUri.custom = currentUri.custom || {};
|
||||
currentUri.custom[entry.customType] = entry.data;
|
||||
// if this is manifest-level data attach to the top level manifest object
|
||||
// if this is manifest-level data attach to the top level manifest object
|
||||
} else if (entry.multiple) {
|
||||
this.manifest.custom = this.manifest.custom || {};
|
||||
this.manifest.custom[entry.customType] = this.manifest.custom[entry.customType] || [];
|
||||
this.manifest.custom[entry.customType].push(entry.data);
|
||||
} else {
|
||||
this.manifest.custom = this.manifest.custom || {};
|
||||
this.manifest.custom[entry.customType] = entry.data;
|
||||
|
|
@ -918,28 +432,6 @@ export default class Parser extends Stream {
|
|||
});
|
||||
}
|
||||
|
||||
requiredCompatibilityversion(currentVersion, targetVersion) {
|
||||
if (currentVersion < targetVersion || !currentVersion) {
|
||||
this.trigger('warn', {
|
||||
message: `manifest must be at least version ${targetVersion}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
warnOnMissingAttributes_(identifier, attributes, required) {
|
||||
const missing = [];
|
||||
|
||||
required.forEach(function(key) {
|
||||
if (!attributes.hasOwnProperty(key)) {
|
||||
missing.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
if (missing.length) {
|
||||
this.trigger('warn', {message: `${identifier} lacks required attribute(s): ${missing.join(', ')}`});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input string and update the manifest object.
|
||||
*
|
||||
|
|
@ -957,21 +449,13 @@ export default class Parser extends Stream {
|
|||
end() {
|
||||
// flush any buffered input
|
||||
this.lineStream.push('\n');
|
||||
if (this.manifest.dateRanges.length && this.lastProgramDateTime === null) {
|
||||
this.trigger('warn', {
|
||||
message: 'A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag'
|
||||
});
|
||||
}
|
||||
|
||||
this.lastProgramDateTime = null;
|
||||
this.trigger('end');
|
||||
}
|
||||
/**
|
||||
* Add an additional parser for non-standard tags
|
||||
*
|
||||
* @param {Object} options a map of options for the added parser
|
||||
* @param {RegExp} options.expression a regular expression to match the custom header
|
||||
* @param {string} options.customType the custom type to register to the output
|
||||
* @param {string} options.type the type to register to the output
|
||||
* @param {Function} [options.dataParser] function to parse the line into an object
|
||||
* @param {boolean} [options.segment] should tag data be attached to the segment object
|
||||
*/
|
||||
|
|
|
|||
33
test/fixtures/integration/absoluteUris.js
vendored
33
test/fixtures/integration/absoluteUris.js
vendored
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'http://example.com/00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'https://example.com/00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '//example.com/00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'http://example.com/00004.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
167
test/fixtures/integration/allowCache.js
vendored
167
test/fixtures/integration/allowCache.js
vendored
|
|
@ -1,167 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
dateRanges: [],
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
23
test/fixtures/integration/allowCacheInvalid.js
vendored
23
test/fixtures/integration/allowCacheInvalid.js
vendored
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
dateRanges: [],
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
58
test/fixtures/integration/alternateAudio.js
vendored
58
test/fixtures/integration/alternateAudio.js
vendored
|
|
@ -1,58 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
discontinuityStarts: [],
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaGroups: {
|
||||
// TYPE
|
||||
'AUDIO': {
|
||||
// GROUP-ID
|
||||
audio: {
|
||||
// NAME
|
||||
English: {
|
||||
language: 'eng',
|
||||
autoselect: true,
|
||||
default: true,
|
||||
uri: 'eng/prog_index.m3u8'
|
||||
},
|
||||
// NAME
|
||||
Français: {
|
||||
language: 'fre',
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: 'fre/prog_index.m3u8'
|
||||
},
|
||||
// NAME
|
||||
Espanol: {
|
||||
language: 'sp',
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: 'sp/prog_index.m3u8'
|
||||
}
|
||||
}
|
||||
},
|
||||
'VIDEO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 195023,
|
||||
'CODECS': 'avc1.42e00a,mp4a.40.2',
|
||||
'AUDIO': 'audio'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'lo/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 591680,
|
||||
'CODECS': 'avc1.42e01e,mp4a.40.2',
|
||||
'AUDIO': 'audio'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hi/prog_index.m3u8'
|
||||
}],
|
||||
segments: []
|
||||
};
|
||||
59
test/fixtures/integration/brightcove.js
vendored
59
test/fixtures/integration/brightcove.js
vendored
|
|
@ -1,59 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
iFramePlaylists: [],
|
||||
dateRanges: [],
|
||||
playlists: [
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 240000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 40000
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 440000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 1928000,
|
||||
'RESOLUTION': {
|
||||
width: 960,
|
||||
height: 540
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001'
|
||||
}
|
||||
],
|
||||
discontinuityStarts: [],
|
||||
mediaGroups: {
|
||||
'VIDEO': {},
|
||||
'AUDIO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
segments: []
|
||||
};
|
||||
163
test/fixtures/integration/byteRange.js
vendored
163
test/fixtures/integration/byteRange.js
vendored
|
|
@ -1,163 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video2.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 3
|
||||
};
|
||||
31
test/fixtures/integration/dateTime.js
vendored
31
test/fixtures/integration/dateTime.js
vendored
|
|
@ -1,31 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: false,
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
dateRanges: [],
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
dateTimeString: '2016-06-22T09:20:16.166-04:00',
|
||||
dateTimeObject: new Date('2016-06-22T09:20:16.166-04:00'),
|
||||
programDateTime: 1466601616166,
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
dateTimeString: '2016-06-22T09:20:26.166-04:00',
|
||||
dateTimeObject: new Date('2016-06-22T09:20:26.166-04:00'),
|
||||
programDateTime: 1466601626166,
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
dateTimeString: '2016-06-22T09:20:16.166-04:00',
|
||||
dateTimeObject: new Date('2016-06-22T09:20:16.166-04:00'),
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
166
test/fixtures/integration/diff-init-key.js
vendored
166
test/fixtures/integration/diff-init-key.js
vendored
|
|
@ -1,166 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 7794,
|
||||
segments: [
|
||||
{
|
||||
duration: 2.833,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/init52.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence52-A.m4s'
|
||||
},
|
||||
{
|
||||
duration: 15,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/init52.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence52-B.m4s'
|
||||
},
|
||||
{
|
||||
duration: 13.333,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/init52.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence52-C.m4s'
|
||||
},
|
||||
{
|
||||
duration: 15,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=53'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=53'
|
||||
},
|
||||
uri: 'http://media.example.com/init53-A.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence53-A.m4s'
|
||||
},
|
||||
{
|
||||
duration: 14,
|
||||
key: {
|
||||
iv: new Uint32Array([0, 0, 331, 3063767524]),
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=53'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
iv: new Uint32Array([0, 0, 331, 3063767524]),
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=53'
|
||||
},
|
||||
uri: 'http://media.example.com/init53-B.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence53-B.m4s'
|
||||
},
|
||||
{
|
||||
duration: 12,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54'
|
||||
},
|
||||
map: {
|
||||
uri: 'http://media.example.com/init54-A.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-A.m4s'
|
||||
},
|
||||
{
|
||||
duration: 13,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54'
|
||||
},
|
||||
map: {
|
||||
uri: 'http://media.example.com/init54-A.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-B.m4s'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54'
|
||||
},
|
||||
uri: 'http://media.example.com/init54-B.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-A.m4s'
|
||||
},
|
||||
{
|
||||
duration: 11,
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54'
|
||||
},
|
||||
uri: 'http://media.example.com/init54-B.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-B.m4s'
|
||||
},
|
||||
{
|
||||
duration: 4,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54-b'
|
||||
},
|
||||
map: {
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54-a'
|
||||
},
|
||||
uri: 'http://media.example.com/init54-D.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-A.m4s'
|
||||
},
|
||||
{
|
||||
duration: 12,
|
||||
map: {
|
||||
uri: 'http://media.example.com/init54-E.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence54-A.m4s'
|
||||
}
|
||||
],
|
||||
targetDuration: 15,
|
||||
version: 7
|
||||
};
|
||||
57
test/fixtures/integration/diff-init-key.m3u8
vendored
57
test/fixtures/integration/diff-init-key.m3u8
vendored
|
|
@ -1,57 +0,0 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:7
|
||||
#EXT-X-MEDIA-SEQUENCE:7794
|
||||
#EXT-X-TARGETDURATION:15
|
||||
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"
|
||||
#EXT-X-MAP:URI="http://media.example.com/init52.mp4"
|
||||
|
||||
#EXTINF:2.833,
|
||||
http://media.example.com/fileSequence52-A.m4s
|
||||
#EXTINF:15.0,
|
||||
http://media.example.com/fileSequence52-B.m4s
|
||||
#EXTINF:13.333,
|
||||
http://media.example.com/fileSequence52-C.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=53"
|
||||
#EXT-X-MAP:URI="http://media.example.com/init53-A.mp4"
|
||||
|
||||
#EXTINF:15.0,
|
||||
http://media.example.com/fileSequence53-A.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=53",IV=0x00000000000000000000014BB69D61E4
|
||||
#EXT-X-MAP:URI="http://media.example.com/init53-B.mp4"
|
||||
|
||||
#EXTINF:14.0,
|
||||
http://media.example.com/fileSequence53-B.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=NONE
|
||||
#EXT-X-MAP:URI="http://media.example.com/init54-A.mp4"
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=54"
|
||||
|
||||
#EXTINF:12.0,
|
||||
http://media.example.com/fileSequence54-A.m4s
|
||||
#EXTINF:13.0,
|
||||
http://media.example.com/fileSequence54-B.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=54"
|
||||
#EXT-X-MAP:URI="http://media.example.com/init54-B.mp4"
|
||||
#EXT-X-KEY:METHOD=NONE
|
||||
|
||||
#EXTINF:10.0,
|
||||
http://media.example.com/fileSequence54-A.m4s
|
||||
#EXTINF:11.0,
|
||||
http://media.example.com/fileSequence54-B.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=54-a"
|
||||
#EXT-X-MAP:URI="http://media.example.com/init54-D.mp4"
|
||||
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=54-b"
|
||||
|
||||
#EXTINF:4.0,
|
||||
http://media.example.com/fileSequence54-A.m4s
|
||||
|
||||
#EXT-X-KEY:METHOD=NONE
|
||||
#EXT-X-MAP:URI="http://media.example.com/init54-E.mp4"
|
||||
|
||||
#EXTINF:12.0,
|
||||
http://media.example.com/fileSequence54-A.m4s
|
||||
23
test/fixtures/integration/disallowCache.js
vendored
23
test/fixtures/integration/disallowCache.js
vendored
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: false,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
38
test/fixtures/integration/disc-sequence.js
vendored
38
test/fixtures/integration/disc-sequence.js
vendored
|
|
@ -1,38 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
discontinuitySequence: 3,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 3,
|
||||
uri: '001.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 19,
|
||||
timeline: 3,
|
||||
uri: '002.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
discontinuity: true,
|
||||
duration: 10,
|
||||
timeline: 4,
|
||||
uri: '003.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 11,
|
||||
timeline: 4,
|
||||
uri: '004.ts',
|
||||
title: '0'
|
||||
}
|
||||
],
|
||||
targetDuration: 19,
|
||||
endList: true,
|
||||
discontinuityStarts: [2],
|
||||
version: 3
|
||||
};
|
||||
70
test/fixtures/integration/discontinuity.js
vendored
70
test/fixtures/integration/discontinuity.js
vendored
|
|
@ -1,70 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
discontinuitySequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '001.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 19,
|
||||
timeline: 0,
|
||||
uri: '002.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
discontinuity: true,
|
||||
duration: 10,
|
||||
timeline: 1,
|
||||
uri: '003.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 11,
|
||||
timeline: 1,
|
||||
uri: '004.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
discontinuity: true,
|
||||
duration: 10,
|
||||
timeline: 2,
|
||||
uri: '005.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 2,
|
||||
uri: '006.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 2,
|
||||
uri: '007.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
discontinuity: true,
|
||||
duration: 10,
|
||||
timeline: 3,
|
||||
uri: '008.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 16,
|
||||
timeline: 3,
|
||||
uri: '009.ts',
|
||||
title: '0'
|
||||
}
|
||||
],
|
||||
targetDuration: 19,
|
||||
endList: true,
|
||||
discontinuityStarts: [2, 4, 7],
|
||||
version: 3
|
||||
};
|
||||
33
test/fixtures/integration/domainUris.js
vendored
33
test/fixtures/integration/domainUris.js
vendored
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/subdir/00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/00004.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
7
test/fixtures/integration/empty.js
vendored
7
test/fixtures/integration/empty.js
vendored
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
segments: []
|
||||
};
|
||||
23
test/fixtures/integration/emptyAllowCache.js
vendored
23
test/fixtures/integration/emptyAllowCache.js
vendored
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
37
test/fixtures/integration/emptyMediaSequence.js
vendored
37
test/fixtures/integration/emptyMediaSequence.js
vendored
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
42
test/fixtures/integration/emptyPlaylistType.js
vendored
42
test/fixtures/integration/emptyPlaylistType.js
vendored
|
|
@ -1,42 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
59
test/fixtures/integration/emptyTargetDuration.js
vendored
59
test/fixtures/integration/emptyTargetDuration.js
vendored
|
|
@ -1,59 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
playlists: [
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 240000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 40000
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 440000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 1928000,
|
||||
'RESOLUTION': {
|
||||
width: 960,
|
||||
height: 540
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001'
|
||||
}
|
||||
],
|
||||
discontinuityStarts: [],
|
||||
mediaGroups: {
|
||||
'VIDEO': {},
|
||||
'AUDIO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
segments: []
|
||||
};
|
||||
63
test/fixtures/integration/encrypted.js
vendored
63
test/fixtures/integration/encrypted.js
vendored
|
|
@ -1,63 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 7794,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
segments: [
|
||||
{
|
||||
duration: 2.833,
|
||||
timeline: 0,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/fileSequence52-A.ts'
|
||||
},
|
||||
{
|
||||
duration: 15,
|
||||
timeline: 0,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/fileSequence52-B.ts'
|
||||
},
|
||||
{
|
||||
duration: 13.333,
|
||||
timeline: 0,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=52'
|
||||
},
|
||||
uri: 'http://media.example.com/fileSequence52-C.ts'
|
||||
},
|
||||
{
|
||||
duration: 15,
|
||||
timeline: 0,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=53'
|
||||
},
|
||||
uri: 'http://media.example.com/fileSequence53-A.ts'
|
||||
},
|
||||
{
|
||||
duration: 14,
|
||||
timeline: 0,
|
||||
key: {
|
||||
method: 'AES-128',
|
||||
uri: 'https://priv.example.com/key.php?r=54',
|
||||
iv: new Uint32Array([0, 0, 331, 3063767524])
|
||||
},
|
||||
uri: 'http://media.example.com/fileSequence53-B.ts'
|
||||
},
|
||||
{
|
||||
duration: 15,
|
||||
timeline: 0,
|
||||
uri: 'http://media.example.com/fileSequence53-B.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 15,
|
||||
version: 3
|
||||
};
|
||||
43
test/fixtures/integration/event.js
vendored
43
test/fixtures/integration/event.js
vendored
|
|
@ -1,43 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'EVENT',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 1,
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
168
test/fixtures/integration/extinf.js
vendored
168
test/fixtures/integration/extinf.js
vendored
|
|
@ -1,168 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts',
|
||||
title: ';asljasdfii11)))00,'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 9.7,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 3
|
||||
};
|
||||
47
test/fixtures/integration/fmp4.js
vendored
47
test/fixtures/integration/fmp4.js
vendored
|
|
@ -1,47 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 1,
|
||||
playlistType: 'VOD',
|
||||
targetDuration: 6,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 5666510,
|
||||
offset: 720
|
||||
},
|
||||
duration: 6.006,
|
||||
timeline: 0,
|
||||
uri: 'main.mp4',
|
||||
map: {
|
||||
byterange: {
|
||||
length: 720,
|
||||
offset: 0
|
||||
},
|
||||
uri: 'main.mp4'
|
||||
}
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 5861577,
|
||||
offset: 5667230
|
||||
},
|
||||
duration: 6.006,
|
||||
timeline: 0,
|
||||
uri: 'main.mp4',
|
||||
map: {
|
||||
byterange: {
|
||||
length: 720,
|
||||
offset: 0
|
||||
},
|
||||
uri: 'main.mp4'
|
||||
}
|
||||
}
|
||||
],
|
||||
endList: true,
|
||||
version: 7,
|
||||
independentSegments: true
|
||||
};
|
||||
7
test/fixtures/integration/headerOnly.js
vendored
7
test/fixtures/integration/headerOnly.js
vendored
|
|
@ -1,7 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
segments: []
|
||||
};
|
||||
288
test/fixtures/integration/iFramePlaylist.js
vendored
288
test/fixtures/integration/iFramePlaylist.js
vendored
|
|
@ -1,288 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 248586,
|
||||
'BANDWIDTH': 593626,
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'RESOLUTION': { width: 1280, height: 720 },
|
||||
'URI': 'sdr_720/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'SDR'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'sdr_720/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 399790,
|
||||
'BANDWIDTH': 956552,
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'RESOLUTION': { width: 1920, height: 1080 },
|
||||
'URI': 'sdr_1080/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'SDR'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'sdr_1080/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 826971,
|
||||
'BANDWIDTH': 1941397,
|
||||
'CODECS': 'hvc1.2.4.L150.B0',
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'RESOLUTION': { width: 3840, height: 2160 },
|
||||
'URI': 'sdr_2160/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'SDR'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'sdr_2160/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 232253,
|
||||
'BANDWIDTH': 573073,
|
||||
'CODECS': 'dvh1.05.01',
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'RESOLUTION': { width: 1280, height: 720 },
|
||||
'URI': 'dolby_720/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'dolby_720/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 365337,
|
||||
'BANDWIDTH': 905037,
|
||||
'CODECS': 'dvh1.05.03',
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'RESOLUTION': { width: 1920, height: 1080 },
|
||||
'URI': 'dolby_1080/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'dolby_1080/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 739114,
|
||||
'BANDWIDTH': 1893236,
|
||||
'CODECS': 'dvh1.05.06',
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'RESOLUTION': { width: 3840, height: 2160 },
|
||||
'URI': 'dolby_2160/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'dolby_2160/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 232511,
|
||||
'BANDWIDTH': 572673,
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'RESOLUTION': { width: 1280, height: 720 },
|
||||
'URI': 'hdr10_720/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hdr10_720/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 364552,
|
||||
'BANDWIDTH': 905053,
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'RESOLUTION': { width: 1920, height: 1080 },
|
||||
'URI': 'hdr10_1080/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hdr10_1080/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 739757,
|
||||
'BANDWIDTH': 1895477,
|
||||
'CODECS': 'hvc1.2.4.L150.B0',
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'RESOLUTION': { width: 3840, height: 2160 },
|
||||
'URI': 'hdr10_2160/iframe_index.m3u8',
|
||||
'VIDEO-RANGE': 'PQ'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hdr10_2160/iframe_index.m3u8'
|
||||
}
|
||||
],
|
||||
independentSegments: true,
|
||||
mediaGroups: {
|
||||
'AUDIO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {},
|
||||
'VIDEO': {}
|
||||
},
|
||||
playlists: [
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1280,
|
||||
height: 720
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'VIDEO-RANGE': 'SDR',
|
||||
'BANDWIDTH': 3971374,
|
||||
'AVERAGE-BANDWIDTH': '2778321'
|
||||
},
|
||||
uri: 'sdr_720/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'VIDEO-RANGE': 'SDR',
|
||||
'BANDWIDTH': 10022043,
|
||||
'AVERAGE-BANDWIDTH': '6759875'
|
||||
},
|
||||
uri: 'sdr_1080/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 3840,
|
||||
height: 2160
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L150.B0',
|
||||
'VIDEO-RANGE': 'SDR',
|
||||
'BANDWIDTH': 28058971,
|
||||
'AVERAGE-BANDWIDTH': '20985770'
|
||||
},
|
||||
uri: 'sdr_2160/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1280,
|
||||
height: 720
|
||||
},
|
||||
'CODECS': 'dvh1.05.01',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 5327059,
|
||||
'AVERAGE-BANDWIDTH': '3385450'
|
||||
},
|
||||
uri: 'dolby_720/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
},
|
||||
'CODECS': 'dvh1.05.03',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 12876596,
|
||||
'AVERAGE-BANDWIDTH': '7999361'
|
||||
},
|
||||
uri: 'dolby_1080/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 3840,
|
||||
height: 2160
|
||||
},
|
||||
'CODECS': 'dvh1.05.06',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 30041698,
|
||||
'AVERAGE-BANDWIDTH': '24975091'
|
||||
},
|
||||
uri: 'dolby_2160/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'NONE',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1280,
|
||||
height: 720
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 5280654,
|
||||
'AVERAGE-BANDWIDTH': '3320040'
|
||||
},
|
||||
uri: 'hdr10_720/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-0',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L123.B0',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 12886714,
|
||||
'AVERAGE-BANDWIDTH': '7964551'
|
||||
},
|
||||
uri: 'hdr10_1080/prog_index.m3u8',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'HDCP-LEVEL': 'TYPE-1',
|
||||
'CLOSED-CAPTIONS': 'NONE',
|
||||
'FRAME-RATE': 23.976,
|
||||
'RESOLUTION': {
|
||||
width: 3840,
|
||||
height: 2160
|
||||
},
|
||||
'CODECS': 'hvc1.2.4.L150.B0',
|
||||
'VIDEO-RANGE': 'PQ',
|
||||
'BANDWIDTH': 29983769,
|
||||
'AVERAGE-BANDWIDTH': '24833402'
|
||||
},
|
||||
uri: 'hdr10_2160/prog_index.m3u8',
|
||||
timeline: 0
|
||||
}
|
||||
],
|
||||
segments: [],
|
||||
version: 7
|
||||
};
|
||||
42
test/fixtures/integration/iFramePlaylist.m3u8
vendored
42
test/fixtures/integration/iFramePlaylist.m3u8
vendored
|
|
@ -1,42 +0,0 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:7
|
||||
#EXT-X-INDEPENDENT-SEGMENTS
|
||||
|
||||
# https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices-appendixes#Example-playlist
|
||||
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=248586,BANDWIDTH=593626,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1280x720,HDCP-LEVEL=NONE,URI="sdr_720/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=399790,BANDWIDTH=956552,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1920x1080,HDCP-LEVEL=TYPE-0,URI="sdr_1080/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=826971,BANDWIDTH=1941397,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L150.B0",RESOLUTION=3840x2160,HDCP-LEVEL=TYPE-1,URI="sdr_2160/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=232253,BANDWIDTH=573073,VIDEO-RANGE=PQ,CODECS="dvh1.05.01",RESOLUTION=1280x720,HDCP-LEVEL=NONE,URI="dolby_720/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=365337,BANDWIDTH=905037,VIDEO-RANGE=PQ,CODECS="dvh1.05.03",RESOLUTION=1920x1080,HDCP-LEVEL=TYPE-0,URI="dolby_1080/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=739114,BANDWIDTH=1893236,VIDEO-RANGE=PQ,CODECS="dvh1.05.06",RESOLUTION=3840x2160,HDCP-LEVEL=TYPE-1,URI="dolby_2160/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=232511,BANDWIDTH=572673,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1280x720,HDCP-LEVEL=NONE,URI="hdr10_720/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=364552,BANDWIDTH=905053,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1920x1080,HDCP-LEVEL=TYPE-0,URI="hdr10_1080/iframe_index.m3u8"
|
||||
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=739757,BANDWIDTH=1895477,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L150.B0",RESOLUTION=3840x2160,HDCP-LEVEL=TYPE-1,URI="hdr10_2160/iframe_index.m3u8"
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=2778321,BANDWIDTH=3971374,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1280x720,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=NONE
|
||||
sdr_720/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=6759875,BANDWIDTH=10022043,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1920x1080,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-0
|
||||
sdr_1080/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=20985770,BANDWIDTH=28058971,VIDEO-RANGE=SDR,CODECS="hvc1.2.4.L150.B0",RESOLUTION=3840x2160,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-1
|
||||
sdr_2160/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=3385450,BANDWIDTH=5327059,VIDEO-RANGE=PQ,CODECS="dvh1.05.01",RESOLUTION=1280x720,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=NONE
|
||||
dolby_720/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=7999361,BANDWIDTH=12876596,VIDEO-RANGE=PQ,CODECS="dvh1.05.03",RESOLUTION=1920x1080,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-0
|
||||
dolby_1080/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=24975091,BANDWIDTH=30041698,VIDEO-RANGE=PQ,CODECS="dvh1.05.06",RESOLUTION=3840x2160,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-1
|
||||
dolby_2160/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=3320040,BANDWIDTH=5280654,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1280x720,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=NONE
|
||||
hdr10_720/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=7964551,BANDWIDTH=12886714,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L123.B0",RESOLUTION=1920x1080,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-0
|
||||
hdr10_1080/prog_index.m3u8
|
||||
|
||||
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=24833402,BANDWIDTH=29983769,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L150.B0",RESOLUTION=3840x2160,FRAME-RATE=23.976,CLOSED-CAPTIONS=NONE,HDCP-LEVEL=TYPE-1
|
||||
hdr10_2160/prog_index.m3u8
|
||||
45
test/fixtures/integration/iFramesOnly.js
vendored
45
test/fixtures/integration/iFramesOnly.js
vendored
|
|
@ -1,45 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
iFramesOnly: true,
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '001.ts'
|
||||
},
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '002.ts'
|
||||
},
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '003.ts'
|
||||
},
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '004.ts'
|
||||
},
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '005.ts'
|
||||
},
|
||||
{
|
||||
duration: 2.002,
|
||||
timeline: 0,
|
||||
uri: '006.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 3,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
19
test/fixtures/integration/iFramesOnly.m3u8
vendored
19
test/fixtures/integration/iFramesOnly.m3u8
vendored
|
|
@ -1,19 +0,0 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:4
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-TARGETDURATION:3
|
||||
#EXT-X-I-FRAMES-ONLY
|
||||
#EXTINF:2.002,
|
||||
001.ts
|
||||
#EXTINF:2.002,
|
||||
002.ts
|
||||
#EXTINF:2.002,
|
||||
003.ts
|
||||
#EXTINF:2.002,
|
||||
004.ts
|
||||
#EXTINF:2.002,
|
||||
005.ts
|
||||
#EXTINF:2.002,
|
||||
006.ts
|
||||
#EXT-X-ENDLIST
|
||||
23
test/fixtures/integration/invalidAllowCache.js
vendored
23
test/fixtures/integration/invalidAllowCache.js
vendored
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
42
test/fixtures/integration/invalidPlaylistType.js
vendored
42
test/fixtures/integration/invalidPlaylistType.js
vendored
|
|
@ -1,42 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
166
test/fixtures/integration/invalidTargetDuration.js
vendored
166
test/fixtures/integration/invalidTargetDuration.js
vendored
|
|
@ -1,166 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
65
test/fixtures/integration/liveStart30sBefore.js
vendored
65
test/fixtures/integration/liveStart30sBefore.js
vendored
|
|
@ -1,65 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '001.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 19,
|
||||
timeline: 0,
|
||||
uri: '002.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '003.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 11,
|
||||
timeline: 0,
|
||||
uri: '004.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '005.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '006.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '007.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '008.ts',
|
||||
title: '0'
|
||||
},
|
||||
{
|
||||
duration: 16,
|
||||
timeline: 0,
|
||||
uri: '009.ts',
|
||||
title: '0'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
255
test/fixtures/integration/llhls-byte-range.js
vendored
255
test/fixtures/integration/llhls-byte-range.js
vendored
|
|
@ -1,255 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
preloadSegment: {
|
||||
preloadHints: [
|
||||
{
|
||||
type: 'PART',
|
||||
uri: 'filePart273.1.mp4',
|
||||
byterange: {
|
||||
length: 2000,
|
||||
offset: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'MAP',
|
||||
uri: 'file-init.mp4',
|
||||
byterange: {
|
||||
length: 5000,
|
||||
offset: 8355216
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'FOO',
|
||||
uri: 'foo.mp4',
|
||||
byterange: {
|
||||
length: 5000,
|
||||
offset: 0
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0
|
||||
},
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video2.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.part.ts',
|
||||
byterange: {
|
||||
length: 45553,
|
||||
offset: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.part.ts',
|
||||
byterange: {
|
||||
length: 28823,
|
||||
offset: 7622329
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.part.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 7651152
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.part.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 7673596
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 45553,
|
||||
offset: 8021772
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 28823,
|
||||
offset: 8067325
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 8096148
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
version: 3
|
||||
};
|
||||
151
test/fixtures/integration/llhls-delta-byte-range.js
vendored
151
test/fixtures/integration/llhls-delta-byte-range.js
vendored
|
|
@ -1,151 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
preloadSegment: {
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 0
|
||||
}
|
||||
}
|
||||
],
|
||||
preloadHints: [
|
||||
{
|
||||
type: 'PART',
|
||||
uri: 'filePart273.1.mp4',
|
||||
byterange: {
|
||||
length: 2000,
|
||||
offset: 22444
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'MAP',
|
||||
uri: 'file-init.mp4',
|
||||
byterange: {
|
||||
length: 5000,
|
||||
offset: 8377660
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'FOO',
|
||||
uri: 'foo.mp4',
|
||||
byterange: {
|
||||
length: 5000,
|
||||
offset: 0
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0
|
||||
},
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 45553,
|
||||
offset: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 28823,
|
||||
offset: 7622329
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 7651152
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 7673596
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 45553,
|
||||
offset: 8021772
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 28823,
|
||||
offset: 8067325
|
||||
}
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'hls_450k_video.ts',
|
||||
byterange: {
|
||||
length: 22444,
|
||||
offset: 8096148
|
||||
}
|
||||
}
|
||||
],
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
skip: {
|
||||
skippedSegments: 3
|
||||
},
|
||||
targetDuration: 10,
|
||||
version: 3
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#EXTM3U
|
||||
#EXT-X-TARGETDURATION:10
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:10,
|
||||
#EXT-X-SKIP:SKIPPED-SEGMENTS=3
|
||||
#EXTINF:10,
|
||||
#EXT-X-BYTERANGE:468684@7108092
|
||||
hls_450k_video.ts
|
||||
#EXTINF:10,
|
||||
#EXT-X-BYTERANGE:444996@7576776
|
||||
hls_450k_video.ts
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=45553
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=28823@7622329
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=22444
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=22444
|
||||
#EXTINF:10,
|
||||
#EXT-X-BYTERANGE:331444@8021772
|
||||
hls_450k_video.ts
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=45553@8021772
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=28823
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=22444
|
||||
#EXTINF:1.4167,
|
||||
#EXT-X-BYTERANGE:44556@8353216
|
||||
hls_450k_video.ts
|
||||
#EXT-X-PART:DURATION=0.33334,URI="hls_450k_video.ts",BYTERANGE=22444
|
||||
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="filePart273.1.mp4",BYTERANGE-LENGTH=2000
|
||||
#EXT-X-PRELOAD-HINT:TYPE=MAP,URI="file-init.mp4",BYTERANGE-LENGTH=5000,BYTERANGE-START=8377660
|
||||
#EXT-X-PRELOAD-HINT:TYPE=FOO,URI="foo.mp4",BYTERANGE-LENGTH=5000
|
||||
223
test/fixtures/integration/llhls.js
vendored
223
test/fixtures/integration/llhls.js
vendored
|
|
@ -1,223 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateTimeObject: new Date('2019-02-14T02:13:36.106Z'),
|
||||
dateTimeString: '2019-02-14T02:13:36.106Z',
|
||||
dateRanges: [],
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 266,
|
||||
preloadSegment: {
|
||||
map: {uri: 'init.mp4'},
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart273.0.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart273.1.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart273.2.mp4'
|
||||
}
|
||||
],
|
||||
preloadHints: [
|
||||
{type: 'PART', uri: 'filePart273.3.mp4'},
|
||||
{type: 'MAP', uri: 'file-init.mp4'}
|
||||
],
|
||||
timeline: 0
|
||||
},
|
||||
renditionReports: [
|
||||
{lastMsn: 273, lastPart: 2, uri: '../1M/waitForMSN.php'},
|
||||
{lastMsn: 273, lastPart: 1, uri: '../4M/waitForMSN.php'}
|
||||
],
|
||||
partInf: {
|
||||
partTarget: 0.33334
|
||||
},
|
||||
partTargetDuration: 0.33334,
|
||||
segments: [
|
||||
{
|
||||
dateTimeObject: new Date('2019-02-14T02:13:36.106Z'),
|
||||
dateTimeString: '2019-02-14T02:13:36.106Z',
|
||||
programDateTime: 1550110416106,
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'fileSequence266.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110420106.08,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence267.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110424106.1602,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence268.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110428106.2402,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence269.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110432106.3203,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence270.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110436106.4004,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence271.mp4',
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.0.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.1.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.2.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.3.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart271.4.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.5.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.6.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.7.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart271.8.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.9.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.10.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.11.mp4'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
dateTimeObject: new Date('2019-02-14T02:14:00.106Z'),
|
||||
dateTimeString: '2019-02-14T02:14:00.106Z',
|
||||
duration: 4.00008,
|
||||
map: {
|
||||
uri: 'init.mp4'
|
||||
},
|
||||
programDateTime: 1550110440106,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence272.mp4',
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
gap: true,
|
||||
uri: 'filePart272.a.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.b.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.c.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.d.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.e.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart272.f.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.g.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.h.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.i.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.j.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.k.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.l.mp4'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
serverControl: {
|
||||
canSkipDateranges: true,
|
||||
canBlockReload: true,
|
||||
canSkipUntil: 12,
|
||||
partHoldBack: 1,
|
||||
holdBack: 12
|
||||
},
|
||||
targetDuration: 4,
|
||||
version: 6
|
||||
};
|
||||
56
test/fixtures/integration/llhls.m3u8
vendored
56
test/fixtures/integration/llhls.m3u8
vendored
|
|
@ -1,56 +0,0 @@
|
|||
#EXTM3U
|
||||
# This Playlist is a response to: GET https://example.com/2M/waitForMSN.php?_HLS_msn=273&_HLS_part=2
|
||||
#EXT-X-TARGETDURATION:4
|
||||
#EXT-X-VERSION:6
|
||||
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-DATERANGES=YES,PART-HOLD-BACK=1.0,CAN-SKIP-UNTIL=12.0,HOLD-BACK=12.0
|
||||
#EXT-X-PART-INF:PART-TARGET=0.33334
|
||||
#EXT-X-MEDIA-SEQUENCE:266
|
||||
#EXT-X-PROGRAM-DATE-TIME:2019-02-14T02:13:36.106Z
|
||||
#EXT-X-MAP:URI="init.mp4"
|
||||
#EXTINF:4.00008,
|
||||
fileSequence266.mp4
|
||||
#EXTINF:4.00008,
|
||||
fileSequence267.mp4
|
||||
#EXTINF:4.00008,
|
||||
fileSequence268.mp4
|
||||
#EXTINF:4.00008,
|
||||
fileSequence269.mp4
|
||||
#EXTINF:4.00008,
|
||||
fileSequence270.mp4
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.0.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.1.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.2.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.3.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.4.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.5.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.6.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.7.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.8.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.9.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.10.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.11.mp4"
|
||||
#EXTINF:4.00008,
|
||||
fileSequence271.mp4
|
||||
#EXT-X-PROGRAM-DATE-TIME:2019-02-14T02:14:00.106Z
|
||||
#EXT-X-PART:GAP=YES,DURATION=0.33334,URI="filePart272.a.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.b.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.c.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.d.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.e.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.f.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.g.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.h.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.i.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.j.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.k.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.l.mp4"
|
||||
#EXTINF:4.00008,
|
||||
fileSequence272.mp4
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.0.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.1.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.2.mp4"
|
||||
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="filePart273.3.mp4"
|
||||
#EXT-X-PRELOAD-HINT:TYPE=MAP,URI="file-init.mp4"
|
||||
|
||||
#EXT-X-RENDITION-REPORT:URI="../1M/waitForMSN.php",LAST-MSN=273,LAST-PART=2
|
||||
#EXT-X-RENDITION-REPORT:URI="../4M/waitForMSN.php",LAST-MSN=273,LAST-PART=1
|
||||
192
test/fixtures/integration/llhlsDelta.js
vendored
192
test/fixtures/integration/llhlsDelta.js
vendored
|
|
@ -1,192 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateTimeObject: new Date('2019-02-14T02:14:00.106Z'),
|
||||
dateTimeString: '2019-02-14T02:14:00.106Z',
|
||||
dateRanges: [],
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 266,
|
||||
preloadSegment: {
|
||||
timeline: 0,
|
||||
preloadHints: [
|
||||
{type: 'PART', uri: 'filePart273.4.mp4'},
|
||||
{type: 'MAP', uri: 'file-init.mp4'}
|
||||
],
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart273.0.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart273.1.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart273.2.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart273.3.mp4'
|
||||
}
|
||||
]
|
||||
},
|
||||
renditionReports: [
|
||||
{lastMsn: 273, lastPart: 3, uri: '../1M/waitForMSN.php'},
|
||||
{lastMsn: 273, lastPart: 3, uri: '../4M/waitForMSN.php'}
|
||||
],
|
||||
partInf: {
|
||||
partTarget: 0.33334
|
||||
},
|
||||
partTargetDuration: 0.33334,
|
||||
segments: [
|
||||
{
|
||||
duration: 4.00008,
|
||||
programDateTime: 1550110428105.7598,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence269.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
programDateTime: 1550110432105.8398,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence270.mp4'
|
||||
},
|
||||
{
|
||||
duration: 4.00008,
|
||||
programDateTime: 1550110436105.92,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence271.mp4',
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.0.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.1.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.2.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.3.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart271.4.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.5.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.6.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.7.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart271.8.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.9.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.10.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart271.11.mp4'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
dateTimeObject: new Date('2019-02-14T02:14:00.106Z'),
|
||||
dateTimeString: '2019-02-14T02:14:00.106Z',
|
||||
duration: 4.00008,
|
||||
programDateTime: 1550110440106,
|
||||
timeline: 0,
|
||||
uri: 'fileSequence272.mp4',
|
||||
parts: [
|
||||
{
|
||||
duration: 0.33334,
|
||||
gap: true,
|
||||
uri: 'filePart272.a.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.b.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.c.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.d.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.e.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
independent: true,
|
||||
uri: 'filePart272.f.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.g.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.h.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.i.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.j.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.k.mp4'
|
||||
},
|
||||
{
|
||||
duration: 0.33334,
|
||||
uri: 'filePart272.l.mp4'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
skip: {
|
||||
skippedSegments: 3,
|
||||
recentlyRemovedDateranges: [
|
||||
'foo',
|
||||
'bar'
|
||||
]
|
||||
},
|
||||
serverControl: {
|
||||
canSkipDateranges: true,
|
||||
canBlockReload: true,
|
||||
canSkipUntil: 12,
|
||||
partHoldBack: 1,
|
||||
holdBack: 12
|
||||
},
|
||||
targetDuration: 4,
|
||||
version: 9
|
||||
};
|
||||
50
test/fixtures/integration/llhlsDelta.m3u8
vendored
50
test/fixtures/integration/llhlsDelta.m3u8
vendored
|
|
@ -1,50 +0,0 @@
|
|||
#EXTM3U
|
||||
# Following the example above, this Playlist is a response to: GET https://example.com/2M/waitForMSN.php?_HLS_msn=273&_HLS_part=3 &_HLS_skip=YES
|
||||
#EXT-X-TARGETDURATION:4
|
||||
#EXT-X-VERSION:9
|
||||
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,CAN-SKIP-DATERANGES=YES,PART-HOLD-BACK=1.0,CAN-SKIP-UNTIL=12.0,HOLD-BACK=12.0
|
||||
#EXT-X-PART-INF:PART-TARGET=0.33334
|
||||
#EXT-X-MEDIA-SEQUENCE:266
|
||||
#EXT-X-SKIP:SKIPPED-SEGMENTS=3,RECENTLY-REMOVED-DATERANGES=foo bar
|
||||
#EXTINF:4.00008,
|
||||
fileSequence269.mp4
|
||||
#EXTINF:4.00008,
|
||||
fileSequence270.mp4
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.0.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.1.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.2.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.3.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.4.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.5.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.6.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.7.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.8.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.9.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.10.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart271.11.mp4"
|
||||
#EXTINF:4.00008,
|
||||
fileSequence271.mp4
|
||||
#EXT-X-PROGRAM-DATE-TIME:2019-02-14T02:14:00.106Z
|
||||
#EXT-X-PART:GAP=YES,DURATION=0.33334,URI="filePart272.a.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.b.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.c.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.d.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.e.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.f.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.g.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.h.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.i.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.j.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.k.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart272.l.mp4"
|
||||
#EXTINF:4.00008,
|
||||
fileSequence272.mp4
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.0.mp4",INDEPENDENT=YES
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.1.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.2.mp4"
|
||||
#EXT-X-PART:DURATION=0.33334,URI="filePart273.3.mp4"
|
||||
#EXT-X-PRELOAD-HINT:TYPE=PART,URI="filePart273.4.mp4"
|
||||
#EXT-X-PRELOAD-HINT:TYPE=MAP,URI="file-init.mp4"
|
||||
|
||||
#EXT-X-RENDITION-REPORT:URI="../1M/waitForMSN.php",LAST-MSN=273,LAST-PART=3
|
||||
#EXT-X-RENDITION-REPORT:URI="../4M/waitForMSN.php",LAST-MSN=273,LAST-PART=3
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00001.ts'
|
||||
}
|
||||
],
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00004.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00005.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
17
test/fixtures/integration/manifestNoExtM3u.js
vendored
17
test/fixtures/integration/manifestNoExtM3u.js
vendored
|
|
@ -1,17 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/zencoder/gogo/00001.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
553
test/fixtures/integration/master-fmp4.js
vendored
553
test/fixtures/integration/master-fmp4.js
vendored
|
|
@ -1,553 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 163198,
|
||||
'BANDWIDTH': 166942,
|
||||
'CODECS': 'avc1.64002a',
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'URI': 'v6/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v6/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 131314,
|
||||
'BANDWIDTH': 139041,
|
||||
'CODECS': 'avc1.640020',
|
||||
'RESOLUTION': {
|
||||
height: 720,
|
||||
width: 1280
|
||||
},
|
||||
'URI': 'v5/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v5/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 100233,
|
||||
'BANDWIDTH': 101724,
|
||||
'CODECS': 'avc1.640020',
|
||||
'RESOLUTION': {
|
||||
height: 540,
|
||||
width: 960
|
||||
},
|
||||
'URI': 'v4/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v4/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 81002,
|
||||
'BANDWIDTH': 84112,
|
||||
'CODECS': 'avc1.64001e',
|
||||
'RESOLUTION': {
|
||||
height: 432,
|
||||
width: 768
|
||||
},
|
||||
'URI': 'v3/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v3/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 64987,
|
||||
'BANDWIDTH': 65835,
|
||||
'CODECS': 'avc1.64001e',
|
||||
'RESOLUTION': {
|
||||
height: 360,
|
||||
width: 640
|
||||
},
|
||||
'URI': 'v2/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v2/iframe_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': 41547,
|
||||
'BANDWIDTH': 42106,
|
||||
'CODECS': 'avc1.640015',
|
||||
'RESOLUTION': {
|
||||
height: 270,
|
||||
width: 480
|
||||
},
|
||||
'URI': 'v1/iframe_index.m3u8'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v1/iframe_index.m3u8'
|
||||
}
|
||||
],
|
||||
mediaGroups: {
|
||||
'AUDIO': {
|
||||
aud1: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'a1/prog_index.m3u8'
|
||||
}
|
||||
},
|
||||
aud2: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'a2/prog_index.m3u8'
|
||||
}
|
||||
},
|
||||
aud3: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'a3/prog_index.m3u8'
|
||||
}
|
||||
}
|
||||
},
|
||||
'VIDEO': {},
|
||||
'CLOSED-CAPTIONS': {
|
||||
cc1: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
instreamId: 'CC1'
|
||||
}
|
||||
}
|
||||
},
|
||||
'SUBTITLES': {
|
||||
sub1: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 's1/eng/prog_index.m3u8',
|
||||
forced: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
'AVERAGE-BANDWIDTH': '2165224',
|
||||
'BANDWIDTH': 2215219,
|
||||
'CODECS': 'avc1.640020,mp4a.40.2',
|
||||
'RESOLUTION': {
|
||||
width: 960,
|
||||
height: 540
|
||||
},
|
||||
'FRAME-RATE': 59.940,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'AUDIO': 'aud1',
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v4/prog_index.m3u8'
|
||||
},
|
||||
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '7962844',
|
||||
'BANDWIDTH': 7976430,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,mp4a.40.2',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v8/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '6165024',
|
||||
'BANDWIDTH': 6181885,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,mp4a.40.2',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v7/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '4664459',
|
||||
'BANDWIDTH': 4682666,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,mp4a.40.2',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v6/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '3164759',
|
||||
'BANDWIDTH': 3170746,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640020,mp4a.40.2',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 720,
|
||||
width: 1280
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v5/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '1262552',
|
||||
'BANDWIDTH': 1276223,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,mp4a.40.2',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 432,
|
||||
width: 768
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v3/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '893243',
|
||||
'BANDWIDTH': 904744,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,mp4a.40.2',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 360,
|
||||
width: 640
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v2/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud1',
|
||||
'AVERAGE-BANDWIDTH': '527673',
|
||||
'BANDWIDTH': 538201,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640015,mp4a.40.2',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 270,
|
||||
width: 480
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v1/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '2390334',
|
||||
'BANDWIDTH': 2440329,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640020,ac-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 540,
|
||||
width: 960
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v4/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '8187954',
|
||||
'BANDWIDTH': 8201540,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ac-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v8/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '6390134',
|
||||
'BANDWIDTH': 6406995,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ac-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v7/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '4889569',
|
||||
'BANDWIDTH': 4907776,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ac-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v6/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '3389869',
|
||||
'BANDWIDTH': 3395856,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640020,ac-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 720,
|
||||
width: 1280
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v5/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '1487662',
|
||||
'BANDWIDTH': 1501333,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,ac-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 432,
|
||||
width: 768
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v3/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '1118353',
|
||||
'BANDWIDTH': 1129854,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,ac-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 360,
|
||||
width: 640
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v2/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud2',
|
||||
'AVERAGE-BANDWIDTH': '752783',
|
||||
'BANDWIDTH': 763311,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640015,ac-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 270,
|
||||
width: 480
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v1/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '2198334',
|
||||
'BANDWIDTH': 2248329,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640020,ec-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 540,
|
||||
width: 960
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v4/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '7995954',
|
||||
'BANDWIDTH': 8009540,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ec-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v8/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '6198134',
|
||||
'BANDWIDTH': 6214995,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ec-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v7/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '4697569',
|
||||
'BANDWIDTH': 4715776,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64002a,ec-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 1080,
|
||||
width: 1920
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v6/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '3197869',
|
||||
'BANDWIDTH': 3203856,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640020,ec-3',
|
||||
'FRAME-RATE': 59.940,
|
||||
'RESOLUTION': {
|
||||
height: 720,
|
||||
width: 1280
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v5/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '1295662',
|
||||
'BANDWIDTH': 1309333,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,ec-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 432,
|
||||
width: 768
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v3/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '926353',
|
||||
'BANDWIDTH': 937854,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.64001e,ec-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 360,
|
||||
width: 640
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v2/prog_index.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'AUDIO': 'aud3',
|
||||
'AVERAGE-BANDWIDTH': '560783',
|
||||
'BANDWIDTH': 571311,
|
||||
'CLOSED-CAPTIONS': 'cc1',
|
||||
'CODECS': 'avc1.640015,ec-3',
|
||||
'FRAME-RATE': 29.970,
|
||||
'RESOLUTION': {
|
||||
height: 270,
|
||||
width: 480
|
||||
},
|
||||
'SUBTITLES': 'sub1'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'v1/prog_index.m3u8'
|
||||
}],
|
||||
segments: [],
|
||||
version: 6,
|
||||
independentSegments: true
|
||||
};
|
||||
59
test/fixtures/integration/master.js
vendored
59
test/fixtures/integration/master.js
vendored
|
|
@ -1,59 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
playlists: [
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 240000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'media.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 40000
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'media1.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 440000,
|
||||
'RESOLUTION': {
|
||||
width: 396,
|
||||
height: 224
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'media2.m3u8'
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 1928000,
|
||||
'RESOLUTION': {
|
||||
width: 960,
|
||||
height: 540
|
||||
}
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'media3.m3u8'
|
||||
}
|
||||
],
|
||||
discontinuityStarts: [],
|
||||
mediaGroups: {
|
||||
'VIDEO': {},
|
||||
'AUDIO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
segments: []
|
||||
};
|
||||
33
test/fixtures/integration/media.js
vendored
33
test/fixtures/integration/media.js
vendored
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00004.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
37
test/fixtures/integration/mediaSequence.js
vendored
37
test/fixtures/integration/mediaSequence.js
vendored
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
21
test/fixtures/integration/missingEndlist.js
vendored
21
test/fixtures/integration/missingEndlist.js
vendored
|
|
@ -1,21 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '00002.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
29
test/fixtures/integration/missingExtinf.js
vendored
29
test/fixtures/integration/missingExtinf.js
vendored
|
|
@ -1,29 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 3
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts'
|
||||
},
|
||||
{
|
||||
duration: 8,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
91
test/fixtures/integration/multipleAudioGroups.js
vendored
91
test/fixtures/integration/multipleAudioGroups.js
vendored
|
|
@ -1,91 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaGroups: {
|
||||
'AUDIO': {
|
||||
'audio-lo': {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'englo/prog_index.m3u8'
|
||||
},
|
||||
Français: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'fre',
|
||||
uri: 'frelo/prog_index.m3u8'
|
||||
},
|
||||
Espanol: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'sp',
|
||||
uri: 'splo/prog_index.m3u8'
|
||||
}
|
||||
},
|
||||
'audio-hi': {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'eng/prog_index.m3u8'
|
||||
},
|
||||
Français: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'fre',
|
||||
uri: 'fre/prog_index.m3u8'
|
||||
},
|
||||
Espanol: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'sp',
|
||||
uri: 'sp/prog_index.m3u8'
|
||||
}
|
||||
}
|
||||
},
|
||||
'VIDEO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 195023,
|
||||
'CODECS': 'mp4a.40.5',
|
||||
'AUDIO': 'audio-lo'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'lo/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 260000,
|
||||
'CODECS': 'avc1.42e01e,mp4a.40.2',
|
||||
'AUDIO': 'audio-lo'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'lo2/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 591680,
|
||||
'CODECS': 'mp4a.40.2, avc1.64001e',
|
||||
'AUDIO': 'audio-hi'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hi/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 650000,
|
||||
'CODECS': 'avc1.42e01e,mp4a.40.2',
|
||||
'AUDIO': 'audio-hi'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hi2/prog_index.m3u8'
|
||||
}],
|
||||
segments: []
|
||||
};
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
discontinuityStarts: [],
|
||||
iFramePlaylists: [],
|
||||
mediaGroups: {
|
||||
'AUDIO': {
|
||||
'audio-lo': {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng'
|
||||
},
|
||||
Français: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'fre',
|
||||
uri: 'frelo/prog_index.m3u8'
|
||||
},
|
||||
Espanol: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'sp',
|
||||
uri: 'splo/prog_index.m3u8'
|
||||
}
|
||||
},
|
||||
'audio-hi': {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'eng/prog_index.m3u8'
|
||||
},
|
||||
Français: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'fre',
|
||||
uri: 'fre/prog_index.m3u8'
|
||||
},
|
||||
Espanol: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
language: 'sp',
|
||||
uri: 'sp/prog_index.m3u8'
|
||||
}
|
||||
}
|
||||
},
|
||||
'VIDEO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 195023,
|
||||
'CODECS': 'mp4a.40.5',
|
||||
'AUDIO': 'audio-lo'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'lo/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 260000,
|
||||
'CODECS': 'avc1.42e01e,mp4a.40.2',
|
||||
'AUDIO': 'audio-lo'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'lo2/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 591680,
|
||||
'CODECS': 'mp4a.40.2, avc1.64001e',
|
||||
'AUDIO': 'audio-hi'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hi/prog_index.m3u8'
|
||||
}, {
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 650000,
|
||||
'CODECS': 'avc1.42e01e,mp4a.40.2',
|
||||
'AUDIO': 'audio-hi'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'hi2/prog_index.m3u8'
|
||||
}],
|
||||
segments: []
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
targetDuration: 10,
|
||||
segments: [
|
||||
{
|
||||
uri: '001.ts',
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
uri: '002.ts',
|
||||
duration: 9,
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
uri: '003.ts',
|
||||
duration: 7,
|
||||
timeline: 0
|
||||
},
|
||||
{
|
||||
uri: '004.ts',
|
||||
duration: 10,
|
||||
timeline: 0
|
||||
}
|
||||
],
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: -11,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
167
test/fixtures/integration/playlist.js
vendored
167
test/fixtures/integration/playlist.js
vendored
|
|
@ -1,167 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
byterange: {
|
||||
length: 522828,
|
||||
offset: 0
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 587500,
|
||||
offset: 522828
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 713084,
|
||||
offset: 1110328
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 476580,
|
||||
offset: 1823412
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 535612,
|
||||
offset: 2299992
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 207176,
|
||||
offset: 2835604
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 455900,
|
||||
offset: 3042780
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 657248,
|
||||
offset: 3498680
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 571708,
|
||||
offset: 4155928
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 485040,
|
||||
offset: 4727636
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 709136,
|
||||
offset: 5212676
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 730004,
|
||||
offset: 5921812
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 456276,
|
||||
offset: 6651816
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 468684,
|
||||
offset: 7108092
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 444996,
|
||||
offset: 7576776
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 331444,
|
||||
offset: 8021772
|
||||
},
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
},
|
||||
{
|
||||
byterange: {
|
||||
length: 44556,
|
||||
offset: 8353216
|
||||
},
|
||||
duration: 1.4167,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
version: 4
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 17,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
38
test/fixtures/integration/start.js
vendored
38
test/fixtures/integration/start.js
vendored
|
|
@ -1,38 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'media-00004.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: [],
|
||||
start: {
|
||||
timeOffset: 10.3,
|
||||
precise: false
|
||||
},
|
||||
version: 3
|
||||
};
|
||||
26
test/fixtures/integration/streamInfInvalid.js
vendored
26
test/fixtures/integration/streamInfInvalid.js
vendored
|
|
@ -1,26 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
playlists: [
|
||||
{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'media.m3u8'
|
||||
},
|
||||
{
|
||||
timeline: 0,
|
||||
uri: 'media1.m3u8'
|
||||
}
|
||||
],
|
||||
discontinuityStarts: [],
|
||||
mediaGroups: {
|
||||
'VIDEO': {},
|
||||
'AUDIO': {},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
},
|
||||
segments: []
|
||||
};
|
||||
37
test/fixtures/integration/twoMediaSequences.js
vendored
37
test/fixtures/integration/twoMediaSequences.js
vendored
|
|
@ -1,37 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 11,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 6.64,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.08,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 6.6,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts',
|
||||
title: '{}'
|
||||
},
|
||||
{
|
||||
duration: 5,
|
||||
timeline: 0,
|
||||
uri: '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts',
|
||||
title: '{}'
|
||||
}
|
||||
],
|
||||
targetDuration: 8,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
18
test/fixtures/integration/versionInvalid.js
vendored
18
test/fixtures/integration/versionInvalid.js
vendored
|
|
@ -1,18 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'hls_450k_video.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
33
test/fixtures/integration/whiteSpace.js
vendored
33
test/fixtures/integration/whiteSpace.js
vendored
|
|
@ -1,33 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaSequence: 0,
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'http://example.com/00001.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'https://example.com/00002.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: '//example.com/00003.ts'
|
||||
},
|
||||
{
|
||||
duration: 10,
|
||||
timeline: 0,
|
||||
uri: 'http://example.com/00004.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
18
test/fixtures/integration/zeroDuration.js
vendored
18
test/fixtures/integration/zeroDuration.js
vendored
|
|
@ -1,18 +0,0 @@
|
|||
module.exports = {
|
||||
allowCache: true,
|
||||
mediaSequence: 0,
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
playlistType: 'VOD',
|
||||
segments: [
|
||||
{
|
||||
duration: 0.01,
|
||||
timeline: 0,
|
||||
uri: 'http://example.com/00001.ts'
|
||||
}
|
||||
],
|
||||
targetDuration: 10,
|
||||
endList: true,
|
||||
discontinuitySequence: 0,
|
||||
discontinuityStarts: []
|
||||
};
|
||||
31
test/fixtures/m3u8/absoluteUris.json
vendored
Normal file
31
test/fixtures/m3u8/absoluteUris.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "http://example.com/00001.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "https://example.com/00002.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "//example.com/00003.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "http://example.com/00004.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
|
|
@ -9,4 +9,5 @@ https://example.com/00002.ts
|
|||
//example.com/00003.ts
|
||||
#EXTINF:10,
|
||||
http://example.com/00004.ts
|
||||
#ZEN-TOTAL-DURATION:57.9911
|
||||
#EXT-X-ENDLIST
|
||||
164
test/fixtures/m3u8/allowCache.json
vendored
Normal file
164
test/fixtures/m3u8/allowCache.json
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"byterange": {
|
||||
"length": 522828,
|
||||
"offset": 0
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 587500,
|
||||
"offset": 522828
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 713084,
|
||||
"offset": 1110328
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 476580,
|
||||
"offset": 1823412
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 535612,
|
||||
"offset": 2299992
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 207176,
|
||||
"offset": 2835604
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 455900,
|
||||
"offset": 3042780
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 657248,
|
||||
"offset": 3498680
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 571708,
|
||||
"offset": 4155928
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 485040,
|
||||
"offset": 4727636
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 709136,
|
||||
"offset": 5212676
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 730004,
|
||||
"offset": 5921812
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 456276,
|
||||
"offset": 6651816
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 468684,
|
||||
"offset": 7108092
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 444996,
|
||||
"offset": 7576776
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 331444,
|
||||
"offset": 8021772
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 44556,
|
||||
"offset": 8353216
|
||||
},
|
||||
"duration": 1.4167,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
20
test/fixtures/m3u8/allowCacheInvalid.json
vendored
Normal file
20
test/fixtures/m3u8/allowCacheInvalid.json
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"byterange": {
|
||||
"length": 522828,
|
||||
"offset": 0
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
56
test/fixtures/m3u8/alternateAudio.json
vendored
Normal file
56
test/fixtures/m3u8/alternateAudio.json
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
allowCache: true,
|
||||
discontinuityStarts: [],
|
||||
mediaGroups: {
|
||||
// TYPE
|
||||
AUDIO: {
|
||||
// GROUP-ID
|
||||
"audio": {
|
||||
// NAME
|
||||
"English": {
|
||||
language: 'eng',
|
||||
autoselect: true,
|
||||
default: true,
|
||||
uri: "eng/prog_index.m3u8"
|
||||
},
|
||||
// NAME
|
||||
"Français": {
|
||||
language: "fre",
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: "fre/prog_index.m3u8"
|
||||
},
|
||||
// NAME
|
||||
"Espanol": {
|
||||
language: "sp",
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: "sp/prog_index.m3u8"
|
||||
}
|
||||
}
|
||||
},
|
||||
VIDEO: {},
|
||||
"CLOSED-CAPTIONS": {},
|
||||
SUBTITLES: {}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
"PROGRAM-ID": 1,
|
||||
BANDWIDTH: 195023,
|
||||
CODECS: "avc1.42e00a,mp4a.40.2",
|
||||
AUDIO: 'audio'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: "lo/prog_index.m3u8"
|
||||
}, {
|
||||
attributes: {
|
||||
"PROGRAM-ID": 1,
|
||||
BANDWIDTH: 591680,
|
||||
CODECS: "avc1.42e01e,mp4a.40.2",
|
||||
AUDIO: 'audio'
|
||||
},
|
||||
timeline: 0,
|
||||
uri: "hi/prog_index.m3u8"
|
||||
}],
|
||||
segments: []
|
||||
}
|
||||
|
|
@ -1,21 +1,19 @@
|
|||
module.exports = {
|
||||
{
|
||||
allowCache: true,
|
||||
discontinuityStarts: [],
|
||||
dateRanges: [],
|
||||
iFramePlaylists: [],
|
||||
mediaGroups: {
|
||||
'AUDIO': {
|
||||
AUDIO: {
|
||||
aac: {
|
||||
English: {
|
||||
autoselect: true,
|
||||
default: true,
|
||||
language: 'eng',
|
||||
uri: 'eng/prog_index.m3u8'
|
||||
language: "eng",
|
||||
uri: "eng/prog_index.m3u8"
|
||||
}
|
||||
}
|
||||
},
|
||||
'VIDEO': {
|
||||
'500kbs': {
|
||||
VIDEO: {
|
||||
"500kbs": {
|
||||
Angle1: {
|
||||
autoselect: true,
|
||||
default: true
|
||||
|
|
@ -23,28 +21,28 @@ module.exports = {
|
|||
Angle2: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: 'Angle2/500kbs/prog_index.m3u8'
|
||||
uri: "Angle2/500kbs/prog_index.m3u8"
|
||||
},
|
||||
Angle3: {
|
||||
autoselect: true,
|
||||
default: false,
|
||||
uri: 'Angle3/500kbs/prog_index.m3u8'
|
||||
uri: "Angle3/500kbs/prog_index.m3u8"
|
||||
}
|
||||
}
|
||||
},
|
||||
'CLOSED-CAPTIONS': {},
|
||||
'SUBTITLES': {}
|
||||
"CLOSED-CAPTIONS": {},
|
||||
SUBTITLES: {}
|
||||
},
|
||||
playlists: [{
|
||||
attributes: {
|
||||
'PROGRAM-ID': 1,
|
||||
'BANDWIDTH': 754857,
|
||||
'CODECS': 'mp4a.40.2,avc1.4d401e',
|
||||
'AUDIO': 'aac',
|
||||
'VIDEO': '500kbs'
|
||||
"PROGRAM-ID": 1,
|
||||
BANDWIDTH: 754857,
|
||||
CODECS: "mp4a.40.2,avc1.4d401e",
|
||||
AUDIO: "aac",
|
||||
VIDEO: "500kbs"
|
||||
},
|
||||
timeline: 0,
|
||||
uri: 'Angle1/500kbs/prog_index.m3u8'
|
||||
uri: "Angle1/500kbs/prog_index.m3u8"
|
||||
}],
|
||||
segments: []
|
||||
};
|
||||
}
|
||||
57
test/fixtures/m3u8/brightcove.json
vendored
Normal file
57
test/fixtures/m3u8/brightcove.json
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"playlists": [
|
||||
{
|
||||
"attributes": {
|
||||
"PROGRAM-ID": 1,
|
||||
"BANDWIDTH": 240000,
|
||||
"RESOLUTION": {
|
||||
"width": 396,
|
||||
"height": 224
|
||||
}
|
||||
},
|
||||
"timeline": 0,
|
||||
"uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001"
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"PROGRAM-ID": 1,
|
||||
"BANDWIDTH": 40000
|
||||
},
|
||||
"timeline": 0,
|
||||
"uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001"
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"PROGRAM-ID": 1,
|
||||
"BANDWIDTH": 440000,
|
||||
"RESOLUTION": {
|
||||
"width": 396,
|
||||
"height": 224
|
||||
}
|
||||
},
|
||||
"timeline": 0,
|
||||
"uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001"
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
"PROGRAM-ID": 1,
|
||||
"BANDWIDTH": 1928000,
|
||||
"RESOLUTION": {
|
||||
"width": 960,
|
||||
"height": 540
|
||||
}
|
||||
},
|
||||
"timeline": 0,
|
||||
"uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001"
|
||||
}
|
||||
],
|
||||
"discontinuityStarts": [],
|
||||
"mediaGroups": {
|
||||
"VIDEO": {},
|
||||
"AUDIO": {},
|
||||
"CLOSED-CAPTIONS": {},
|
||||
"SUBTITLES": {}
|
||||
},
|
||||
"segments": []
|
||||
}
|
||||
160
test/fixtures/m3u8/byteRange.json
vendored
Normal file
160
test/fixtures/m3u8/byteRange.json
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 587500,
|
||||
"offset": 522828
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 713084,
|
||||
"offset": 1110328
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video2.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 476580,
|
||||
"offset": 1823412
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 535612,
|
||||
"offset": 2299992
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 207176,
|
||||
"offset": 2835604
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 455900,
|
||||
"offset": 3042780
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 657248,
|
||||
"offset": 3498680
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 571708,
|
||||
"offset": 4155928
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 485040,
|
||||
"offset": 4727636
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 709136,
|
||||
"offset": 5212676
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 730004,
|
||||
"offset": 5921812
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 456276,
|
||||
"offset": 6651816
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 468684,
|
||||
"offset": 7108092
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 444996,
|
||||
"offset": 7576776
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 331444,
|
||||
"offset": 8021772
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"byterange": {
|
||||
"length": 44556,
|
||||
"offset": 8353216
|
||||
},
|
||||
"duration": 1.4167,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
27
test/fixtures/m3u8/dateTime.json
vendored
Normal file
27
test/fixtures/m3u8/dateTime.json
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"allowCache": false,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"dateTimeString": "2016-06-22T09:20:16.166-04:00",
|
||||
"dateTimeObject": new Date("2016-06-22T09:20:16.166-04:00"),
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
},
|
||||
{
|
||||
"dateTimeString": "2016-06-22T09:20:26.166-04:00",
|
||||
"dateTimeObject": new Date("2016-06-22T09:20:26.166-04:00"),
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"dateTimeString": "2016-06-22T09:20:16.166-04:00",
|
||||
"dateTimeObject": new Date("2016-06-22T09:20:16.166-04:00"),
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
20
test/fixtures/m3u8/disallowCache.json
vendored
Normal file
20
test/fixtures/m3u8/disallowCache.json
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"allowCache": false,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"byterange": {
|
||||
"length": 522828,
|
||||
"offset": 0
|
||||
},
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "hls_450k_video.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
31
test/fixtures/m3u8/disc-sequence.json
vendored
Normal file
31
test/fixtures/m3u8/disc-sequence.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"discontinuitySequence": 3,
|
||||
"segments": [
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 3,
|
||||
"uri": "001.ts"
|
||||
},
|
||||
{
|
||||
"duration": 19,
|
||||
"timeline": 3,
|
||||
"uri": "002.ts"
|
||||
},
|
||||
{
|
||||
"discontinuity": true,
|
||||
"duration": 10,
|
||||
"timeline": 4,
|
||||
"uri": "003.ts"
|
||||
},
|
||||
{
|
||||
"duration": 11,
|
||||
"timeline": 4,
|
||||
"uri": "004.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 19,
|
||||
"endList": true,
|
||||
"discontinuityStarts": [2]
|
||||
}
|
||||
58
test/fixtures/m3u8/discontinuity.json
vendored
Normal file
58
test/fixtures/m3u8/discontinuity.json
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"discontinuitySequence": 0,
|
||||
"segments": [
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "001.ts"
|
||||
},
|
||||
{
|
||||
"duration": 19,
|
||||
"timeline": 0,
|
||||
"uri": "002.ts"
|
||||
},
|
||||
{
|
||||
"discontinuity": true,
|
||||
"duration": 10,
|
||||
"timeline": 1,
|
||||
"uri": "003.ts"
|
||||
},
|
||||
{
|
||||
"duration": 11,
|
||||
"timeline": 1,
|
||||
"uri": "004.ts"
|
||||
},
|
||||
{
|
||||
"discontinuity": true,
|
||||
"duration": 10,
|
||||
"timeline": 2,
|
||||
"uri": "005.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 2,
|
||||
"uri": "006.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 2,
|
||||
"uri": "007.ts"
|
||||
},
|
||||
{
|
||||
"discontinuity": true,
|
||||
"duration": 10,
|
||||
"timeline": 3,
|
||||
"uri": "008.ts"
|
||||
},
|
||||
{
|
||||
"duration": 16,
|
||||
"timeline": 3,
|
||||
"uri": "009.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 19,
|
||||
"endList": true,
|
||||
"discontinuityStarts": [2, 4, 7]
|
||||
}
|
||||
31
test/fixtures/m3u8/domainUris.json
vendored
Normal file
31
test/fixtures/m3u8/domainUris.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"allowCache": true,
|
||||
"mediaSequence": 0,
|
||||
"playlistType": "VOD",
|
||||
"segments": [
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "/00001.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "/subdir/00002.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "/00003.ts"
|
||||
},
|
||||
{
|
||||
"duration": 10,
|
||||
"timeline": 0,
|
||||
"uri": "/00004.ts"
|
||||
}
|
||||
],
|
||||
"targetDuration": 10,
|
||||
"endList": true,
|
||||
"discontinuitySequence": 0,
|
||||
"discontinuityStarts": []
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue