pr-player 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -5
- package/dist/{src/PrPlayer.d.ts → PrPlayer.d.ts} +3 -3
- package/dist/{src/decoder → decoder}/Decoder.d.ts +1 -1
- package/dist/{src/decoder → decoder}/type.d.ts +1 -1
- package/dist/{src/demuxer → demuxer}/Cacher.d.ts +1 -0
- package/dist/{src/demuxer → demuxer}/Demuxer.d.ts +2 -15
- package/dist/{src/demuxer → demuxer/parsers}/264Parser.d.ts +3 -8
- package/dist/demuxer/parsers/boxParser.d.ts +19 -0
- package/dist/{src/demuxer → demuxer/parsers}/flv264Parser.d.ts +4 -4
- package/dist/demuxer/parsers/fmp4Parser.d.ts +38 -0
- package/dist/demuxer/parsers/index.d.ts +7 -0
- package/dist/demuxer/parsers/mpdParser.d.ts +41 -0
- package/dist/{src/demuxer → demuxer/parsers}/ts264Parser.d.ts +8 -4
- package/dist/demuxer/parsers/types.d.ts +14 -0
- package/dist/{src/index.d.ts → index.d.ts} +1 -0
- package/dist/index.js +1255 -567
- package/dist/index.umd.cjs +2 -2
- package/dist/{src/render → render}/Render.d.ts +2 -2
- package/dist/{src/render → render}/RenderWorker.d.ts +1 -1
- package/dist/{src/tools.d.ts → tools.d.ts} +1 -1
- package/dist/type.d.ts +1 -0
- package/package.json +5 -5
- package/dist/src/type.d.ts +0 -1
- /package/dist/{src/PrResolves.d.ts → PrResolves.d.ts} +0 -0
- /package/dist/{src/audioPlayer → audioPlayer}/audioPlayer.d.ts +0 -0
- /package/dist/{src/decoder → decoder}/DecoderWorker.d.ts +0 -0
- /package/dist/{src/decoder → decoder}/decoder.worker.d.ts +0 -0
- /package/dist/{src/demuxer → demuxer}/DemuxerWorker.d.ts +0 -0
- /package/dist/{src/demuxer → demuxer}/demuxer.worker.d.ts +0 -0
- /package/dist/{src/demuxer → demuxer}/type.d.ts +0 -0
- /package/dist/{src/render → render}/render.worker.d.ts +0 -0
- /package/dist/{src/render → render}/type.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 对 flv 格式的地址进行解析 并输出 MediaStream,提供 demuxer 层(info、chunk
|
|
1
|
+
# 对 flv、hls、dash、mp4 格式的地址进行解析 并输出 MediaStream,提供 demuxer 层(info、chunk)回调、 decoder 层(audio、video、sei)回调 ,提供 cut 等相关能力,以支持根据业务层 SEI 对视频进行剪切渲染。
|
|
2
2
|
|
|
3
3
|
## 立即开始
|
|
4
4
|
|
|
@@ -14,16 +14,13 @@ npm i pr-player
|
|
|
14
14
|
import { PrPlayer } from 'pr-player'
|
|
15
15
|
|
|
16
16
|
// 除此之外 如果你需要自定义扩展 为你提供了独立的 Demuxer、Decoder、Render
|
|
17
|
-
import { DemuxerWorker } from '
|
|
18
|
-
import { DecoderWorker } from '../../src/index'
|
|
19
|
-
import { RenderWorker } from '../../src/index'
|
|
17
|
+
import { DemuxerWorker, DecoderWorker, RenderWorker } from 'pr-player'
|
|
20
18
|
```
|
|
21
19
|
|
|
22
20
|
## 快速使用
|
|
23
21
|
|
|
24
22
|
```js
|
|
25
23
|
const player = new PrPlayer()
|
|
26
|
-
const player = new PrPlayer({ debug: true })
|
|
27
24
|
|
|
28
25
|
// 如果你只需要复解器相关的能力 可以拿到复解后的所有回调
|
|
29
26
|
{
|
|
@@ -42,6 +39,7 @@ const player = new PrPlayer({ debug: true })
|
|
|
42
39
|
}
|
|
43
40
|
player.on.decoder.video = (video) => {
|
|
44
41
|
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: video`, video)
|
|
42
|
+
// video.frame 为 VideoFrame,使用后需要 video.frame.close()
|
|
45
43
|
}
|
|
46
44
|
player.on.decoder.sei = (sei) => {
|
|
47
45
|
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: sei`, sei)
|
|
@@ -51,6 +49,11 @@ const player = new PrPlayer({ debug: true })
|
|
|
51
49
|
await player.start('https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-720p.flv')
|
|
52
50
|
player.setMute(false) // 默认都是静音 所以主动开启
|
|
53
51
|
const stream = player.getStream()
|
|
52
|
+
|
|
53
|
+
// 绑定到 video 标签
|
|
54
|
+
const view = document.createElement('video')
|
|
55
|
+
view.srcObject = stream
|
|
56
|
+
view.play()
|
|
54
57
|
```
|
|
55
58
|
|
|
56
59
|
### 暂停渲染
|
|
@@ -72,10 +75,18 @@ player.stop()
|
|
|
72
75
|
### 创建剪切
|
|
73
76
|
|
|
74
77
|
```js
|
|
78
|
+
// sx、sy、sw、sh 为原视频坐标系下的裁剪区域,通常配合 on.demuxer.info 中的 width、height 使用
|
|
79
|
+
const { width, height } = info
|
|
75
80
|
player.cut.create('cut-any-key', { sx: width * 0.25, sy: height * 0.4, sw: width * 0.5, sh: height * 0.5 })
|
|
76
81
|
const stream = player.cut.getStream('cut-any-key')
|
|
77
82
|
```
|
|
78
83
|
|
|
84
|
+
### 修改剪切区域
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
player.cut.setCut('cut-any-key', { sx: 100, sy: 100, sw: 640, sh: 360 })
|
|
88
|
+
```
|
|
89
|
+
|
|
79
90
|
### 暂停剪切
|
|
80
91
|
|
|
81
92
|
```js
|
|
@@ -88,6 +99,138 @@ player.cut.setPause('cut-any-key', true)
|
|
|
88
99
|
player.cut.remove('cut-any-key')
|
|
89
100
|
```
|
|
90
101
|
|
|
102
|
+
## 结合 SEI 进行剪切
|
|
103
|
+
|
|
104
|
+
- 典型流程:解析 SEI 拿到业务坐标 → 创建或更新 cut → 输出独立 MediaStream
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
let videoInfo
|
|
108
|
+
|
|
109
|
+
player.on.demuxer.info = (info) => {
|
|
110
|
+
videoInfo = info
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
player.on.decoder.sei = (sei) => {
|
|
114
|
+
// 根据业务协议解析 sei,得到裁剪区域
|
|
115
|
+
const { sx, sy, sw, sh } = parseSeiRect(sei, videoInfo)
|
|
116
|
+
|
|
117
|
+
if (!player.cut.getStream('sei-cut')) {
|
|
118
|
+
player.cut.create('sei-cut', { sx, sy, sw, sh })
|
|
119
|
+
} else {
|
|
120
|
+
player.cut.setCut('sei-cut', { sx, sy, sw, sh })
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await player.start(url)
|
|
125
|
+
const cutStream = player.cut.getStream('sei-cut')
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## PrPlayer API
|
|
129
|
+
|
|
130
|
+
### 构造
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
new PrPlayer({ frameTrack?: boolean })
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
- `frameTrack`:是否默认开启追帧,适用于直播场景
|
|
137
|
+
|
|
138
|
+
### 实例方法
|
|
139
|
+
|
|
140
|
+
| 方法 | 说明 |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| `start(url)` | 开始拉流并解析,第一帧视频到达后 resolve |
|
|
143
|
+
| `stop()` | 停止拉流,销毁 worker 与 MediaStream |
|
|
144
|
+
| `getStream()` | 获取主路视频 MediaStream |
|
|
145
|
+
| `setPause(pause)` | 暂停/恢复主路渲染 |
|
|
146
|
+
| `setMute(state?)` | 设置静音,默认静音,播放前通常需 `setMute(false)` |
|
|
147
|
+
| `setOutputGain(gain)` | 设置输出音量 |
|
|
148
|
+
| `setFrameTrack(frameTrack)` | 开启/关闭追帧,适用于直播场景 |
|
|
149
|
+
| `isReady()` | 返回 Promise,MediaStream 激活后 resolve |
|
|
150
|
+
|
|
151
|
+
### cut 命名空间
|
|
152
|
+
|
|
153
|
+
| 方法 | 说明 |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `cut.create(key, { sx, sy, sw, sh })` | 创建剪切路,返回 cut 的 MediaStream |
|
|
156
|
+
| `cut.getStream(key)` | 获取已创建的 cut MediaStream |
|
|
157
|
+
| `cut.setCut(key, cutOption)` | 运行时修改裁剪区域 |
|
|
158
|
+
| `cut.setPause(key, pause)` | 暂停/恢复指定 cut 路 |
|
|
159
|
+
| `cut.remove(key)` | 移除指定 cut 路 |
|
|
160
|
+
|
|
161
|
+
### 实例属性
|
|
162
|
+
|
|
163
|
+
- `player.on`:事件回调,见下方
|
|
164
|
+
- `player.audioPlayer`:内部音频播放器,可通过 `player.audioPlayer.getStream()` 获取音频 MediaStream
|
|
165
|
+
|
|
166
|
+
## 事件回调 player.on
|
|
167
|
+
|
|
168
|
+
### demuxer
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
player.on.demuxer.info = (info) => {} // 流元信息,如 width、height
|
|
172
|
+
player.on.demuxer.config = (config) => {} // 音视频 decoder 配置
|
|
173
|
+
player.on.demuxer.chunk = (chunk) => {} // 解复用后的 chunk
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### decoder
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
player.on.decoder.audio = ({ audioData, playbackRate }) => {}
|
|
180
|
+
player.on.decoder.video = ({ timestamp, frame }) => {} // frame 为 VideoFrame
|
|
181
|
+
player.on.decoder.sei = (payload) => {} // H.264 SEI 载荷
|
|
182
|
+
player.on.decoder.analysis = ({ fps, cacheLength, decodingSpeed, decodingSpeedRatio }) => {}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 其他
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
player.on.error = (e) => {}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## 支持的地址格式
|
|
192
|
+
|
|
193
|
+
- `flv`:HTTP-FLV 直播/点播
|
|
194
|
+
- `hls`:`.m3u8` 直播/点播(TS 容器 + H.264/AAC)
|
|
195
|
+
- `dash`:`.mpd` DASH 点播/直播(fMP4 分片 + H.264/AAC)
|
|
196
|
+
- `mp4`:渐进式 MP4 点播(H.264/AAC)
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
// flv
|
|
200
|
+
await player.start('https://example.com/live.flv')
|
|
201
|
+
|
|
202
|
+
// hls
|
|
203
|
+
await player.start('https://example.com/live.m3u8')
|
|
204
|
+
|
|
205
|
+
// dash
|
|
206
|
+
await player.start('https://example.com/manifest.mpd')
|
|
207
|
+
|
|
208
|
+
// mp4
|
|
209
|
+
await player.start('https://example.com/video.mp4')
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- 直播场景可配合 `setFrameTrack(true)` 自动追帧
|
|
213
|
+
- hls / dash / mp4 点播会自动关闭追帧
|
|
214
|
+
- `rtmp://` 地址浏览器内不支持,请使用 HTTP-FLV 或 HLS 替代
|
|
215
|
+
|
|
216
|
+
## 自定义扩展
|
|
217
|
+
|
|
218
|
+
- 如果你不需要完整的 PrPlayer,可以单独使用 Worker 层自行组装管线:
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
import { DemuxerWorker, DecoderWorker, RenderWorker } from 'pr-player'
|
|
222
|
+
|
|
223
|
+
const demuxerWorker = new DemuxerWorker()
|
|
224
|
+
const decoderWorker = new DecoderWorker()
|
|
225
|
+
const renderWorker = new RenderWorker()
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 浏览器要求
|
|
229
|
+
|
|
230
|
+
- 需支持 WebCodecs(`VideoDecoder` / `AudioDecoder`)
|
|
231
|
+
- 视频输出优先使用 `MediaStreamTrackGenerator`,不支持时自动降级为 `canvas.captureStream()`
|
|
232
|
+
- 剪切多路输出需浏览器支持 `VideoFrame` 的 `visibleRect` 裁剪
|
|
233
|
+
|
|
91
234
|
## 代码仓库
|
|
92
235
|
|
|
93
236
|
[github](https://github.com/breathe97/pr-player)
|
|
@@ -12,16 +12,14 @@ interface On {
|
|
|
12
12
|
}) => void;
|
|
13
13
|
video?: (_frame: {
|
|
14
14
|
timestamp: number;
|
|
15
|
-
|
|
15
|
+
frame: VideoFrame;
|
|
16
16
|
}) => void;
|
|
17
17
|
sei?: (_payload: Uint8Array) => void;
|
|
18
18
|
analysis?: (_e: any) => void;
|
|
19
19
|
};
|
|
20
|
-
debug?: (_e: any) => void;
|
|
21
20
|
error?: (_e: any) => void;
|
|
22
21
|
}
|
|
23
22
|
interface PrPlayerOption {
|
|
24
|
-
debug?: boolean;
|
|
25
23
|
frameTrack?: boolean;
|
|
26
24
|
}
|
|
27
25
|
export declare class PrPlayer {
|
|
@@ -129,5 +127,7 @@ export declare class PrPlayer {
|
|
|
129
127
|
private initRender;
|
|
130
128
|
private flv;
|
|
131
129
|
private hls;
|
|
130
|
+
private mp4;
|
|
131
|
+
private dash;
|
|
132
132
|
}
|
|
133
133
|
export {};
|
|
@@ -27,7 +27,7 @@ export declare class Decoder {
|
|
|
27
27
|
on: On;
|
|
28
28
|
constructor();
|
|
29
29
|
init: (pattern: Pattern) => void;
|
|
30
|
-
initAudio: (config: AudioDecoderConfig) => void
|
|
30
|
+
initAudio: (config: AudioDecoderConfig) => Promise<void>;
|
|
31
31
|
initVideo: (config: VideoDecoderConfig) => void;
|
|
32
32
|
setFrameTrack: (frameTrack: boolean) => void;
|
|
33
33
|
push: (chunk: PendingChunk) => void;
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import { Cacher, Chunk } from './Cacher';
|
|
2
2
|
import { Pattern } from '../type';
|
|
3
|
-
export
|
|
4
|
-
kind: 'audio';
|
|
5
|
-
codec: string;
|
|
6
|
-
sampleRate: number;
|
|
7
|
-
numberOfChannels: number;
|
|
8
|
-
}
|
|
9
|
-
export interface VideoConfig {
|
|
10
|
-
kind: 'video';
|
|
11
|
-
codec: string;
|
|
12
|
-
sps: Uint8Array;
|
|
13
|
-
pps: Uint8Array;
|
|
14
|
-
description: Uint8Array;
|
|
15
|
-
}
|
|
3
|
+
export type { AudioConfig, VideoConfig } from './parsers/types';
|
|
16
4
|
export interface On {
|
|
17
|
-
debug?: (_debug: unknown) => void;
|
|
18
5
|
info?: (_info: any) => void;
|
|
19
|
-
config?: (_config: AudioConfig | VideoConfig) => void;
|
|
6
|
+
config?: (_config: import('./parsers/types').AudioConfig | import('./parsers/types').VideoConfig) => void;
|
|
20
7
|
chunk?: (_chunk: Chunk) => void;
|
|
21
8
|
sei?: (_sei: Uint8Array[]) => void;
|
|
22
9
|
}
|
|
@@ -5,13 +5,8 @@ export declare const parseAVCC: (avcc: Uint8Array) => {
|
|
|
5
5
|
profile: number;
|
|
6
6
|
compatibility: number;
|
|
7
7
|
level: number;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
sequenceParameterSetLength: number;
|
|
11
|
-
sps: Uint8Array<ArrayBuffer | SharedArrayBuffer>;
|
|
12
|
-
numOfPictureParameterSets: number;
|
|
13
|
-
pictureParameterSetLength: number;
|
|
14
|
-
pps: Uint8Array<ArrayBuffer | SharedArrayBuffer>;
|
|
8
|
+
sps: Uint8Array<ArrayBufferLike>;
|
|
9
|
+
pps: Uint8Array<ArrayBufferLike>;
|
|
15
10
|
};
|
|
16
11
|
export declare const naluToAVCC: (nalu: Uint8Array) => Uint8Array;
|
|
17
12
|
export declare const mergeNalus: (nalus: Uint8Array[]) => Uint8Array;
|
|
@@ -22,5 +17,5 @@ export declare const parseNalu: (nalu: Uint8Array) => {
|
|
|
22
17
|
nal_ref_idc: number;
|
|
23
18
|
nal_unit_type: number;
|
|
24
19
|
};
|
|
25
|
-
data: Uint8Array<
|
|
20
|
+
data: Uint8Array<ArrayBufferLike>;
|
|
26
21
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface BoxInfo {
|
|
2
|
+
offset: number;
|
|
3
|
+
size: number;
|
|
4
|
+
type: string;
|
|
5
|
+
headerSize: number;
|
|
6
|
+
contentStart: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const readBoxType: (view: DataView, offset: number) => string;
|
|
9
|
+
export declare const readBoxAt: (view: DataView, offset: number, end: number) => BoxInfo | null;
|
|
10
|
+
export declare const forEachBox: (view: DataView, start: number, end: number, fn: (box: BoxInfo) => void) => void;
|
|
11
|
+
export declare const findBox: (view: DataView, start: number, end: number, type: string) => BoxInfo | null;
|
|
12
|
+
export declare const collectBoxes: (view: DataView, start: number, end: number, type: string, out?: BoxInfo[]) => BoxInfo[];
|
|
13
|
+
export declare const findBoxInRange: (view: DataView, start: number, end: number, type: string) => BoxInfo | null;
|
|
14
|
+
export declare const findSampleEntryChild: (view: DataView, entryStart: number, entryEnd: number, type: string, skipBytes?: number) => BoxInfo | null;
|
|
15
|
+
export declare const listTopLevelBoxes: (view: DataView, end: number, limit?: number) => {
|
|
16
|
+
type: string;
|
|
17
|
+
offset: number;
|
|
18
|
+
size: number;
|
|
19
|
+
}[];
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Chunk } from '
|
|
2
|
-
import { AudioConfig, VideoConfig } from './
|
|
3
|
-
|
|
4
|
-
debug?: (_debug: any) => void;
|
|
1
|
+
import { Chunk } from '../Cacher';
|
|
2
|
+
import { AudioConfig, VideoConfig } from './types';
|
|
3
|
+
interface On {
|
|
5
4
|
info?: (_info: any) => void;
|
|
6
5
|
config?: (_config: AudioConfig | VideoConfig) => void;
|
|
7
6
|
chunk?: (_chunk: Chunk) => void;
|
|
@@ -25,3 +24,4 @@ export declare class ParseFLV {
|
|
|
25
24
|
private getAMFName;
|
|
26
25
|
private getAMFValue;
|
|
27
26
|
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Chunk } from '../Cacher';
|
|
2
|
+
import { AudioConfig, VideoConfig } from './types';
|
|
3
|
+
interface On {
|
|
4
|
+
info?: (_info: any) => void;
|
|
5
|
+
config?: (_config: AudioConfig | VideoConfig) => void;
|
|
6
|
+
chunk?: (_chunk: Chunk) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare class ParseFMP4 {
|
|
9
|
+
audioConfig?: AudioConfig;
|
|
10
|
+
videoConfig?: VideoConfig;
|
|
11
|
+
private tracks;
|
|
12
|
+
private mdatBox;
|
|
13
|
+
private progressiveParsed;
|
|
14
|
+
on: On;
|
|
15
|
+
/** moov-at-end 的 MP4 在 sample 提取完成前不能丢弃 buffer */
|
|
16
|
+
getDiscardOffset: (bufferLength: number, view: DataView) => number;
|
|
17
|
+
constructor();
|
|
18
|
+
parse: (view: DataView) => Promise<number>;
|
|
19
|
+
private tryRunProgressive;
|
|
20
|
+
private isProgressiveReady;
|
|
21
|
+
private parseMoov;
|
|
22
|
+
private readTkhdSize;
|
|
23
|
+
/** VisualSampleEntry 中的宽高(uint16,比 tkhd 更可靠) */
|
|
24
|
+
private readSampleEntrySize;
|
|
25
|
+
private parseTrak;
|
|
26
|
+
private parseEsds;
|
|
27
|
+
private findMdatForMoof;
|
|
28
|
+
private parseMoof;
|
|
29
|
+
private ticksToMs;
|
|
30
|
+
/** ctts:每个 sample 的 composition offset(timescale 单位) */
|
|
31
|
+
private readCttsOffsets;
|
|
32
|
+
private parseTraf;
|
|
33
|
+
private parseProgressive;
|
|
34
|
+
private collectProgressiveTrackSamples;
|
|
35
|
+
private isAvccKeyFrame;
|
|
36
|
+
private splitAvccNalus;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface MpdByteRange {
|
|
2
|
+
start: number;
|
|
3
|
+
end: number;
|
|
4
|
+
}
|
|
5
|
+
export interface MpdSegmentTemplate {
|
|
6
|
+
initialization?: string;
|
|
7
|
+
media?: string;
|
|
8
|
+
timescale: number;
|
|
9
|
+
duration: number;
|
|
10
|
+
startNumber: number;
|
|
11
|
+
}
|
|
12
|
+
export interface MpdSegmentListInfo {
|
|
13
|
+
timescale: number;
|
|
14
|
+
duration: number;
|
|
15
|
+
initRange?: MpdByteRange;
|
|
16
|
+
segments: MpdByteRange[];
|
|
17
|
+
}
|
|
18
|
+
export interface MpdRepresentation {
|
|
19
|
+
id: string;
|
|
20
|
+
codecs: string;
|
|
21
|
+
bandwidth: number;
|
|
22
|
+
width?: number;
|
|
23
|
+
height?: number;
|
|
24
|
+
baseUrl?: string;
|
|
25
|
+
template?: MpdSegmentTemplate;
|
|
26
|
+
segmentList?: MpdSegmentListInfo;
|
|
27
|
+
}
|
|
28
|
+
export interface MpdAdaptation {
|
|
29
|
+
kind: 'video' | 'audio' | 'mux';
|
|
30
|
+
mimeType: string;
|
|
31
|
+
representation: MpdRepresentation;
|
|
32
|
+
}
|
|
33
|
+
export interface MpdInfo {
|
|
34
|
+
isLive: boolean;
|
|
35
|
+
duration?: number;
|
|
36
|
+
baseUrl: string;
|
|
37
|
+
adaptations: MpdAdaptation[];
|
|
38
|
+
}
|
|
39
|
+
export declare const resolveUrl: (baseUrl: string, href: string) => string;
|
|
40
|
+
export declare const buildSegmentUrl: (baseUrl: string, template: string, vars: Record<string, string | number>) => string;
|
|
41
|
+
export declare const parseMpd: (xml: string, mpdUrl: string) => MpdInfo;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Chunk } from '
|
|
2
|
-
import { AudioConfig, VideoConfig } from './
|
|
3
|
-
|
|
1
|
+
import { Chunk } from '../Cacher';
|
|
2
|
+
import { AudioConfig, VideoConfig } from './types';
|
|
3
|
+
interface Pat {
|
|
4
4
|
header: {
|
|
5
5
|
pointer_field: number;
|
|
6
6
|
table_id: number;
|
|
@@ -45,7 +45,6 @@ export interface PESPacket {
|
|
|
45
45
|
data: Uint8Array;
|
|
46
46
|
}
|
|
47
47
|
export interface On {
|
|
48
|
-
debug?: (_debug: any) => void;
|
|
49
48
|
info?: (_info: any) => void;
|
|
50
49
|
config?: (_config: AudioConfig | VideoConfig) => void;
|
|
51
50
|
chunk?: (_chunk: Chunk) => void;
|
|
@@ -65,6 +64,8 @@ export declare class ParseTS {
|
|
|
65
64
|
private parsePMT;
|
|
66
65
|
private parseAdaptationField;
|
|
67
66
|
private parseAudio;
|
|
67
|
+
/** 解析 ADTS 头,返回 header 长度与 AAC 配置 */
|
|
68
|
+
private parseAdts;
|
|
68
69
|
private parseVideo;
|
|
69
70
|
/**
|
|
70
71
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
@@ -74,4 +75,7 @@ export declare class ParseTS {
|
|
|
74
75
|
type: number;
|
|
75
76
|
nalu: Uint8Array<ArrayBufferLike>;
|
|
76
77
|
}[];
|
|
78
|
+
/** 查找 Annex-B 起始码,支持 0x000001 与 0x00000001 */
|
|
79
|
+
private findAnnexBStart;
|
|
77
80
|
}
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AudioConfig {
|
|
2
|
+
kind: 'audio';
|
|
3
|
+
codec: string;
|
|
4
|
+
sampleRate: number;
|
|
5
|
+
numberOfChannels: number;
|
|
6
|
+
description?: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
export interface VideoConfig {
|
|
9
|
+
kind: 'video';
|
|
10
|
+
codec: string;
|
|
11
|
+
sps: Uint8Array;
|
|
12
|
+
pps: Uint8Array;
|
|
13
|
+
description: Uint8Array;
|
|
14
|
+
}
|