pr-player 0.2.3 → 0.2.5
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 +29 -36
- package/dist/PrPlayer.d.ts +16 -16
- package/dist/decoder/Decoder.d.ts +9 -6
- package/dist/decoder/DecoderWorker.d.ts +2 -5
- package/dist/decoder/type.d.ts +1 -0
- package/dist/demuxer/Demuxer.d.ts +1 -1
- package/dist/demuxer/DemuxerWorker.d.ts +2 -1
- package/dist/index.js +106 -90
- package/dist/index.umd.cjs +4 -4
- package/dist/tools.d.ts +1 -1
- package/dist/type.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 对 flv 格式的地址进行解析 并输出
|
|
1
|
+
# 对 flv 格式的地址进行解析 并输出 MediaStream,提供 demuxer 层(info、chunk、sei)回调、 decoder 层(audio、video)回调 ,提供 cut 等相关能力,以支持根据业务层 SEI 对视频进行剪切渲染。
|
|
2
2
|
|
|
3
3
|
## 立即开始
|
|
4
4
|
|
|
@@ -13,31 +13,44 @@ npm i pr-player
|
|
|
13
13
|
```js
|
|
14
14
|
import { PrPlayer } from 'pr-player'
|
|
15
15
|
|
|
16
|
-
// 除此之外 如果你需要自定义扩展 为你提供了独立的 Demuxer、Decoder、Render
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
16
|
+
// 除此之外 如果你需要自定义扩展 为你提供了独立的 Demuxer、Decoder、Render
|
|
17
|
+
import { DemuxerWorker } from '../../src/index'
|
|
18
|
+
import { DecoderWorker } from '../../src/index'
|
|
19
|
+
import { RenderWorker } from '../../src/index'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## 快速使用
|
|
23
23
|
|
|
24
24
|
```js
|
|
25
25
|
const player = new PrPlayer()
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
const player = new PrPlayer({ debug: true })
|
|
27
|
+
|
|
28
|
+
// 如果你只需要复解器相关的能力 可以拿到复解后的所有回调
|
|
29
|
+
{
|
|
30
|
+
player.on.demuxer.info = (info) => {
|
|
31
|
+
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: info`, info)
|
|
32
|
+
}
|
|
33
|
+
player.on.demuxer.chunk = (chunk) => {
|
|
34
|
+
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: chunk`, chunk)
|
|
35
|
+
}
|
|
36
|
+
player.on.demuxer.sei = (sei) => {
|
|
37
|
+
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: sei`, sei)
|
|
34
38
|
}
|
|
39
|
+
}
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
// 如果你只需要解码器相关的能力 可以拿到解码后的所有回调
|
|
42
|
+
{
|
|
43
|
+
player.on.decoder.audio = (audio) => {
|
|
44
|
+
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: audio`, audio)
|
|
45
|
+
}
|
|
46
|
+
player.on.decoder.video = (video) => {
|
|
47
|
+
console.log('\x1b[38;2;0;151;255m%c%s\x1b[0m', 'color:#0097ff;', `------->Breathe: video`, video)
|
|
39
48
|
}
|
|
40
49
|
}
|
|
50
|
+
|
|
51
|
+
await player.start('https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-720p.flv')
|
|
52
|
+
player.setMute(false) // 默认都是静音 所以主动开启
|
|
53
|
+
const stream = player.getStream()
|
|
41
54
|
```
|
|
42
55
|
|
|
43
56
|
### 暂停渲染
|
|
@@ -46,14 +59,6 @@ const play = async () => {
|
|
|
46
59
|
player.setPause(true)
|
|
47
60
|
```
|
|
48
61
|
|
|
49
|
-
### 设置渲染模式
|
|
50
|
-
|
|
51
|
-
- 默认只开启 'stream' 如果需要同时使用 'canvas' 、'stream' 则需要手动设置
|
|
52
|
-
|
|
53
|
-
```js
|
|
54
|
-
player.setShader(['canvas', 'stream'])
|
|
55
|
-
```
|
|
56
|
-
|
|
57
62
|
### 停止
|
|
58
63
|
|
|
59
64
|
```js
|
|
@@ -68,10 +73,6 @@ player.stop()
|
|
|
68
73
|
|
|
69
74
|
```js
|
|
70
75
|
player.cut.create('cut-any-key', { sx: width * 0.25, sy: height * 0.4, sw: width * 0.5, sh: height * 0.5 })
|
|
71
|
-
|
|
72
|
-
const canvas = player.cut.getCanvas('cut-any-key')
|
|
73
|
-
|
|
74
|
-
// 渲染方式二
|
|
75
76
|
const stream = player.cut.getStream('cut-any-key')
|
|
76
77
|
```
|
|
77
78
|
|
|
@@ -81,14 +82,6 @@ const stream = player.cut.getStream('cut-any-key')
|
|
|
81
82
|
player.cut.setPause('cut-any-key', true)
|
|
82
83
|
```
|
|
83
84
|
|
|
84
|
-
### 设置渲染模式
|
|
85
|
-
|
|
86
|
-
- 默认只开启 'stream' 如果需要同时使用 'canvas' 、'stream' 则需要手动设置
|
|
87
|
-
|
|
88
|
-
```js
|
|
89
|
-
player.cut.setShader('cut-any-key', ['canvas', 'stream'])
|
|
90
|
-
```
|
|
91
|
-
|
|
92
85
|
### 移除剪切
|
|
93
86
|
|
|
94
87
|
```js
|
package/dist/PrPlayer.d.ts
CHANGED
|
@@ -36,10 +36,6 @@ export declare class PrPlayer {
|
|
|
36
36
|
private cutRenders;
|
|
37
37
|
trackGenerator: MediaStreamTrackGenerator;
|
|
38
38
|
constructor(option?: PrPlayerOption);
|
|
39
|
-
/**
|
|
40
|
-
* 初始化
|
|
41
|
-
*/
|
|
42
|
-
init: () => void;
|
|
43
39
|
/**
|
|
44
40
|
* 开始播放
|
|
45
41
|
* @param url : string
|
|
@@ -72,18 +68,6 @@ export declare class PrPlayer {
|
|
|
72
68
|
* 是否已准备好
|
|
73
69
|
*/
|
|
74
70
|
isReady: () => Promise<unknown>;
|
|
75
|
-
/**
|
|
76
|
-
* 初始化解复器
|
|
77
|
-
*/
|
|
78
|
-
private initDemuxer;
|
|
79
|
-
/**
|
|
80
|
-
* 初始化解码器
|
|
81
|
-
*/
|
|
82
|
-
private initDecoder;
|
|
83
|
-
/**
|
|
84
|
-
* 初始化渲染器
|
|
85
|
-
*/
|
|
86
|
-
private initRender;
|
|
87
71
|
cut: {
|
|
88
72
|
/**
|
|
89
73
|
* 创建剪切
|
|
@@ -112,6 +96,22 @@ export declare class PrPlayer {
|
|
|
112
96
|
*/
|
|
113
97
|
remove: (key: string) => void;
|
|
114
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* 初始化
|
|
101
|
+
*/
|
|
102
|
+
private init;
|
|
103
|
+
/**
|
|
104
|
+
* 初始化解复器
|
|
105
|
+
*/
|
|
106
|
+
private initDemuxer;
|
|
107
|
+
/**
|
|
108
|
+
* 初始化解码器
|
|
109
|
+
*/
|
|
110
|
+
private initDecoder;
|
|
111
|
+
/**
|
|
112
|
+
* 初始化渲染器
|
|
113
|
+
*/
|
|
114
|
+
private initRender;
|
|
115
115
|
private flv;
|
|
116
116
|
private hls;
|
|
117
117
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Pattern } from '../type';
|
|
1
2
|
import { On } from './type';
|
|
2
3
|
export declare class Decoder {
|
|
4
|
+
private pattern;
|
|
3
5
|
private audioDecoderConfig?;
|
|
4
6
|
private audioDecoder?;
|
|
5
7
|
private videoDecoderConfig?;
|
|
@@ -10,18 +12,19 @@ export declare class Decoder {
|
|
|
10
12
|
private isProcessing;
|
|
11
13
|
private decodeTimer;
|
|
12
14
|
private frameTrack;
|
|
13
|
-
private
|
|
15
|
+
private isFrameTrack;
|
|
16
|
+
private fameTrackOption;
|
|
14
17
|
private decodingSpeed;
|
|
18
|
+
private fps;
|
|
19
|
+
private firstVideoChunkTimestamp?;
|
|
20
|
+
private secondVideoChunkTimestamp?;
|
|
15
21
|
private decodingSpeedRatio;
|
|
16
22
|
private maxDecodingSpeedRatio;
|
|
23
|
+
private lastRenderTime?;
|
|
17
24
|
private nextRenderTime?;
|
|
18
25
|
on: On;
|
|
19
26
|
constructor();
|
|
20
|
-
init: (
|
|
21
|
-
decodingSpeed: number;
|
|
22
|
-
frameTrack?: boolean;
|
|
23
|
-
minFrameTrackCacheNum?: number;
|
|
24
|
-
}) => void;
|
|
27
|
+
init: (pattern: Pattern) => void;
|
|
25
28
|
setFrameTrack: (frameTrack: boolean) => void;
|
|
26
29
|
private initDecodeInterval;
|
|
27
30
|
private decode;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
+
import { Pattern } from '../type';
|
|
1
2
|
import { On } from './type';
|
|
2
3
|
export declare class DecoderWorker {
|
|
3
4
|
worker: Worker;
|
|
4
5
|
on: On;
|
|
5
6
|
constructor();
|
|
6
|
-
init: (
|
|
7
|
-
decodingSpeed: number;
|
|
8
|
-
frameTrack?: boolean;
|
|
9
|
-
minFrameTrackCacheNum?: number;
|
|
10
|
-
}) => void;
|
|
7
|
+
init: (pattern: Pattern) => void;
|
|
11
8
|
setFrameTrack: (frameTrack: boolean) => void;
|
|
12
9
|
audio: {
|
|
13
10
|
init: (config: AudioDecoderConfig) => void;
|
package/dist/decoder/type.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ function L(l) {
|
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
class
|
|
21
|
+
class F {
|
|
22
22
|
worker = new L();
|
|
23
23
|
on = {};
|
|
24
24
|
constructor() {
|
|
@@ -46,9 +46,9 @@ class N {
|
|
|
46
46
|
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
const S = `(function(){"use strict";class
|
|
49
|
+
const S = `(function(){"use strict";class c{pattern="flv";audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];isProcessing=!1;decodeTimer=0;frameTrack=!1;isFrameTrack=!1;fameTrackOption={flv:[20,50],hls:[200,300],dash:[50,100],rtmp:[50,100]};decodingSpeed=16;fps=0;firstVideoChunkTimestamp;secondVideoChunkTimestamp;decodingSpeedRatio=1;maxDecodingSpeedRatio=2;lastRenderTime;nextRenderTime;on={audio:{},video:{}};constructor(){}init=e=>{this.destroy(),this.pattern=e,this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()};setFrameTrack=e=>{this.frameTrack=e,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};initDecodeInterval=()=>{let e=this.decodingSpeed/this.decodingSpeedRatio;const i=this.baseTime+performance.now();if(this.lastRenderTime||(this.lastRenderTime=i),this.fps=Math.round(1e3/(i-this.lastRenderTime)),this.lastRenderTime=i,this.nextRenderTime){const t=this.lastRenderTime-this.nextRenderTime;e-=t}this.nextRenderTime=this.lastRenderTime+e,this.decodeTimer=setTimeout(()=>{this.decode(),this.initDecodeInterval()},e)};decode=()=>{if(this.isProcessing!==!0){for(this.isProcessing=!0;;){const e=this.pendingChunks.shift(),i=this.pendingChunks.length;if(this.frameTrack){const[n,r]=this.fameTrackOption[this.pattern];if(i<=n&&(this.isFrameTrack=!1),i>=r&&(this.isFrameTrack=!0),this.isFrameTrack){const a=Math.min(1+(i-n)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(a.toFixed(1))}else this.decodingSpeedRatio=1}if(this.on.debug){const{decodingSpeed:n,decodingSpeedRatio:r,fps:a}=this;this.on.debug({decodingSpeed:n,decodingSpeedRatio:r,fps:a})}if(!e)break;const{type:t,init:o}=e;switch(t){case"audio":this.decodeAudio(o);break;case"video":this.decodeVideo(o);break}if(t==="video")break}this.isProcessing=!1}};decodeAudio=e=>{if(!this.audioDecoder)return;const i=new EncodedAudioChunk(e);this.audioDecoder.decode(i)};decodeVideo=e=>{if(this.videoDecoder&&(e.type==="key"&&(this.hasKeyFrame=!0),this.firstVideoChunkTimestamp?this.secondVideoChunkTimestamp||(this.secondVideoChunkTimestamp=e.timestamp,this.decodingSpeed=(this.secondVideoChunkTimestamp-this.firstVideoChunkTimestamp)/1e3):this.firstVideoChunkTimestamp=e.timestamp,this.hasKeyFrame)){const i=new EncodedVideoChunk(e);this.videoDecoder.decode(i)}};destroy=()=>{this.audio.destroy(),this.video.destroy(),clearInterval(this.decodeTimer)};audio={init:e=>{this.audio.destroy(),this.audioDecoderConfig={...e},this.audioDecoder=new AudioDecoder({output:i=>{const t=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:i,playbackRate:t})},error:i=>{this.on.audio.error&&this.on.audio.error(i)}}),this.audioDecoder.configure(this.audioDecoderConfig)},push:e=>{this.pendingChunks.push({type:"audio",init:e})},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:e=>{this.video.destroy(),this.videoDecoderConfig={...e},this.videoDecoder=new VideoDecoder({output:async i=>{const t=i.timestamp+this.baseTime*1e3,o=await createImageBitmap(i);i.close(),o.width>0&&o.height>0?this.on.video.decode&&this.on.video.decode({timestamp:t,bitmap:o}):o.close()},error:i=>{this.on.video.error&&this.on.video.error(i)}}),this.videoDecoder.configure(this.videoDecoderConfig)},push:e=>{this.pendingChunks.push({type:"video",init:e})},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}const d=new c;d.on.audio.decode=s=>postMessage({type:"audio",action:"onDecode",data:s}),d.on.audio.error=s=>postMessage({type:"audio",action:"onError",data:s}),d.on.video.decode=s=>postMessage({type:"video",action:"onDecode",data:s}),d.on.video.error=s=>postMessage({type:"video",action:"onError",data:s}),onmessage=s=>{const{type:e,action:i,data:t}=s.data;if(e){const o=d[e][i];o&&o(t)}else{const o=d[i];o&&o(t)}}})();
|
|
50
50
|
`, v = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", S], { type: "text/javascript;charset=utf-8" });
|
|
51
|
-
function
|
|
51
|
+
function V(l) {
|
|
52
52
|
let t;
|
|
53
53
|
try {
|
|
54
54
|
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
@@ -67,8 +67,8 @@ function F(l) {
|
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
class
|
|
71
|
-
worker = new
|
|
70
|
+
class N {
|
|
71
|
+
worker = new V();
|
|
72
72
|
on = { audio: {}, video: {} };
|
|
73
73
|
constructor() {
|
|
74
74
|
this.worker.onmessage = (t) => {
|
|
@@ -105,8 +105,8 @@ class B {
|
|
|
105
105
|
this.worker.postMessage({ action: "destroy" }), this.worker.terminate();
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
|
-
var
|
|
109
|
-
class
|
|
108
|
+
var B = Object.defineProperty, E = (l, t, s) => t in l ? B(l, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : l[t] = s, y = (l, t, s) => E(l, typeof t != "symbol" ? t + "" : t, s);
|
|
109
|
+
class G {
|
|
110
110
|
constructor(t, s) {
|
|
111
111
|
y(this, "inputStream", new MediaStream()), y(this, "outputStream", new MediaStream()), y(this, "inputGain", 1), y(this, "enhanceGain", 1), y(this, "bgsGain", 1), y(this, "bgmGain", 1), y(this, "outputGain", 1), y(this, "mixAudioMap", /* @__PURE__ */ new Map()), y(this, "audioContext", new AudioContext()), y(this, "sourceNode"), y(this, "inputGainNode"), y(this, "enhanceGainNode"), y(this, "bgsGainNode"), y(this, "bgmGainNode"), y(this, "analyserNode"), y(this, "analyserArrayData"), y(this, "outputGainNode"), y(this, "destinationNode"), y(this, "filterStream", (e) => e), y(this, "stop", () => {
|
|
112
112
|
{
|
|
@@ -160,7 +160,7 @@ class O {
|
|
|
160
160
|
this.setMute(!0), this.audioContext.resume();
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
const
|
|
163
|
+
const O = async (l, t) => {
|
|
164
164
|
try {
|
|
165
165
|
const { format: s, numberOfChannels: e, numberOfFrames: i, sampleRate: n } = t, r = l.createBuffer(e, i, n);
|
|
166
166
|
for (let a = 0; a < e; a++) {
|
|
@@ -206,13 +206,13 @@ class W {
|
|
|
206
206
|
constructor() {
|
|
207
207
|
}
|
|
208
208
|
init = (t) => {
|
|
209
|
-
t || (t = new (window.AudioContext || window.webkitAudioContext)()), this.audioContext = t, this.destination = this.audioContext.createMediaStreamDestination(), this.stream = new MediaStream(), this.stream.addTrack(this.destination.stream.getAudioTracks()[0]), this.prAudioStream = new
|
|
209
|
+
t || (t = new (window.AudioContext || window.webkitAudioContext)()), this.audioContext = t, this.destination = this.audioContext.createMediaStreamDestination(), this.stream = new MediaStream(), this.stream.addTrack(this.destination.stream.getAudioTracks()[0]), this.prAudioStream = new G(this.stream, this.audioContext), this.nextStartTime = 0, this.pendingSources = [];
|
|
210
210
|
};
|
|
211
211
|
async push(t) {
|
|
212
212
|
const { audioData: s, playbackRate: e = 1 } = t;
|
|
213
213
|
try {
|
|
214
214
|
if (!this.audioContext || !this.destination) return;
|
|
215
|
-
let i = await
|
|
215
|
+
let i = await O(this.audioContext, s);
|
|
216
216
|
if (!i) return;
|
|
217
217
|
const n = this.audioContext.createBufferSource();
|
|
218
218
|
n.buffer = i, n.playbackRate.value = e;
|
|
@@ -267,14 +267,14 @@ class z {
|
|
|
267
267
|
const q = (l) => {
|
|
268
268
|
const t = l.toLowerCase();
|
|
269
269
|
return t.includes(".m3u8") || t.includes("hls") || t.includes("master.m3u8") || t.match(/index\d*\.m3u8/) ? "hls" : t.includes(".mpd") || t.includes("dash") ? "dash" : t.startsWith("rtmp://") || t.startsWith("rtmps://") ? "rtmp" : t.includes(".flv") || t.includes("flv") && !t.includes("flash") ? "flv" : "unknown";
|
|
270
|
-
},
|
|
270
|
+
}, R = (l) => {
|
|
271
271
|
const t = l?.getTracks() || [];
|
|
272
272
|
for (const s of t)
|
|
273
273
|
s.stop();
|
|
274
274
|
}, A = () => {
|
|
275
275
|
const l = new MediaStreamTrackGenerator({ kind: "video" }), t = new MediaStream([l]), s = new z();
|
|
276
276
|
return s.init({ writable: l.writable }), { worker: s, stream: t, destroy: () => {
|
|
277
|
-
s.destroy(),
|
|
277
|
+
s.destroy(), R(t);
|
|
278
278
|
} };
|
|
279
279
|
};
|
|
280
280
|
class $ {
|
|
@@ -316,7 +316,7 @@ const H = (l, t) => {
|
|
|
316
316
|
const s = new Uint8Array(l), e = new Uint8Array(t), i = new Uint8Array(11 + s.length + e.length);
|
|
317
317
|
let n = 0;
|
|
318
318
|
return i[n++] = 1, i[n++] = s[1], i[n++] = s[2], i[n++] = s[3], i[n++] = 255, i[n++] = 225, i[n++] = s.length >> 8 & 255, i[n++] = s.length & 255, i.set(s, n), n += s.length, i[n++] = 1, i[n++] = e.length >> 8 & 255, i[n++] = e.length & 255, i.set(e, n), i;
|
|
319
|
-
},
|
|
319
|
+
}, P = (l) => {
|
|
320
320
|
let t = 0;
|
|
321
321
|
const s = new DataView(l.buffer), e = s.getUint8(t);
|
|
322
322
|
if (t = t + 1, e !== 1) throw new Error("Invalid AVC version");
|
|
@@ -437,21 +437,15 @@ class et {
|
|
|
437
437
|
const { debug: s = !1 } = t;
|
|
438
438
|
this.option.debug = s;
|
|
439
439
|
}
|
|
440
|
-
/**
|
|
441
|
-
* 初始化
|
|
442
|
-
*/
|
|
443
|
-
init = () => {
|
|
444
|
-
this.initDecoder(), this.initRender(), this.audioPlayer = new W(), this.audioPlayer.init();
|
|
445
|
-
};
|
|
446
440
|
/**
|
|
447
441
|
* 开始播放
|
|
448
442
|
* @param url : string
|
|
449
443
|
*/
|
|
450
444
|
start = async (t) => {
|
|
451
|
-
this.stop(), this.url = t
|
|
445
|
+
this.stop(), this.url = t;
|
|
452
446
|
const s = q(t);
|
|
453
447
|
if (s === "unknown") throw new Error("This address cannot be parsed.");
|
|
454
|
-
switch (this.
|
|
448
|
+
switch (this.init(s), s) {
|
|
455
449
|
case "flv":
|
|
456
450
|
this.flv.start();
|
|
457
451
|
break;
|
|
@@ -473,7 +467,7 @@ class et {
|
|
|
473
467
|
const t = [...this.cutRenders.keys()];
|
|
474
468
|
for (const s of t)
|
|
475
469
|
this.cutRenders.get(s)?.worker.destroy(), this.cutRenders.delete(s);
|
|
476
|
-
|
|
470
|
+
R(this.stream), this.audioPlayer?.destroy();
|
|
477
471
|
};
|
|
478
472
|
/**
|
|
479
473
|
* 获取媒体流
|
|
@@ -505,16 +499,46 @@ class et {
|
|
|
505
499
|
const t = () => this.stream?.active === !0;
|
|
506
500
|
return this.prResolves.add("isReady", t);
|
|
507
501
|
};
|
|
502
|
+
cut = {
|
|
503
|
+
/**
|
|
504
|
+
* 创建剪切
|
|
505
|
+
*/
|
|
506
|
+
create: (t, s) => {
|
|
507
|
+
let e = this.cutRenders.get(t);
|
|
508
|
+
return e ? (e.worker.setCut(s), e.worker.setPause(!1), e) : (e = A(), e.worker.setCut(s), this.cutRenders.set(t, e), e);
|
|
509
|
+
},
|
|
510
|
+
/**
|
|
511
|
+
* 获取媒体流
|
|
512
|
+
*/
|
|
513
|
+
getStream: (t) => this.cutRenders.get(t)?.stream,
|
|
514
|
+
/**
|
|
515
|
+
* 设置暂停
|
|
516
|
+
* @param pause: boolean
|
|
517
|
+
*/
|
|
518
|
+
setPause: (t, s) => {
|
|
519
|
+
this.cutRenders.get(t)?.worker.setPause(s);
|
|
520
|
+
},
|
|
521
|
+
/**
|
|
522
|
+
* 移除剪切
|
|
523
|
+
*/
|
|
524
|
+
remove: (t) => {
|
|
525
|
+
this.cutRenders.get(t)?.destroy(), this.cutRenders.delete(t);
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
* 初始化
|
|
530
|
+
*/
|
|
531
|
+
init = (t) => {
|
|
532
|
+
this.initDecoder(t), this.initRender(), this.initDemuxer(t), this.audioPlayer = new W(), this.audioPlayer.init();
|
|
533
|
+
};
|
|
508
534
|
/**
|
|
509
535
|
* 初始化解复器
|
|
510
536
|
*/
|
|
511
537
|
initDemuxer = (t) => {
|
|
512
|
-
this.demuxerWorker = new
|
|
538
|
+
this.demuxerWorker = new F(), this.demuxerWorker.init(t), this.demuxerWorker.on.debug = (s) => {
|
|
513
539
|
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: debug", s);
|
|
514
540
|
}, this.demuxerWorker.on.info = (s) => {
|
|
515
|
-
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: info", s);
|
|
516
|
-
const { framerate: e = 25 } = s, i = 1e3 / e;
|
|
517
|
-
this.decoderWorker?.init({ decodingSpeed: i }), this.on.demuxer.info && this.on.demuxer.info(s);
|
|
541
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: info", s), this.on.demuxer.info && this.on.demuxer.info(s);
|
|
518
542
|
}, this.demuxerWorker.on.config = (s) => {
|
|
519
543
|
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: config", s), this.on.demuxer.config && this.on.demuxer.config(s);
|
|
520
544
|
const { kind: e } = s;
|
|
@@ -559,19 +583,21 @@ class et {
|
|
|
559
583
|
/**
|
|
560
584
|
* 初始化解码器
|
|
561
585
|
*/
|
|
562
|
-
initDecoder = () => {
|
|
563
|
-
this.decoderWorker = new
|
|
564
|
-
this.
|
|
565
|
-
}, this.decoderWorker.on.audio.
|
|
566
|
-
this.
|
|
567
|
-
}, this.decoderWorker.on.
|
|
568
|
-
this.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
this.
|
|
586
|
+
initDecoder = (t) => {
|
|
587
|
+
this.decoderWorker = new N(), this.decoderWorker.init(t), this.decoderWorker.on.debug = (s) => {
|
|
588
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: debug", s);
|
|
589
|
+
}, this.decoderWorker.on.audio.decode = (s) => {
|
|
590
|
+
this.audioPlayer?.push(s), this.on.decoder.audio && this.on.decoder.audio(s);
|
|
591
|
+
}, this.decoderWorker.on.audio.error = (s) => {
|
|
592
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: audio.error ", s), this.on.error && this.on.error(s);
|
|
593
|
+
}, this.decoderWorker.on.video.decode = async (s) => {
|
|
594
|
+
this.renderWorker?.push(s);
|
|
595
|
+
const e = [...this.cutRenders.keys()];
|
|
596
|
+
for (const i of e)
|
|
597
|
+
this.cutRenders.get(i)?.worker.push(s);
|
|
598
|
+
this.on.decoder.video && this.on.decoder.video(s), s.bitmap.close();
|
|
599
|
+
}, this.decoderWorker.on.video.error = (s) => {
|
|
600
|
+
this.stop(), this.on.error && this.on.error(s);
|
|
575
601
|
};
|
|
576
602
|
};
|
|
577
603
|
/**
|
|
@@ -581,32 +607,6 @@ class et {
|
|
|
581
607
|
const { worker: t, stream: s } = A();
|
|
582
608
|
this.renderWorker = t, this.stream = s, this.renderWorker.setPause(!1);
|
|
583
609
|
};
|
|
584
|
-
cut = {
|
|
585
|
-
/**
|
|
586
|
-
* 创建剪切
|
|
587
|
-
*/
|
|
588
|
-
create: (t, s) => {
|
|
589
|
-
let e = this.cutRenders.get(t);
|
|
590
|
-
return e ? (e.worker.setCut(s), e.worker.setPause(!1), e) : (e = A(), e.worker.setCut(s), this.cutRenders.set(t, e), e);
|
|
591
|
-
},
|
|
592
|
-
/**
|
|
593
|
-
* 获取媒体流
|
|
594
|
-
*/
|
|
595
|
-
getStream: (t) => this.cutRenders.get(t)?.stream,
|
|
596
|
-
/**
|
|
597
|
-
* 设置暂停
|
|
598
|
-
* @param pause: boolean
|
|
599
|
-
*/
|
|
600
|
-
setPause: (t, s) => {
|
|
601
|
-
this.cutRenders.get(t)?.worker.setPause(s);
|
|
602
|
-
},
|
|
603
|
-
/**
|
|
604
|
-
* 移除剪切
|
|
605
|
-
*/
|
|
606
|
-
remove: (t) => {
|
|
607
|
-
this.cutRenders.get(t)?.destroy(), this.cutRenders.delete(t);
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
610
|
flv = {
|
|
611
611
|
start: async () => {
|
|
612
612
|
try {
|
|
@@ -966,7 +966,7 @@ class Z {
|
|
|
966
966
|
if (!this.videoConfig) {
|
|
967
967
|
let u, g;
|
|
968
968
|
if (u = r.find((m) => m.type === 7)?.nalu.slice(4), g = r.find((m) => m.type === 8)?.nalu.slice(4), u && g) {
|
|
969
|
-
const f = H(u, g), { codec: m } =
|
|
969
|
+
const f = H(u, g), { codec: m } = P(f);
|
|
970
970
|
this.videoConfig = { kind: "video", codec: m, description: f, sps: u, pps: g }, this.on.config && this.on.config(this.videoConfig);
|
|
971
971
|
}
|
|
972
972
|
}
|
|
@@ -1177,7 +1177,7 @@ class tt {
|
|
|
1177
1177
|
switch (a) {
|
|
1178
1178
|
case 7:
|
|
1179
1179
|
if (o === 0) {
|
|
1180
|
-
const p =
|
|
1180
|
+
const p = P(h);
|
|
1181
1181
|
return { frameType: r, codecID: a, avcPacketType: o, cts: d, data: h, ...p };
|
|
1182
1182
|
} else if (o === 1) {
|
|
1183
1183
|
const p = [], u = i + e - 5;
|
|
@@ -1312,6 +1312,7 @@ class st {
|
|
|
1312
1312
|
};
|
|
1313
1313
|
}
|
|
1314
1314
|
class it {
|
|
1315
|
+
pattern = "flv";
|
|
1315
1316
|
audioDecoderConfig;
|
|
1316
1317
|
audioDecoder;
|
|
1317
1318
|
videoDecoderConfig;
|
|
@@ -1324,22 +1325,33 @@ class it {
|
|
|
1324
1325
|
decodeTimer = 0;
|
|
1325
1326
|
// 解码定时器
|
|
1326
1327
|
frameTrack = !1;
|
|
1327
|
-
//
|
|
1328
|
-
|
|
1329
|
-
//
|
|
1330
|
-
|
|
1328
|
+
// 是否开启自动追帧
|
|
1329
|
+
isFrameTrack = !1;
|
|
1330
|
+
// 当前是否正在追帧
|
|
1331
|
+
fameTrackOption = {
|
|
1332
|
+
// [停止追帧, 开启追帧]
|
|
1333
|
+
flv: [20, 50],
|
|
1334
|
+
hls: [200, 300],
|
|
1335
|
+
dash: [50, 100],
|
|
1336
|
+
rtmp: [50, 100]
|
|
1337
|
+
};
|
|
1338
|
+
decodingSpeed = 16;
|
|
1331
1339
|
// ms
|
|
1340
|
+
fps = 0;
|
|
1341
|
+
// 实时渲染fps
|
|
1342
|
+
firstVideoChunkTimestamp;
|
|
1343
|
+
secondVideoChunkTimestamp;
|
|
1332
1344
|
decodingSpeedRatio = 1;
|
|
1333
1345
|
maxDecodingSpeedRatio = 2;
|
|
1346
|
+
lastRenderTime;
|
|
1347
|
+
// 上一次渲染的时间
|
|
1334
1348
|
nextRenderTime;
|
|
1335
1349
|
// 下一次渲染的时间
|
|
1336
1350
|
on = { audio: {}, video: {} };
|
|
1337
1351
|
constructor() {
|
|
1338
|
-
this.baseTime = (/* @__PURE__ */ new Date()).getTime() - performance.now(), this.initDecodeInterval();
|
|
1339
1352
|
}
|
|
1340
1353
|
init = (t) => {
|
|
1341
|
-
|
|
1342
|
-
s !== void 0 && (this.decodingSpeed = s), e !== void 0 && (this.frameTrack = e), i !== void 0 && (this.minFrameTrackCacheNum = i);
|
|
1354
|
+
this.destroy(), this.pattern = t, this.baseTime = (/* @__PURE__ */ new Date()).getTime() - performance.now(), this.initDecodeInterval();
|
|
1343
1355
|
};
|
|
1344
1356
|
setFrameTrack = (t) => {
|
|
1345
1357
|
this.frameTrack = t, this.frameTrack === !1 && (this.decodingSpeedRatio = 1);
|
|
@@ -1347,37 +1359,41 @@ class it {
|
|
|
1347
1359
|
initDecodeInterval = () => {
|
|
1348
1360
|
let t = this.decodingSpeed / this.decodingSpeedRatio;
|
|
1349
1361
|
const s = this.baseTime + performance.now();
|
|
1350
|
-
if (this.nextRenderTime) {
|
|
1351
|
-
const e =
|
|
1362
|
+
if (this.lastRenderTime || (this.lastRenderTime = s), this.fps = Math.round(1e3 / (s - this.lastRenderTime)), this.lastRenderTime = s, this.nextRenderTime) {
|
|
1363
|
+
const e = this.lastRenderTime - this.nextRenderTime;
|
|
1352
1364
|
t -= e;
|
|
1353
1365
|
}
|
|
1354
|
-
this.nextRenderTime =
|
|
1366
|
+
this.nextRenderTime = this.lastRenderTime + t, this.decodeTimer = setTimeout(() => {
|
|
1355
1367
|
this.decode(), this.initDecodeInterval();
|
|
1356
1368
|
}, t);
|
|
1357
1369
|
};
|
|
1358
1370
|
decode = () => {
|
|
1359
1371
|
if (this.isProcessing !== !0) {
|
|
1360
1372
|
for (this.isProcessing = !0; ; ) {
|
|
1361
|
-
const t = this.pendingChunks.shift();
|
|
1373
|
+
const t = this.pendingChunks.shift(), s = this.pendingChunks.length;
|
|
1362
1374
|
if (this.frameTrack) {
|
|
1363
|
-
const
|
|
1364
|
-
if (
|
|
1365
|
-
const
|
|
1366
|
-
this.decodingSpeedRatio = Number(
|
|
1375
|
+
const [n, r] = this.fameTrackOption[this.pattern];
|
|
1376
|
+
if (s <= n && (this.isFrameTrack = !1), s >= r && (this.isFrameTrack = !0), this.isFrameTrack) {
|
|
1377
|
+
const a = Math.min(1 + (s - n) / 100, this.maxDecodingSpeedRatio);
|
|
1378
|
+
this.decodingSpeedRatio = Number(a.toFixed(1));
|
|
1367
1379
|
} else
|
|
1368
1380
|
this.decodingSpeedRatio = 1;
|
|
1369
1381
|
}
|
|
1382
|
+
if (this.on.debug) {
|
|
1383
|
+
const { decodingSpeed: n, decodingSpeedRatio: r, fps: a } = this;
|
|
1384
|
+
this.on.debug({ decodingSpeed: n, decodingSpeedRatio: r, fps: a });
|
|
1385
|
+
}
|
|
1370
1386
|
if (!t) break;
|
|
1371
|
-
const { type:
|
|
1372
|
-
switch (
|
|
1387
|
+
const { type: e, init: i } = t;
|
|
1388
|
+
switch (e) {
|
|
1373
1389
|
case "audio":
|
|
1374
|
-
this.decodeAudio(
|
|
1390
|
+
this.decodeAudio(i);
|
|
1375
1391
|
break;
|
|
1376
1392
|
case "video":
|
|
1377
|
-
this.decodeVideo(
|
|
1393
|
+
this.decodeVideo(i);
|
|
1378
1394
|
break;
|
|
1379
1395
|
}
|
|
1380
|
-
if (
|
|
1396
|
+
if (e === "video") break;
|
|
1381
1397
|
}
|
|
1382
1398
|
this.isProcessing = !1;
|
|
1383
1399
|
}
|
|
@@ -1388,7 +1404,7 @@ class it {
|
|
|
1388
1404
|
this.audioDecoder.decode(s);
|
|
1389
1405
|
};
|
|
1390
1406
|
decodeVideo = (t) => {
|
|
1391
|
-
if (this.videoDecoder && (t.type === "key" && (this.hasKeyFrame = !0), this.hasKeyFrame)) {
|
|
1407
|
+
if (this.videoDecoder && (t.type === "key" && (this.hasKeyFrame = !0), this.firstVideoChunkTimestamp ? this.secondVideoChunkTimestamp || (this.secondVideoChunkTimestamp = t.timestamp, this.decodingSpeed = (this.secondVideoChunkTimestamp - this.firstVideoChunkTimestamp) / 1e3) : this.firstVideoChunkTimestamp = t.timestamp, this.hasKeyFrame)) {
|
|
1392
1408
|
const s = new EncodedVideoChunk(t);
|
|
1393
1409
|
this.videoDecoder.decode(s);
|
|
1394
1410
|
}
|
|
@@ -1480,9 +1496,9 @@ class nt {
|
|
|
1480
1496
|
}
|
|
1481
1497
|
export {
|
|
1482
1498
|
it as Decoder,
|
|
1483
|
-
|
|
1499
|
+
N as DecoderWorker,
|
|
1484
1500
|
st as Demuxer,
|
|
1485
|
-
|
|
1501
|
+
F as DemuxerWorker,
|
|
1486
1502
|
et as PrPlayer,
|
|
1487
1503
|
nt as Render,
|
|
1488
1504
|
z as RenderWorker
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(U,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(U=typeof globalThis<"u"?globalThis:U||self,T(U["pr-player"]={}))})(this,(function(U){"use strict";const T='(function(){"use strict";class P{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const I=(y,t)=>{const s=new Uint8Array(y),e=new Uint8Array(t),n=new Uint8Array(11+s.length+e.length);let a=0;return n[a++]=1,n[a++]=s[1],n[a++]=s[2],n[a++]=s[3],n[a++]=255,n[a++]=225,n[a++]=s.length>>8&255,n[a++]=s.length&255,n.set(s,a),a+=s.length,n[a++]=1,n[a++]=e.length>>8&255,n[a++]=e.length&255,n.set(e,a),n},T=y=>{let t=0;const s=new DataView(y.buffer),e=s.getUint8(t);if(t=t+1,e!==1)throw new Error("Invalid AVC version");const n=s.getUint8(t)&255;t=t+1;const a=s.getUint8(t)&255;t=t+1;const o=s.getUint8(t)&255;t=t+1;const c=`avc1.${Array.from([n,a,o],U=>U.toString(16).padStart(2,"0")).join("")}`,r=(s.getUint8(t)&3)-1;t=t+1;const g=s.getUint8(t)&31;t=t+1;const p=s.getUint16(t,!1);t=t+2;const h=new Uint8Array(s.buffer.slice(t,t+p));t=t+p;const d=s.getUint8(t)&31;t=t+1;const u=s.getUint16(t,!1);t=t+2;const f=new Uint8Array(s.buffer.slice(t,t+u));return t=t+u,{version:e,codec:c,profile:n,compatibility:a,level:o,lengthSizeMinusOne:r,numOfSequenceParameterSets:g,sequenceParameterSetLength:p,sps:h,numOfPictureParameterSets:d,pictureParameterSetLength:u,pps:f}},M=y=>{const t=new Uint8Array(4+y.length);return new DataView(t.buffer).setUint32(0,y.length,!1),t.set(y,4),t},C=y=>{let t=0;for(const n of y)t+=n.length;const s=new Uint8Array(t);let e=0;for(const n of y){const a=n;s.set(a,e),e+=a.length}return s},D=y=>{let t="unknown";switch(y){case 1:case 2:case 27:case 36:t="video";break;case 3:case 4:case 15:t="audio";break;case 6:t="subtitle";break;case 134:t="ad";break}return t};class x{pat;pmt;audioConfig;videoConfig;payloadMap=new Map;on={};constructor(){}parse=async t=>{let s=0;for(;!(s+188>t.byteLength);){if(t.getInt8(s)!=71){s++;continue}await this.parsePacket(t,s),s+=188}return s};parsePacket=async(t,s)=>{if(s+188>t.byteLength)throw new Error("Invalid TS packet");if(t.getUint8(s)!==71)throw new Error("Invalid TS packet");let e=s;const n=this.parseHeader(t,e);e+=4;const{transport_error_indicator:a,pid:o,payload_unit_start_indicator:l,adaptation_field_control:i}=n;if(a===1||o===void 0)return;let c=184;if(i===2||i===3){const r=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=r,c-=r}if(i===3&&(c-=1),i===1||i===3){const r=new Uint8Array(t.buffer.slice(e,e+c));if(o===0)return this.parsePAT(t,e);{const{programs:h=[]}=this.pat||{};if(h.find(u=>u.pmt_pid===o))return this.parsePMT(t,e)}const{streams:g=[]}=this.pmt||{},p=g.find(h=>h.elementary_pid===o);if(p){if(l===1){const h=this.payloadMap.get(o);if(h){switch(p.kind){case"audio":{const d=await this.parseAudio(h);this.on.chunk&&this.on.chunk(d)}break;case"video":{const d=await this.parseVideo(h);this.on.chunk&&this.on.chunk(d),await new Promise(u=>setTimeout(()=>u(!0),0))}break}this.payloadMap.delete(o)}}{this.payloadMap.has(o)||this.payloadMap.set(o,new Uint8Array);const h=this.payloadMap.get(o),d=new Uint8Array(h.byteLength+r.byteLength);d.set(h,0),d.set(r,h.byteLength),this.payloadMap.set(o,d)}}}};parseHeader=(t,s)=>{let e=s;const n=t.getUint8(e),a=t.getUint8(e+1),o=t.getUint8(e+2),l=t.getUint8(e+3),i=(a&128)>>7;if(i===1)return{sync_byte:n,transport_error_indicator:i};const c=(a&64)>>6,r=(a&32)>>5,g=(a&31)<<8|o,p=(l&192)>>6,h=l>>4&3,d=l&15;return{sync_byte:n,transport_error_indicator:i,payload_unit_start_indicator:c,transport_priority:r,pid:g,transport_scrambling_control:p,adaptation_field_control:h,continuity_counter:d}};parsePAT=(t,s)=>{let e=s,n;{const l=t.getUint8(e);e+=1;const i=t.getUint8(e);if(e+=1,i!==0)throw new Error("Invalid PAT table_id");const c=t.getUint16(e)&4095;e+=2;const r=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const h=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1,n={pointer_field:l,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:h,last_section_number:d}}const a=[];{const l=n.section_length-5-4,i=e+l;for(;e<i;){const c=t.getUint16(e),r=t.getUint16(e+2)&8191;e+=4,c!==0&&r>=32&&r<=8190&&a.push({program_number:c,pmt_pid:r})}}const o=t.getUint32(e);this.pat={header:n,programs:a,crc32:o},this.on.debug&&this.on.debug({pat:this.pat})};parsePMT=(t,s)=>{let e=s,n;{const l=t.getUint8(e);e+=1;const i=t.getUint8(e);if(e+=1,i!==2)throw new Error("Invalid PMT table_id");const c=t.getUint16(e)&4095;e+=2;const r=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const h=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1;const u=t.getUint16(e)&8191;e+=2;const f=t.getUint16(e)&4095;e+=2,n={pointer_field:l,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:h,last_section_number:d,pcr_pid:u,program_info_length:f}}const a=[];{const l=n.section_length-9-4,i=e+l;for(;e<i;){const c=t.getUint8(e),r=D(c),g=t.getUint16(e+1)&8191,p=t.getUint16(e+3)&4095;if(e+=5,g<32||g>8190){console.warn(`Invalid elementary_pid: 0x${g.toString(16)}`);continue}a.push({kind:r,stream_type:c,elementary_pid:g,es_info_length:p})}}const o=t.getUint32(e);this.pmt={header:n,streams:a,crc32:o},this.on.debug&&this.on.debug({pmt:this.pmt})};parseAdaptationField=(t,s)=>{let e=s,n,a,o,l;const i=t.getUint8(e),c=!!(i&128),r=!!(i&64),g=!!(i&32),p=!!(i&16),h=!!(i&8),d=!!(i&4),u=!!(i&2),f=!!(i&1);e+=1;const U=(_,b)=>{let m=BigInt(0);m|=BigInt(_.getUint16(b))<<25n,m|=BigInt(_.getUint16(b+1))<<17n,m|=BigInt(_.getUint16(b+2))<<9n,m|=BigInt(_.getUint16(b+3))<<1n,m|=BigInt(_.getUint16(b+4)>>7);const S=(_.getUint16(b+4)&1)<<8|_.getUint16(b+5);return m=m*300n+BigInt(S),m};if(p&&(n=U(t,e),e+=6),h&&(a=U(t,e),e+=6),d&&(o=t.getInt8(e),e+=1),u){const _=t.getUint8(e);e+=1,l=new Uint8Array(t.buffer,e,_),e+=_}return{discontinuity_indicator:c,random_access_indicator:r,elementary_stream_priority_indicator:g,pcr_flag:p,opcr_flag:h,splicing_point_flag:d,transport_private_data_flag:u,adaptation_field_extension_flag:f,pcr:n,opcr:a,splice_countdown:o,transport_private_data:l}};parseAudio=async t=>{const s=new DataView(t.buffer);let e=0,n,a;{const o=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!o)throw new Error("invalid ts audio payload.");const l=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,h;{const f=s.getUint8(e);e+=1,c=f>>4&3,r=(f>>3&1)===1,g=(f>>2&1)===1,p=(f>>1&1)===1,h=(f&1)===1}let d,u;{const f=s.getUint8(e);e+=1;const U=f>>6,_=s.getUint8(e);e+=1,(U&2)===2&&(d=this.parsePtsDts(s,e)),(U&1)===1?u=this.parsePtsDts(s,e+5):u=d,e+=_}n={stream_id:l,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:h,pts:d,dts:u}}a=t.slice(e);{if(!this.audioConfig&&s.getUint8(e)===255){const g=s.getUint8(e+2),p=s.getUint8(e+3);let h,d;d=g>>2&15,h=(g&1)<<2|p>>6;const u=`mp4a.40.${h}`,U=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][d];this.audioConfig={kind:"audio",codec:u,sampleRate:U,numberOfChannels:h},this.on.config&&this.on.config(this.audioConfig)}const{dts:o=0,pts:l=0}=n,i=l-o,c=a.slice(7);return{kind:"audio",type:"key",dts:o,pts:l,cts:i,data:c}}};parseVideo=async t=>{const s=new DataView(t.buffer);let e=0,n,a;{const o=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!o)throw new Error("invalid ts video payload.");const l=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,h;{const f=s.getUint8(e);e+=1,c=f>>4&3,r=(f>>3&1)===1,g=(f>>2&1)===1,p=(f>>1&1)===1,h=(f&1)===1}let d,u;{const f=s.getUint8(e);e+=1;const U=f>>6,_=s.getUint8(e);e+=1,(U&2)===2&&(d=this.parsePtsDts(s,e)),(U&1)===1?u=this.parsePtsDts(s,e+5):u=d,e+=_}n={stream_id:l,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:h,pts:d,dts:u}}a=t.slice(e);{const o=this.getNalus(a);if(!this.videoConfig){let h,d;if(h=o.find(f=>f.type===7)?.nalu.slice(4),d=o.find(f=>f.type===8)?.nalu.slice(4),h&&d){const u=I(h,d),{codec:f}=T(u);this.videoConfig={kind:"video",codec:f,description:u,sps:h,pps:d},this.on.config&&this.on.config(this.videoConfig)}}const l=[];let i="delta";for(const h of o){const{type:d,nalu:u}=h;switch(d){case 6:case 9:l.push(u);break;case 1:i="delta",l.push(u);break;case 5:i="key",l.push(u);break}}const c=C(l),{dts:r=0,pts:g=0}=n,p=g-r;return{kind:"video",type:i,dts:r,pts:g,cts:p,data:c,nalus:l}}};parsePtsDts(t,s){const e=t.getUint8(s),n=t.getUint8(s+1),a=t.getUint8(s+2),o=t.getUint8(s+3),l=t.getUint8(s+4),i=(BigInt(e)&0b00001110n)<<29n|(BigInt(n)&0b11111111n)<<22n|(BigInt(a)&0b11111110n)<<14n|(BigInt(o)&0b11111111n)<<7n|(BigInt(l)&0b11111110n)>>1n;return Number(i)/90}getNalus=t=>{const s=[];let e=0;for(;!(e+4>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}e+=3;let n=e;const a=t[e]&31;for(e+=1;!(e+1>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}break}let o=e-n;if(t[e-1]===0&&(o-=1),o!==0){const l=t.slice(n,n+o),i=M(l);s.push({type:a,nalu:i})}}return s}}const k=(y,t)=>y.getUint8(t)<<16|y.getUint8(t+1)<<8|y.getUint8(t+2);class L{audioConfig;videoConfig;header;textDecoder=new TextDecoder("utf-8");on={};constructor(){}parse=async t=>{let s=0;for(this.header||(this.parseHeader(t,s),s+=9);this.isSurplusTag(t,s)!==!1;){const n=this.parseTagHeader(t,s+4),{tagType:a,dataSize:o,timestamp:l}=n;if(a){const i=this.parseTagBody(a,t,s+4+11,o);switch(a){case"script":this.on.info&&this.on.info(i);break;case"audio":{const{accPacketType:c}=i;if(c===0){const{codec:r,sampleRate:g,channelConfiguration:p}=i;this.audioConfig={kind:"audio",codec:r,sampleRate:g,numberOfChannels:p},this.on.config&&this.on.config(this.audioConfig)}else{const{cts:r,data:g}=i,p="key",h=r===void 0?void 0:r+l;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:l,pts:h,cts:r,data:g})}}break;case"video":{const{avcPacketType:c}=i;if(c===0){const{codec:r,sps:g,pps:p,data:h}=i;this.videoConfig={kind:"video",codec:r,description:h,sps:g,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:r,cts:g,data:p,nalus:h}=i,d=r===1?"key":"delta",u=g===void 0?void 0:g+l;this.on.chunk&&this.on.chunk({kind:"video",type:d,dts:l,pts:u,cts:g,data:p,nalus:h})}}break}s=s+4+11+o}await new Promise(i=>setTimeout(()=>i(!0),8))}return s};parseHeader=(t,s)=>{let e,n,a,o;e=t.getUint8(s)<<16|t.getUint8(s+1)<<8|t.getUint8(s+2),n=t.getUint8(3);{const i=t.getUint8(0).toString(2).padStart(5,"0").split(""),[,,c,,r]=i;a={audio:r==="1",video:c==="1"}}o=t.getUint32(5),this.header={signature:e,version:n,flags:a,dataOffset:o}};isSurplusTag=(t,s)=>{let e=!0;const n=t.byteLength;if(s+4>n)e=!1;else if(s+4+11>n)e=!1;else{const a=k(t,s+4+1);s+4+11+a>n&&(e=!1)}return e};parseTagHeader=(t,s)=>{let e,n,a,o,l;{const i=t.getUint8(s);let c;switch(i){case 18:c="script";break;case 8:c="audio";break;case 9:c="video";break}e=c}return n=k(t,s+1),a=k(t,s+4),o=t.getUint8(s+7),l=k(t,s+8),{tagType:e,dataSize:n,timestamp:a,timestampExtended:o,streamID:l}};parseTagBody=(t,s,e,n)=>{let a;switch(t){case"script":a=this.parseMetaData(s,e);break;case"audio":a=this.parseAudio(s,e,n);break;case"video":a=this.parseVideo(s,e,n);break}return a};parseMetaData=(t,s)=>{let e=s;{if(t.getUint8(e)!==2)throw new Error("Invalid AMF type for onMetaData (expected 0x02)");e=e+1}const n=t.getUint16(e,!1);e=e+2;{const l=new Int8Array(t.buffer.slice(e,e+n));if((this.textDecoder?.decode(l)||"")!=="onMetaData")throw new Error("Expected \'onMetaData\' string");e=e+n}const a=this.getAmfType(t,e);return e=e+1,this.getAMFValue(t,e,a).value};parseAudio=(t,s,e)=>{let n=s;const a=t.getUint8(n),o=a>>4&15,l=a>>2&3,i=a>>1&1,c=a&1;n=n+1;const r=t.getUint8(n);n=n+1;const g=e,p=new Uint8Array(t.buffer.slice(n,n+g));if(o===10&&r===0){const h=t.getUint8(n),d=t.getUint8(n+1),u=h>>3&31,f=(h&7)<<1|d>>7,U=d>>3&15,_=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],b=`mp4a.40.${u}`,m=_[f];return{soundFormat:o,soundRate:l,soundSize:i,soundType:c,accPacketType:r,data:p,samplingFrequencyIndex:f,channelConfiguration:U,codec:b,sampleRate:m}}return{soundFormat:o,soundRate:l,soundSize:i,soundType:c,accPacketType:r,data:p}};parseVideo=(t,s,e)=>{let n=s;const a=t.getUint8(n),o=a>>4&15,l=a&15;n=n+1;const i=t.getUint8(n);n=n+1;const c=k(t,n);n=n+3;const r=e-5,g=new Uint8Array(t.buffer.slice(n,n+r));switch(l){case 7:if(i===0){const p=T(g);return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g,...p}}else if(i===1){const p=[],h=n+e-5;for(;!(n+4>h);){const d=t.getUint32(n,!1),u=new Uint8Array(t.buffer.slice(n,n+4+d));n+=4+d,p.push(u)}return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g}};getAmfType=(t,s)=>t.getUint8(s);getAMFName=(t,s,e)=>{const n=new Uint8Array(t.buffer.slice(s,s+e));return this.textDecoder?.decode(n)||""};getAMFValue=(t,s,e)=>{let n=s,a,o=0;switch(e){case 0:a=t.getFloat64(n,!1),o=8;break;case 1:a=!!t.getUint8(n),o=1;break;case 2:{a="";const i=t.getUint16(n,!1);n=n+2;const c=new Int8Array(t.buffer,n,i).filter(g=>g!==0);a=(this.textDecoder?.decode(c)||"").trim(),o=2+i}break;case 3:for(a={};n<t.byteLength;){const i=t.getUint16(n,!1);if(i===0)break;n=n+2;const c=this.getAMFName(t,n,i);n=n+i;const r=this.getAmfType(t,n);if(r===6)break;n=n+1;const g=this.getAMFValue(t,n,r);n=n+g.length,a[c]=g.value,o=2+i+1+g.length}break;case 8:{a={};const i=t.getUint32(n,!1);n=n+4;for(let c=0;c<i;c++){const r=t.getUint16(n,!1);n=n+2;const g=this.getAMFName(t,n,r);n=n+r;const p=this.getAmfType(t,n);n=n+1;const h=this.getAMFValue(t,n,p);n=n+h.length,a[g]=h.value,o=2+r+1+h.length}}break;case 10:{a=[];const i=t.getUint32(n,!1);n=n+4;for(let c=0;c<i;c++){const r=this.getAmfType(t,n);n=n+1;const g=this.getAMFValue(t,n,r);n=n+g.length,a.push(g.value),o=1+g.length}}break}return{amfType:e,length:o,value:a}}}class O{pattern;cacher=new P;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new L;break;case"hls":this.parser=new x;break;default:throw new Error("is error pattern.")}this.parser.on.debug=s=>this.on.debug&&this.on.debug(s),this.parser.on.info=s=>this.on.info&&this.on.info(s),this.parser.on.config=s=>this.on.config&&this.on.config(s),this.parser.on.chunk=s=>{this.cacher.pushChunk(s),this.on.chunk&&this.on.chunk(s)}};push=t=>{this.cacher.push(t),this.isParseing===!1&&this.parse()};destroy=()=>{this.cacher.destroy(),this.isParseing=!1,this.offset=0};parse=async()=>{try{if(this.isParseing=!0,!this.pattern)throw new Error("You need to set the pattern.");if(!this.parser)throw new Error("You need to init parser.");for(;;){const t=this.cacher.next(this.offset);if(this.offset=0,!t)break;this.offset=await this.parser.parse(t)}this.isParseing=!1}catch{this.destroy()}}}const A=new O;A.on.debug=y=>postMessage({action:"onDebug",data:y}),A.on.info=y=>postMessage({action:"onInfo",data:y}),A.on.config=y=>postMessage({action:"onConfig",data:y}),A.on.chunk=y=>postMessage({action:"onChunk",data:y}),onmessage=y=>{const{action:t,data:s}=y.data,e=A[t];e&&e(s)}})();\n',x=typeof self<"u"&&self.Blob&&new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",T],{type:"text/javascript;charset=utf-8"});function B(l){let t;try{if(t=x&&(self.URL||self.webkitURL).createObjectURL(x),!t)throw"";const s=new Worker(t,{name:l?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(T),{name:l?.name})}}class A{worker=new B;on={};constructor(){this.worker.onmessage=t=>{const{action:s,data:e}=t.data;switch(s){case"onInfo":this.on.info&&this.on.info(e);break;case"onConfig":this.on.config&&this.on.config(e);break;case"onDebug":this.on.debug&&this.on.debug(e);break;case"onChunk":this.on.chunk&&this.on.chunk(e);break}}}init=t=>this.worker.postMessage({action:"init",data:t});push=t=>this.worker.postMessage({action:"push",data:t});destroy=()=>{this.worker.postMessage({action:"destroy",data:{}}),this.worker.terminate()}}const D=`(function(){"use strict";class n{audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];isProcessing=!1;decodeTimer=0;frameTrack=!1;minFrameTrackCacheNum=20;decodingSpeed=40;decodingSpeedRatio=1;maxDecodingSpeedRatio=2;nextRenderTime;on={audio:{},video:{}};constructor(){this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()}init=e=>{const{decodingSpeed:i,frameTrack:d,minFrameTrackCacheNum:o}=e;i!==void 0&&(this.decodingSpeed=i),d!==void 0&&(this.frameTrack=d),o!==void 0&&(this.minFrameTrackCacheNum=o)};setFrameTrack=e=>{this.frameTrack=e,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};initDecodeInterval=()=>{let e=this.decodingSpeed/this.decodingSpeedRatio;const i=this.baseTime+performance.now();if(this.nextRenderTime){const d=i-this.nextRenderTime;e-=d}this.nextRenderTime=i+e,this.decodeTimer=setTimeout(()=>{this.decode(),this.initDecodeInterval()},e)};decode=()=>{if(this.isProcessing!==!0){for(this.isProcessing=!0;;){const e=this.pendingChunks.shift();if(this.frameTrack){const o=this.pendingChunks.length;if(o>=this.minFrameTrackCacheNum){const r=Math.min(1+(o-this.minFrameTrackCacheNum)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(r.toFixed(1))}else this.decodingSpeedRatio=1}if(!e)break;const{type:i,init:d}=e;switch(i){case"audio":this.decodeAudio(d);break;case"video":this.decodeVideo(d);break}if(i==="video")break}this.isProcessing=!1}};decodeAudio=e=>{if(!this.audioDecoder)return;const i=new EncodedAudioChunk(e);this.audioDecoder.decode(i)};decodeVideo=e=>{if(this.videoDecoder&&(e.type==="key"&&(this.hasKeyFrame=!0),this.hasKeyFrame)){const i=new EncodedVideoChunk(e);this.videoDecoder.decode(i)}};destroy=()=>{this.audio.destroy(),this.video.destroy(),clearInterval(this.decodeTimer)};audio={init:e=>{this.audio.destroy(),this.audioDecoderConfig={...e},this.audioDecoder=new AudioDecoder({output:i=>{const d=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:i,playbackRate:d})},error:i=>{this.on.audio.error&&this.on.audio.error(i)}}),this.audioDecoder.configure(this.audioDecoderConfig)},push:e=>{this.pendingChunks.push({type:"audio",init:e})},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:e=>{this.video.destroy(),this.videoDecoderConfig={...e},this.videoDecoder=new VideoDecoder({output:async i=>{const d=i.timestamp+this.baseTime*1e3,o=await createImageBitmap(i);i.close(),o.width>0&&o.height>0?this.on.video.decode&&this.on.video.decode({timestamp:d,bitmap:o}):o.close()},error:i=>{this.on.video.error&&this.on.video.error(i)}}),this.videoDecoder.configure(this.videoDecoderConfig)},push:e=>{this.pendingChunks.push({type:"video",init:e})},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}const s=new n;s.on.audio.decode=t=>postMessage({type:"audio",action:"onDecode",data:t}),s.on.audio.error=t=>postMessage({type:"audio",action:"onError",data:t}),s.on.video.decode=t=>postMessage({type:"video",action:"onDecode",data:t}),s.on.video.error=t=>postMessage({type:"video",action:"onError",data:t}),onmessage=t=>{const{type:e,action:i,data:d}=t.data;if(e){const o=s[e][i];o&&o(d)}else{const o=s[i];o&&o(d)}}})();
|
|
2
|
-
`,
|
|
3
|
-
`,
|
|
4
|
-
`).map(c=>c.replace("\r","")),n=this.url.substring(0,this.url.lastIndexOf("/")+1);let r=4,a=0,o=!1;const d=[];for(const c of i)c.startsWith("#EXTINF:")?r=parseFloat(c.split(":")[1].split(",")[0]):c.startsWith("#EXT-X-TARGETDURATION:")?a=parseInt(c.split(":")[1]):c.startsWith("#EXT-X-ENDLIST")?o=!1:c.startsWith("#EXT-X-MEDIA-SEQUENCE:")?o=!0:c.includes(".ts")&&!c.startsWith("#")&&d.push({url:c.startsWith("http")?c:n+c,duration:r,isLive:o});return{baseUrl:n,targetDuration:a,isLive:o,segments:d}},getSegments:async()=>{try{const t=new F;let s=await t.request(this.url);if(s.status!==200&&(await new Promise(i=>setTimeout(()=>i(!0),500)),s=await t.request(this.url)),s.status!==200&&(await new Promise(i=>setTimeout(()=>i(!0),500)),s=await t.request(this.url)),s.status!==200)throw new Error("request is error.");const e=s.body?.getReader();if(!e)throw new Error("reader is error.");for(;;){const{done:i,value:n}=await e.read();if(n){const r=await this.hls.parse(n),{segments:a=[],isLive:o=!1}=r;this.hls.isLive=o,o===!1&&(this.option.frameTrack=!1);let d=Array.from(a,h=>h.url);const c=d.findIndex(h=>h===this.hls.url);c!==-1&&(d=d.slice(c+1)),this.hls.urls=d}if(i)break}}catch(t){this.on.error&&this.on.error(t)}},start:async()=>{try{for(await this.hls.getSegments(),this.hls.getSegmentsTimer=window.setInterval(this.hls.getSegments,500),this.hls.isLive===!1&&(clearInterval(this.hls.getSegmentsTimer),this.decoderWorker?.setFrameTrack(!1));;){const t=this.hls.urls.shift();if(t){this.hls.url=t;const e=(await this.prFetch.request(t)).body?.getReader();if(!e)throw new Error("segment reader is error.");for(;;){const{done:i,value:n}=await e.read();if(n&&this.demuxerWorker?.push(n),i)break}}else await new Promise(s=>setTimeout(()=>s(!0),300))}}catch(t){if(t?.name!=="AbortError")throw Error(t)}}}}class J{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const Z=l=>{let t="unknown";switch(l){case 1:case 2:case 27:case 36:t="video";break;case 3:case 4:case 15:t="audio";break;case 6:t="subtitle";break;case 134:t="ad";break}return t};class tt{pat;pmt;audioConfig;videoConfig;payloadMap=new Map;on={};constructor(){}parse=async t=>{let s=0;for(;!(s+188>t.byteLength);){if(t.getInt8(s)!=71){s++;continue}await this.parsePacket(t,s),s+=188}return s};parsePacket=async(t,s)=>{if(s+188>t.byteLength)throw new Error("Invalid TS packet");if(t.getUint8(s)!==71)throw new Error("Invalid TS packet");let e=s;const i=this.parseHeader(t,e);e+=4;const{transport_error_indicator:n,pid:r,payload_unit_start_indicator:a,adaptation_field_control:o}=i;if(n===1||r===void 0)return;let d=184;if(o===2||o===3){const c=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=c,d-=c}if(o===3&&(d-=1),o===1||o===3){const c=new Uint8Array(t.buffer.slice(e,e+d));if(r===0)return this.parsePAT(t,e);{const{programs:u=[]}=this.pat||{};if(u.find(f=>f.pmt_pid===r))return this.parsePMT(t,e)}const{streams:h=[]}=this.pmt||{},p=h.find(u=>u.elementary_pid===r);if(p){if(a===1){const u=this.payloadMap.get(r);if(u){switch(p.kind){case"audio":{const g=await this.parseAudio(u);this.on.chunk&&this.on.chunk(g)}break;case"video":{const g=await this.parseVideo(u);this.on.chunk&&this.on.chunk(g),await new Promise(f=>setTimeout(()=>f(!0),0))}break}this.payloadMap.delete(r)}}{this.payloadMap.has(r)||this.payloadMap.set(r,new Uint8Array);const u=this.payloadMap.get(r),g=new Uint8Array(u.byteLength+c.byteLength);g.set(u,0),g.set(c,u.byteLength),this.payloadMap.set(r,g)}}}};parseHeader=(t,s)=>{let e=s;const i=t.getUint8(e),n=t.getUint8(e+1),r=t.getUint8(e+2),a=t.getUint8(e+3),o=(n&128)>>7;if(o===1)return{sync_byte:i,transport_error_indicator:o};const d=(n&64)>>6,c=(n&32)>>5,h=(n&31)<<8|r,p=(a&192)>>6,u=a>>4&3,g=a&15;return{sync_byte:i,transport_error_indicator:o,payload_unit_start_indicator:d,transport_priority:c,pid:h,transport_scrambling_control:p,adaptation_field_control:u,continuity_counter:g}};parsePAT=(t,s)=>{let e=s,i;{const a=t.getUint8(e);e+=1;const o=t.getUint8(e);if(e+=1,o!==0)throw new Error("Invalid PAT table_id");const d=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const h=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const u=t.getUint8(e);e+=1;const g=t.getUint8(e);e+=1,i={pointer_field:a,table_id:o,section_length:d,transport_stream_id:c,version_number:h,current_next_indicator:p,section_number:u,last_section_number:g}}const n=[];{const a=i.section_length-5-4,o=e+a;for(;e<o;){const d=t.getUint16(e),c=t.getUint16(e+2)&8191;e+=4,d!==0&&c>=32&&c<=8190&&n.push({program_number:d,pmt_pid:c})}}const r=t.getUint32(e);this.pat={header:i,programs:n,crc32:r},this.on.debug&&this.on.debug({pat:this.pat})};parsePMT=(t,s)=>{let e=s,i;{const a=t.getUint8(e);e+=1;const o=t.getUint8(e);if(e+=1,o!==2)throw new Error("Invalid PMT table_id");const d=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const h=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const u=t.getUint8(e);e+=1;const g=t.getUint8(e);e+=1;const f=t.getUint16(e)&8191;e+=2;const y=t.getUint16(e)&4095;e+=2,i={pointer_field:a,table_id:o,section_length:d,transport_stream_id:c,version_number:h,current_next_indicator:p,section_number:u,last_section_number:g,pcr_pid:f,program_info_length:y}}const n=[];{const a=i.section_length-9-4,o=e+a;for(;e<o;){const d=t.getUint8(e),c=Z(d),h=t.getUint16(e+1)&8191,p=t.getUint16(e+3)&4095;if(e+=5,h<32||h>8190){console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);continue}n.push({kind:c,stream_type:d,elementary_pid:h,es_info_length:p})}}const r=t.getUint32(e);this.pmt={header:i,streams:n,crc32:r},this.on.debug&&this.on.debug({pmt:this.pmt})};parseAdaptationField=(t,s)=>{let e=s,i,n,r,a;const o=t.getUint8(e),d=!!(o&128),c=!!(o&64),h=!!(o&32),p=!!(o&16),u=!!(o&8),g=!!(o&4),f=!!(o&2),y=!!(o&1);e+=1;const b=(k,_)=>{let w=BigInt(0);w|=BigInt(k.getUint16(_))<<25n,w|=BigInt(k.getUint16(_+1))<<17n,w|=BigInt(k.getUint16(_+2))<<9n,w|=BigInt(k.getUint16(_+3))<<1n,w|=BigInt(k.getUint16(_+4)>>7);const ot=(k.getUint16(_+4)&1)<<8|k.getUint16(_+5);return w=w*300n+BigInt(ot),w};if(p&&(i=b(t,e),e+=6),u&&(n=b(t,e),e+=6),g&&(r=t.getInt8(e),e+=1),f){const k=t.getUint8(e);e+=1,a=new Uint8Array(t.buffer,e,k),e+=k}return{discontinuity_indicator:d,random_access_indicator:c,elementary_stream_priority_indicator:h,pcr_flag:p,opcr_flag:u,splicing_point_flag:g,transport_private_data_flag:f,adaptation_field_extension_flag:y,pcr:i,opcr:n,splice_countdown:r,transport_private_data:a}};parseAudio=async t=>{const s=new DataView(t.buffer);let e=0,i,n;{const r=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!r)throw new Error("invalid ts audio payload.");const a=s.getUint8(e);e+=1;const o=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let d,c,h,p,u;{const y=s.getUint8(e);e+=1,d=y>>4&3,c=(y>>3&1)===1,h=(y>>2&1)===1,p=(y>>1&1)===1,u=(y&1)===1}let g,f;{const y=s.getUint8(e);e+=1;const b=y>>6,k=s.getUint8(e);e+=1,(b&2)===2&&(g=this.parsePtsDts(s,e)),(b&1)===1?f=this.parsePtsDts(s,e+5):f=g,e+=k}i={stream_id:a,pes_packet_length:o,scrambling_control:d,priority:c,data_alignment:h,copyright:p,original_copy:u,pts:g,dts:f}}n=t.slice(e);{if(!this.audioConfig&&s.getUint8(e)===255){const h=s.getUint8(e+2),p=s.getUint8(e+3);let u,g;g=h>>2&15,u=(h&1)<<2|p>>6;const f=`mp4a.40.${u}`,b=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][g];this.audioConfig={kind:"audio",codec:f,sampleRate:b,numberOfChannels:u},this.on.config&&this.on.config(this.audioConfig)}const{dts:r=0,pts:a=0}=i,o=a-r,d=n.slice(7);return{kind:"audio",type:"key",dts:r,pts:a,cts:o,data:d}}};parseVideo=async t=>{const s=new DataView(t.buffer);let e=0,i,n;{const r=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!r)throw new Error("invalid ts video payload.");const a=s.getUint8(e);e+=1;const o=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let d,c,h,p,u;{const y=s.getUint8(e);e+=1,d=y>>4&3,c=(y>>3&1)===1,h=(y>>2&1)===1,p=(y>>1&1)===1,u=(y&1)===1}let g,f;{const y=s.getUint8(e);e+=1;const b=y>>6,k=s.getUint8(e);e+=1,(b&2)===2&&(g=this.parsePtsDts(s,e)),(b&1)===1?f=this.parsePtsDts(s,e+5):f=g,e+=k}i={stream_id:a,pes_packet_length:o,scrambling_control:d,priority:c,data_alignment:h,copyright:p,original_copy:u,pts:g,dts:f}}n=t.slice(e);{const r=this.getNalus(n);if(!this.videoConfig){let u,g;if(u=r.find(y=>y.type===7)?.nalu.slice(4),g=r.find(y=>y.type===8)?.nalu.slice(4),u&&g){const f=H(u,g),{codec:y}=N(f);this.videoConfig={kind:"video",codec:y,description:f,sps:u,pps:g},this.on.config&&this.on.config(this.videoConfig)}}const a=[];let o="delta";for(const u of r){const{type:g,nalu:f}=u;switch(g){case 6:case 9:a.push(f);break;case 1:o="delta",a.push(f);break;case 5:o="key",a.push(f);break}}const d=X(a),{dts:c=0,pts:h=0}=i,p=h-c;return{kind:"video",type:o,dts:c,pts:h,cts:p,data:d,nalus:a}}};parsePtsDts(t,s){const e=t.getUint8(s),i=t.getUint8(s+1),n=t.getUint8(s+2),r=t.getUint8(s+3),a=t.getUint8(s+4),o=(BigInt(e)&0b00001110n)<<29n|(BigInt(i)&0b11111111n)<<22n|(BigInt(n)&0b11111110n)<<14n|(BigInt(r)&0b11111111n)<<7n|(BigInt(a)&0b11111110n)>>1n;return Number(o)/90}getNalus=t=>{const s=[];let e=0;for(;!(e+4>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}e+=3;let i=e;const n=t[e]&31;for(e+=1;!(e+1>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}break}let r=e-i;if(t[e-1]===0&&(r-=1),r!==0){const a=t.slice(i,i+r),o=K(a);s.push({type:n,nalu:o})}}return s}}const v=(l,t)=>l.getUint8(t)<<16|l.getUint8(t+1)<<8|l.getUint8(t+2);class et{audioConfig;videoConfig;header;textDecoder=new TextDecoder("utf-8");on={};constructor(){}parse=async t=>{let s=0;for(this.header||(this.parseHeader(t,s),s+=9);this.isSurplusTag(t,s)!==!1;){const i=this.parseTagHeader(t,s+4),{tagType:n,dataSize:r,timestamp:a}=i;if(n){const o=this.parseTagBody(n,t,s+4+11,r);switch(n){case"script":this.on.info&&this.on.info(o);break;case"audio":{const{accPacketType:d}=o;if(d===0){const{codec:c,sampleRate:h,channelConfiguration:p}=o;this.audioConfig={kind:"audio",codec:c,sampleRate:h,numberOfChannels:p},this.on.config&&this.on.config(this.audioConfig)}else{const{cts:c,data:h}=o,p="key",u=c===void 0?void 0:c+a;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:a,pts:u,cts:c,data:h})}}break;case"video":{const{avcPacketType:d}=o;if(d===0){const{codec:c,sps:h,pps:p,data:u}=o;this.videoConfig={kind:"video",codec:c,description:u,sps:h,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:c,cts:h,data:p,nalus:u}=o,g=c===1?"key":"delta",f=h===void 0?void 0:h+a;this.on.chunk&&this.on.chunk({kind:"video",type:g,dts:a,pts:f,cts:h,data:p,nalus:u})}}break}s=s+4+11+r}await new Promise(o=>setTimeout(()=>o(!0),8))}return s};parseHeader=(t,s)=>{let e,i,n,r;e=t.getUint8(s)<<16|t.getUint8(s+1)<<8|t.getUint8(s+2),i=t.getUint8(3);{const o=t.getUint8(0).toString(2).padStart(5,"0").split(""),[,,d,,c]=o;n={audio:c==="1",video:d==="1"}}r=t.getUint32(5),this.header={signature:e,version:i,flags:n,dataOffset:r}};isSurplusTag=(t,s)=>{let e=!0;const i=t.byteLength;if(s+4>i)e=!1;else if(s+4+11>i)e=!1;else{const n=v(t,s+4+1);s+4+11+n>i&&(e=!1)}return e};parseTagHeader=(t,s)=>{let e,i,n,r,a;{const o=t.getUint8(s);let d;switch(o){case 18:d="script";break;case 8:d="audio";break;case 9:d="video";break}e=d}return i=v(t,s+1),n=v(t,s+4),r=t.getUint8(s+7),a=v(t,s+8),{tagType:e,dataSize:i,timestamp:n,timestampExtended:r,streamID:a}};parseTagBody=(t,s,e,i)=>{let n;switch(t){case"script":n=this.parseMetaData(s,e);break;case"audio":n=this.parseAudio(s,e,i);break;case"video":n=this.parseVideo(s,e,i);break}return n};parseMetaData=(t,s)=>{let e=s;{if(t.getUint8(e)!==2)throw new Error("Invalid AMF type for onMetaData (expected 0x02)");e=e+1}const i=t.getUint16(e,!1);e=e+2;{const a=new Int8Array(t.buffer.slice(e,e+i));if((this.textDecoder?.decode(a)||"")!=="onMetaData")throw new Error("Expected 'onMetaData' string");e=e+i}const n=this.getAmfType(t,e);return e=e+1,this.getAMFValue(t,e,n).value};parseAudio=(t,s,e)=>{let i=s;const n=t.getUint8(i),r=n>>4&15,a=n>>2&3,o=n>>1&1,d=n&1;i=i+1;const c=t.getUint8(i);i=i+1;const h=e,p=new Uint8Array(t.buffer.slice(i,i+h));if(r===10&&c===0){const u=t.getUint8(i),g=t.getUint8(i+1),f=u>>3&31,y=(u&7)<<1|g>>7,b=g>>3&15,k=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],_=`mp4a.40.${f}`,w=k[y];return{soundFormat:r,soundRate:a,soundSize:o,soundType:d,accPacketType:c,data:p,samplingFrequencyIndex:y,channelConfiguration:b,codec:_,sampleRate:w}}return{soundFormat:r,soundRate:a,soundSize:o,soundType:d,accPacketType:c,data:p}};parseVideo=(t,s,e)=>{let i=s;const n=t.getUint8(i),r=n>>4&15,a=n&15;i=i+1;const o=t.getUint8(i);i=i+1;const d=v(t,i);i=i+3;const c=e-5,h=new Uint8Array(t.buffer.slice(i,i+c));switch(a){case 7:if(o===0){const p=N(h);return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h,...p}}else if(o===1){const p=[],u=i+e-5;for(;!(i+4>u);){const g=t.getUint32(i,!1),f=new Uint8Array(t.buffer.slice(i,i+4+g));i+=4+g,p.push(f)}return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h}};getAmfType=(t,s)=>t.getUint8(s);getAMFName=(t,s,e)=>{const i=new Uint8Array(t.buffer.slice(s,s+e));return this.textDecoder?.decode(i)||""};getAMFValue=(t,s,e)=>{let i=s,n,r=0;switch(e){case 0:n=t.getFloat64(i,!1),r=8;break;case 1:n=!!t.getUint8(i),r=1;break;case 2:{n="";const o=t.getUint16(i,!1);i=i+2;const d=new Int8Array(t.buffer,i,o).filter(h=>h!==0);n=(this.textDecoder?.decode(d)||"").trim(),r=2+o}break;case 3:for(n={};i<t.byteLength;){const o=t.getUint16(i,!1);if(o===0)break;i=i+2;const d=this.getAMFName(t,i,o);i=i+o;const c=this.getAmfType(t,i);if(c===6)break;i=i+1;const h=this.getAMFValue(t,i,c);i=i+h.length,n[d]=h.value,r=2+o+1+h.length}break;case 8:{n={};const o=t.getUint32(i,!1);i=i+4;for(let d=0;d<o;d++){const c=t.getUint16(i,!1);i=i+2;const h=this.getAMFName(t,i,c);i=i+c;const p=this.getAmfType(t,i);i=i+1;const u=this.getAMFValue(t,i,p);i=i+u.length,n[h]=u.value,r=2+c+1+u.length}}break;case 10:{n=[];const o=t.getUint32(i,!1);i=i+4;for(let d=0;d<o;d++){const c=this.getAmfType(t,i);i=i+1;const h=this.getAMFValue(t,i,c);i=i+h.length,n.push(h.value),r=1+h.length}}break}return{amfType:e,length:r,value:n}}}class st{pattern;cacher=new J;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new et;break;case"hls":this.parser=new tt;break;default:throw new Error("is error pattern.")}this.parser.on.debug=s=>this.on.debug&&this.on.debug(s),this.parser.on.info=s=>this.on.info&&this.on.info(s),this.parser.on.config=s=>this.on.config&&this.on.config(s),this.parser.on.chunk=s=>{this.cacher.pushChunk(s),this.on.chunk&&this.on.chunk(s)}};push=t=>{this.cacher.push(t),this.isParseing===!1&&this.parse()};destroy=()=>{this.cacher.destroy(),this.isParseing=!1,this.offset=0};parse=async()=>{try{if(this.isParseing=!0,!this.pattern)throw new Error("You need to set the pattern.");if(!this.parser)throw new Error("You need to init parser.");for(;;){const t=this.cacher.next(this.offset);if(this.offset=0,!t)break;this.offset=await this.parser.parse(t)}this.isParseing=!1}catch{this.destroy()}}}class it{audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];isProcessing=!1;decodeTimer=0;frameTrack=!1;minFrameTrackCacheNum=20;decodingSpeed=40;decodingSpeedRatio=1;maxDecodingSpeedRatio=2;nextRenderTime;on={audio:{},video:{}};constructor(){this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()}init=t=>{const{decodingSpeed:s,frameTrack:e,minFrameTrackCacheNum:i}=t;s!==void 0&&(this.decodingSpeed=s),e!==void 0&&(this.frameTrack=e),i!==void 0&&(this.minFrameTrackCacheNum=i)};setFrameTrack=t=>{this.frameTrack=t,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};initDecodeInterval=()=>{let t=this.decodingSpeed/this.decodingSpeedRatio;const s=this.baseTime+performance.now();if(this.nextRenderTime){const e=s-this.nextRenderTime;t-=e}this.nextRenderTime=s+t,this.decodeTimer=setTimeout(()=>{this.decode(),this.initDecodeInterval()},t)};decode=()=>{if(this.isProcessing!==!0){for(this.isProcessing=!0;;){const t=this.pendingChunks.shift();if(this.frameTrack){const i=this.pendingChunks.length;if(i>=this.minFrameTrackCacheNum){const n=Math.min(1+(i-this.minFrameTrackCacheNum)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(n.toFixed(1))}else this.decodingSpeedRatio=1}if(!t)break;const{type:s,init:e}=t;switch(s){case"audio":this.decodeAudio(e);break;case"video":this.decodeVideo(e);break}if(s==="video")break}this.isProcessing=!1}};decodeAudio=t=>{if(!this.audioDecoder)return;const s=new EncodedAudioChunk(t);this.audioDecoder.decode(s)};decodeVideo=t=>{if(this.videoDecoder&&(t.type==="key"&&(this.hasKeyFrame=!0),this.hasKeyFrame)){const s=new EncodedVideoChunk(t);this.videoDecoder.decode(s)}};destroy=()=>{this.audio.destroy(),this.video.destroy(),clearInterval(this.decodeTimer)};audio={init:t=>{this.audio.destroy(),this.audioDecoderConfig={...t},this.audioDecoder=new AudioDecoder({output:s=>{const e=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:s,playbackRate:e})},error:s=>{this.on.audio.error&&this.on.audio.error(s)}}),this.audioDecoder.configure(this.audioDecoderConfig)},push:t=>{this.pendingChunks.push({type:"audio",init:t})},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:t=>{this.video.destroy(),this.videoDecoderConfig={...t},this.videoDecoder=new VideoDecoder({output:async s=>{const e=s.timestamp+this.baseTime*1e3,i=await createImageBitmap(s);s.close(),i.width>0&&i.height>0?this.on.video.decode&&this.on.video.decode({timestamp:e,bitmap:i}):i.close()},error:s=>{this.on.video.error&&this.on.video.error(s)}}),this.videoDecoder.configure(this.videoDecoderConfig)},push:t=>{this.pendingChunks.push({type:"video",init:t})},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}class nt{writable;writer;cutOption;pause=!1;constructor(){}init=({writable:t})=>{this.destroy(),this.writable=t,this.writer=this.writable.getWriter()};push=async t=>{if(this.pause)return;const{timestamp:s}=t;let{bitmap:e}=t;if(this.cutOption){const{sx:n=0,sy:r=0,sw:a=e.width,sh:o=e.height}=this.cutOption;e=await createImageBitmap(e,n,r,a,o)}const i=new VideoFrame(e,{timestamp:s});this.cutOption&&e.close(),this.writer.write(i),i.close()};setCut=t=>{this.cutOption=t};setPause=t=>{this.pause=t};destroy=()=>{this.writable=void 0,this.writer=void 0,this.cutOption=void 0}}U.Decoder=it,U.DecoderWorker=S,U.Demuxer=st,U.DemuxerWorker=A,U.PrPlayer=Q,U.Render=nt,U.RenderWorker=R,Object.defineProperty(U,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(U,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(U=typeof globalThis<"u"?globalThis:U||self,T(U["pr-player"]={}))})(this,(function(U){"use strict";const T='(function(){"use strict";class P{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const I=(y,t)=>{const s=new Uint8Array(y),e=new Uint8Array(t),n=new Uint8Array(11+s.length+e.length);let a=0;return n[a++]=1,n[a++]=s[1],n[a++]=s[2],n[a++]=s[3],n[a++]=255,n[a++]=225,n[a++]=s.length>>8&255,n[a++]=s.length&255,n.set(s,a),a+=s.length,n[a++]=1,n[a++]=e.length>>8&255,n[a++]=e.length&255,n.set(e,a),n},T=y=>{let t=0;const s=new DataView(y.buffer),e=s.getUint8(t);if(t=t+1,e!==1)throw new Error("Invalid AVC version");const n=s.getUint8(t)&255;t=t+1;const a=s.getUint8(t)&255;t=t+1;const o=s.getUint8(t)&255;t=t+1;const c=`avc1.${Array.from([n,a,o],U=>U.toString(16).padStart(2,"0")).join("")}`,r=(s.getUint8(t)&3)-1;t=t+1;const g=s.getUint8(t)&31;t=t+1;const p=s.getUint16(t,!1);t=t+2;const h=new Uint8Array(s.buffer.slice(t,t+p));t=t+p;const d=s.getUint8(t)&31;t=t+1;const u=s.getUint16(t,!1);t=t+2;const f=new Uint8Array(s.buffer.slice(t,t+u));return t=t+u,{version:e,codec:c,profile:n,compatibility:a,level:o,lengthSizeMinusOne:r,numOfSequenceParameterSets:g,sequenceParameterSetLength:p,sps:h,numOfPictureParameterSets:d,pictureParameterSetLength:u,pps:f}},M=y=>{const t=new Uint8Array(4+y.length);return new DataView(t.buffer).setUint32(0,y.length,!1),t.set(y,4),t},C=y=>{let t=0;for(const n of y)t+=n.length;const s=new Uint8Array(t);let e=0;for(const n of y){const a=n;s.set(a,e),e+=a.length}return s},D=y=>{let t="unknown";switch(y){case 1:case 2:case 27:case 36:t="video";break;case 3:case 4:case 15:t="audio";break;case 6:t="subtitle";break;case 134:t="ad";break}return t};class x{pat;pmt;audioConfig;videoConfig;payloadMap=new Map;on={};constructor(){}parse=async t=>{let s=0;for(;!(s+188>t.byteLength);){if(t.getInt8(s)!=71){s++;continue}await this.parsePacket(t,s),s+=188}return s};parsePacket=async(t,s)=>{if(s+188>t.byteLength)throw new Error("Invalid TS packet");if(t.getUint8(s)!==71)throw new Error("Invalid TS packet");let e=s;const n=this.parseHeader(t,e);e+=4;const{transport_error_indicator:a,pid:o,payload_unit_start_indicator:l,adaptation_field_control:i}=n;if(a===1||o===void 0)return;let c=184;if(i===2||i===3){const r=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=r,c-=r}if(i===3&&(c-=1),i===1||i===3){const r=new Uint8Array(t.buffer.slice(e,e+c));if(o===0)return this.parsePAT(t,e);{const{programs:h=[]}=this.pat||{};if(h.find(u=>u.pmt_pid===o))return this.parsePMT(t,e)}const{streams:g=[]}=this.pmt||{},p=g.find(h=>h.elementary_pid===o);if(p){if(l===1){const h=this.payloadMap.get(o);if(h){switch(p.kind){case"audio":{const d=await this.parseAudio(h);this.on.chunk&&this.on.chunk(d)}break;case"video":{const d=await this.parseVideo(h);this.on.chunk&&this.on.chunk(d),await new Promise(u=>setTimeout(()=>u(!0),0))}break}this.payloadMap.delete(o)}}{this.payloadMap.has(o)||this.payloadMap.set(o,new Uint8Array);const h=this.payloadMap.get(o),d=new Uint8Array(h.byteLength+r.byteLength);d.set(h,0),d.set(r,h.byteLength),this.payloadMap.set(o,d)}}}};parseHeader=(t,s)=>{let e=s;const n=t.getUint8(e),a=t.getUint8(e+1),o=t.getUint8(e+2),l=t.getUint8(e+3),i=(a&128)>>7;if(i===1)return{sync_byte:n,transport_error_indicator:i};const c=(a&64)>>6,r=(a&32)>>5,g=(a&31)<<8|o,p=(l&192)>>6,h=l>>4&3,d=l&15;return{sync_byte:n,transport_error_indicator:i,payload_unit_start_indicator:c,transport_priority:r,pid:g,transport_scrambling_control:p,adaptation_field_control:h,continuity_counter:d}};parsePAT=(t,s)=>{let e=s,n;{const l=t.getUint8(e);e+=1;const i=t.getUint8(e);if(e+=1,i!==0)throw new Error("Invalid PAT table_id");const c=t.getUint16(e)&4095;e+=2;const r=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const h=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1,n={pointer_field:l,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:h,last_section_number:d}}const a=[];{const l=n.section_length-5-4,i=e+l;for(;e<i;){const c=t.getUint16(e),r=t.getUint16(e+2)&8191;e+=4,c!==0&&r>=32&&r<=8190&&a.push({program_number:c,pmt_pid:r})}}const o=t.getUint32(e);this.pat={header:n,programs:a,crc32:o},this.on.debug&&this.on.debug({pat:this.pat})};parsePMT=(t,s)=>{let e=s,n;{const l=t.getUint8(e);e+=1;const i=t.getUint8(e);if(e+=1,i!==2)throw new Error("Invalid PMT table_id");const c=t.getUint16(e)&4095;e+=2;const r=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const h=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1;const u=t.getUint16(e)&8191;e+=2;const f=t.getUint16(e)&4095;e+=2,n={pointer_field:l,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:h,last_section_number:d,pcr_pid:u,program_info_length:f}}const a=[];{const l=n.section_length-9-4,i=e+l;for(;e<i;){const c=t.getUint8(e),r=D(c),g=t.getUint16(e+1)&8191,p=t.getUint16(e+3)&4095;if(e+=5,g<32||g>8190){console.warn(`Invalid elementary_pid: 0x${g.toString(16)}`);continue}a.push({kind:r,stream_type:c,elementary_pid:g,es_info_length:p})}}const o=t.getUint32(e);this.pmt={header:n,streams:a,crc32:o},this.on.debug&&this.on.debug({pmt:this.pmt})};parseAdaptationField=(t,s)=>{let e=s,n,a,o,l;const i=t.getUint8(e),c=!!(i&128),r=!!(i&64),g=!!(i&32),p=!!(i&16),h=!!(i&8),d=!!(i&4),u=!!(i&2),f=!!(i&1);e+=1;const U=(_,b)=>{let m=BigInt(0);m|=BigInt(_.getUint16(b))<<25n,m|=BigInt(_.getUint16(b+1))<<17n,m|=BigInt(_.getUint16(b+2))<<9n,m|=BigInt(_.getUint16(b+3))<<1n,m|=BigInt(_.getUint16(b+4)>>7);const S=(_.getUint16(b+4)&1)<<8|_.getUint16(b+5);return m=m*300n+BigInt(S),m};if(p&&(n=U(t,e),e+=6),h&&(a=U(t,e),e+=6),d&&(o=t.getInt8(e),e+=1),u){const _=t.getUint8(e);e+=1,l=new Uint8Array(t.buffer,e,_),e+=_}return{discontinuity_indicator:c,random_access_indicator:r,elementary_stream_priority_indicator:g,pcr_flag:p,opcr_flag:h,splicing_point_flag:d,transport_private_data_flag:u,adaptation_field_extension_flag:f,pcr:n,opcr:a,splice_countdown:o,transport_private_data:l}};parseAudio=async t=>{const s=new DataView(t.buffer);let e=0,n,a;{const o=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!o)throw new Error("invalid ts audio payload.");const l=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,h;{const f=s.getUint8(e);e+=1,c=f>>4&3,r=(f>>3&1)===1,g=(f>>2&1)===1,p=(f>>1&1)===1,h=(f&1)===1}let d,u;{const f=s.getUint8(e);e+=1;const U=f>>6,_=s.getUint8(e);e+=1,(U&2)===2&&(d=this.parsePtsDts(s,e)),(U&1)===1?u=this.parsePtsDts(s,e+5):u=d,e+=_}n={stream_id:l,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:h,pts:d,dts:u}}a=t.slice(e);{if(!this.audioConfig&&s.getUint8(e)===255){const g=s.getUint8(e+2),p=s.getUint8(e+3);let h,d;d=g>>2&15,h=(g&1)<<2|p>>6;const u=`mp4a.40.${h}`,U=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][d];this.audioConfig={kind:"audio",codec:u,sampleRate:U,numberOfChannels:h},this.on.config&&this.on.config(this.audioConfig)}const{dts:o=0,pts:l=0}=n,i=l-o,c=a.slice(7);return{kind:"audio",type:"key",dts:o,pts:l,cts:i,data:c}}};parseVideo=async t=>{const s=new DataView(t.buffer);let e=0,n,a;{const o=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!o)throw new Error("invalid ts video payload.");const l=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,h;{const f=s.getUint8(e);e+=1,c=f>>4&3,r=(f>>3&1)===1,g=(f>>2&1)===1,p=(f>>1&1)===1,h=(f&1)===1}let d,u;{const f=s.getUint8(e);e+=1;const U=f>>6,_=s.getUint8(e);e+=1,(U&2)===2&&(d=this.parsePtsDts(s,e)),(U&1)===1?u=this.parsePtsDts(s,e+5):u=d,e+=_}n={stream_id:l,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:h,pts:d,dts:u}}a=t.slice(e);{const o=this.getNalus(a);if(!this.videoConfig){let h,d;if(h=o.find(f=>f.type===7)?.nalu.slice(4),d=o.find(f=>f.type===8)?.nalu.slice(4),h&&d){const u=I(h,d),{codec:f}=T(u);this.videoConfig={kind:"video",codec:f,description:u,sps:h,pps:d},this.on.config&&this.on.config(this.videoConfig)}}const l=[];let i="delta";for(const h of o){const{type:d,nalu:u}=h;switch(d){case 6:case 9:l.push(u);break;case 1:i="delta",l.push(u);break;case 5:i="key",l.push(u);break}}const c=C(l),{dts:r=0,pts:g=0}=n,p=g-r;return{kind:"video",type:i,dts:r,pts:g,cts:p,data:c,nalus:l}}};parsePtsDts(t,s){const e=t.getUint8(s),n=t.getUint8(s+1),a=t.getUint8(s+2),o=t.getUint8(s+3),l=t.getUint8(s+4),i=(BigInt(e)&0b00001110n)<<29n|(BigInt(n)&0b11111111n)<<22n|(BigInt(a)&0b11111110n)<<14n|(BigInt(o)&0b11111111n)<<7n|(BigInt(l)&0b11111110n)>>1n;return Number(i)/90}getNalus=t=>{const s=[];let e=0;for(;!(e+4>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}e+=3;let n=e;const a=t[e]&31;for(e+=1;!(e+1>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}break}let o=e-n;if(t[e-1]===0&&(o-=1),o!==0){const l=t.slice(n,n+o),i=M(l);s.push({type:a,nalu:i})}}return s}}const k=(y,t)=>y.getUint8(t)<<16|y.getUint8(t+1)<<8|y.getUint8(t+2);class L{audioConfig;videoConfig;header;textDecoder=new TextDecoder("utf-8");on={};constructor(){}parse=async t=>{let s=0;for(this.header||(this.parseHeader(t,s),s+=9);this.isSurplusTag(t,s)!==!1;){const n=this.parseTagHeader(t,s+4),{tagType:a,dataSize:o,timestamp:l}=n;if(a){const i=this.parseTagBody(a,t,s+4+11,o);switch(a){case"script":this.on.info&&this.on.info(i);break;case"audio":{const{accPacketType:c}=i;if(c===0){const{codec:r,sampleRate:g,channelConfiguration:p}=i;this.audioConfig={kind:"audio",codec:r,sampleRate:g,numberOfChannels:p},this.on.config&&this.on.config(this.audioConfig)}else{const{cts:r,data:g}=i,p="key",h=r===void 0?void 0:r+l;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:l,pts:h,cts:r,data:g})}}break;case"video":{const{avcPacketType:c}=i;if(c===0){const{codec:r,sps:g,pps:p,data:h}=i;this.videoConfig={kind:"video",codec:r,description:h,sps:g,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:r,cts:g,data:p,nalus:h}=i,d=r===1?"key":"delta",u=g===void 0?void 0:g+l;this.on.chunk&&this.on.chunk({kind:"video",type:d,dts:l,pts:u,cts:g,data:p,nalus:h})}}break}s=s+4+11+o}await new Promise(i=>setTimeout(()=>i(!0),8))}return s};parseHeader=(t,s)=>{let e,n,a,o;e=t.getUint8(s)<<16|t.getUint8(s+1)<<8|t.getUint8(s+2),n=t.getUint8(3);{const i=t.getUint8(0).toString(2).padStart(5,"0").split(""),[,,c,,r]=i;a={audio:r==="1",video:c==="1"}}o=t.getUint32(5),this.header={signature:e,version:n,flags:a,dataOffset:o}};isSurplusTag=(t,s)=>{let e=!0;const n=t.byteLength;if(s+4>n)e=!1;else if(s+4+11>n)e=!1;else{const a=k(t,s+4+1);s+4+11+a>n&&(e=!1)}return e};parseTagHeader=(t,s)=>{let e,n,a,o,l;{const i=t.getUint8(s);let c;switch(i){case 18:c="script";break;case 8:c="audio";break;case 9:c="video";break}e=c}return n=k(t,s+1),a=k(t,s+4),o=t.getUint8(s+7),l=k(t,s+8),{tagType:e,dataSize:n,timestamp:a,timestampExtended:o,streamID:l}};parseTagBody=(t,s,e,n)=>{let a;switch(t){case"script":a=this.parseMetaData(s,e);break;case"audio":a=this.parseAudio(s,e,n);break;case"video":a=this.parseVideo(s,e,n);break}return a};parseMetaData=(t,s)=>{let e=s;{if(t.getUint8(e)!==2)throw new Error("Invalid AMF type for onMetaData (expected 0x02)");e=e+1}const n=t.getUint16(e,!1);e=e+2;{const l=new Int8Array(t.buffer.slice(e,e+n));if((this.textDecoder?.decode(l)||"")!=="onMetaData")throw new Error("Expected \'onMetaData\' string");e=e+n}const a=this.getAmfType(t,e);return e=e+1,this.getAMFValue(t,e,a).value};parseAudio=(t,s,e)=>{let n=s;const a=t.getUint8(n),o=a>>4&15,l=a>>2&3,i=a>>1&1,c=a&1;n=n+1;const r=t.getUint8(n);n=n+1;const g=e,p=new Uint8Array(t.buffer.slice(n,n+g));if(o===10&&r===0){const h=t.getUint8(n),d=t.getUint8(n+1),u=h>>3&31,f=(h&7)<<1|d>>7,U=d>>3&15,_=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],b=`mp4a.40.${u}`,m=_[f];return{soundFormat:o,soundRate:l,soundSize:i,soundType:c,accPacketType:r,data:p,samplingFrequencyIndex:f,channelConfiguration:U,codec:b,sampleRate:m}}return{soundFormat:o,soundRate:l,soundSize:i,soundType:c,accPacketType:r,data:p}};parseVideo=(t,s,e)=>{let n=s;const a=t.getUint8(n),o=a>>4&15,l=a&15;n=n+1;const i=t.getUint8(n);n=n+1;const c=k(t,n);n=n+3;const r=e-5,g=new Uint8Array(t.buffer.slice(n,n+r));switch(l){case 7:if(i===0){const p=T(g);return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g,...p}}else if(i===1){const p=[],h=n+e-5;for(;!(n+4>h);){const d=t.getUint32(n,!1),u=new Uint8Array(t.buffer.slice(n,n+4+d));n+=4+d,p.push(u)}return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:o,codecID:l,avcPacketType:i,cts:c,data:g}};getAmfType=(t,s)=>t.getUint8(s);getAMFName=(t,s,e)=>{const n=new Uint8Array(t.buffer.slice(s,s+e));return this.textDecoder?.decode(n)||""};getAMFValue=(t,s,e)=>{let n=s,a,o=0;switch(e){case 0:a=t.getFloat64(n,!1),o=8;break;case 1:a=!!t.getUint8(n),o=1;break;case 2:{a="";const i=t.getUint16(n,!1);n=n+2;const c=new Int8Array(t.buffer,n,i).filter(g=>g!==0);a=(this.textDecoder?.decode(c)||"").trim(),o=2+i}break;case 3:for(a={};n<t.byteLength;){const i=t.getUint16(n,!1);if(i===0)break;n=n+2;const c=this.getAMFName(t,n,i);n=n+i;const r=this.getAmfType(t,n);if(r===6)break;n=n+1;const g=this.getAMFValue(t,n,r);n=n+g.length,a[c]=g.value,o=2+i+1+g.length}break;case 8:{a={};const i=t.getUint32(n,!1);n=n+4;for(let c=0;c<i;c++){const r=t.getUint16(n,!1);n=n+2;const g=this.getAMFName(t,n,r);n=n+r;const p=this.getAmfType(t,n);n=n+1;const h=this.getAMFValue(t,n,p);n=n+h.length,a[g]=h.value,o=2+r+1+h.length}}break;case 10:{a=[];const i=t.getUint32(n,!1);n=n+4;for(let c=0;c<i;c++){const r=this.getAmfType(t,n);n=n+1;const g=this.getAMFValue(t,n,r);n=n+g.length,a.push(g.value),o=1+g.length}}break}return{amfType:e,length:o,value:a}}}class O{pattern;cacher=new P;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new L;break;case"hls":this.parser=new x;break;default:throw new Error("is error pattern.")}this.parser.on.debug=s=>this.on.debug&&this.on.debug(s),this.parser.on.info=s=>this.on.info&&this.on.info(s),this.parser.on.config=s=>this.on.config&&this.on.config(s),this.parser.on.chunk=s=>{this.cacher.pushChunk(s),this.on.chunk&&this.on.chunk(s)}};push=t=>{this.cacher.push(t),this.isParseing===!1&&this.parse()};destroy=()=>{this.cacher.destroy(),this.isParseing=!1,this.offset=0};parse=async()=>{try{if(this.isParseing=!0,!this.pattern)throw new Error("You need to set the pattern.");if(!this.parser)throw new Error("You need to init parser.");for(;;){const t=this.cacher.next(this.offset);if(this.offset=0,!t)break;this.offset=await this.parser.parse(t)}this.isParseing=!1}catch{this.destroy()}}}const A=new O;A.on.debug=y=>postMessage({action:"onDebug",data:y}),A.on.info=y=>postMessage({action:"onInfo",data:y}),A.on.config=y=>postMessage({action:"onConfig",data:y}),A.on.chunk=y=>postMessage({action:"onChunk",data:y}),onmessage=y=>{const{action:t,data:s}=y.data,e=A[t];e&&e(s)}})();\n',x=typeof self<"u"&&self.Blob&&new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",T],{type:"text/javascript;charset=utf-8"});function N(l){let t;try{if(t=x&&(self.URL||self.webkitURL).createObjectURL(x),!t)throw"";const s=new Worker(t,{name:l?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(T),{name:l?.name})}}class A{worker=new N;on={};constructor(){this.worker.onmessage=t=>{const{action:s,data:e}=t.data;switch(s){case"onInfo":this.on.info&&this.on.info(e);break;case"onConfig":this.on.config&&this.on.config(e);break;case"onDebug":this.on.debug&&this.on.debug(e);break;case"onChunk":this.on.chunk&&this.on.chunk(e);break}}}init=t=>this.worker.postMessage({action:"init",data:t});push=t=>this.worker.postMessage({action:"push",data:t});destroy=()=>{this.worker.postMessage({action:"destroy",data:{}}),this.worker.terminate()}}const C=`(function(){"use strict";class c{pattern="flv";audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];isProcessing=!1;decodeTimer=0;frameTrack=!1;isFrameTrack=!1;fameTrackOption={flv:[20,50],hls:[200,300],dash:[50,100],rtmp:[50,100]};decodingSpeed=16;fps=0;firstVideoChunkTimestamp;secondVideoChunkTimestamp;decodingSpeedRatio=1;maxDecodingSpeedRatio=2;lastRenderTime;nextRenderTime;on={audio:{},video:{}};constructor(){}init=e=>{this.destroy(),this.pattern=e,this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()};setFrameTrack=e=>{this.frameTrack=e,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};initDecodeInterval=()=>{let e=this.decodingSpeed/this.decodingSpeedRatio;const i=this.baseTime+performance.now();if(this.lastRenderTime||(this.lastRenderTime=i),this.fps=Math.round(1e3/(i-this.lastRenderTime)),this.lastRenderTime=i,this.nextRenderTime){const t=this.lastRenderTime-this.nextRenderTime;e-=t}this.nextRenderTime=this.lastRenderTime+e,this.decodeTimer=setTimeout(()=>{this.decode(),this.initDecodeInterval()},e)};decode=()=>{if(this.isProcessing!==!0){for(this.isProcessing=!0;;){const e=this.pendingChunks.shift(),i=this.pendingChunks.length;if(this.frameTrack){const[n,r]=this.fameTrackOption[this.pattern];if(i<=n&&(this.isFrameTrack=!1),i>=r&&(this.isFrameTrack=!0),this.isFrameTrack){const a=Math.min(1+(i-n)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(a.toFixed(1))}else this.decodingSpeedRatio=1}if(this.on.debug){const{decodingSpeed:n,decodingSpeedRatio:r,fps:a}=this;this.on.debug({decodingSpeed:n,decodingSpeedRatio:r,fps:a})}if(!e)break;const{type:t,init:o}=e;switch(t){case"audio":this.decodeAudio(o);break;case"video":this.decodeVideo(o);break}if(t==="video")break}this.isProcessing=!1}};decodeAudio=e=>{if(!this.audioDecoder)return;const i=new EncodedAudioChunk(e);this.audioDecoder.decode(i)};decodeVideo=e=>{if(this.videoDecoder&&(e.type==="key"&&(this.hasKeyFrame=!0),this.firstVideoChunkTimestamp?this.secondVideoChunkTimestamp||(this.secondVideoChunkTimestamp=e.timestamp,this.decodingSpeed=(this.secondVideoChunkTimestamp-this.firstVideoChunkTimestamp)/1e3):this.firstVideoChunkTimestamp=e.timestamp,this.hasKeyFrame)){const i=new EncodedVideoChunk(e);this.videoDecoder.decode(i)}};destroy=()=>{this.audio.destroy(),this.video.destroy(),clearInterval(this.decodeTimer)};audio={init:e=>{this.audio.destroy(),this.audioDecoderConfig={...e},this.audioDecoder=new AudioDecoder({output:i=>{const t=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:i,playbackRate:t})},error:i=>{this.on.audio.error&&this.on.audio.error(i)}}),this.audioDecoder.configure(this.audioDecoderConfig)},push:e=>{this.pendingChunks.push({type:"audio",init:e})},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:e=>{this.video.destroy(),this.videoDecoderConfig={...e},this.videoDecoder=new VideoDecoder({output:async i=>{const t=i.timestamp+this.baseTime*1e3,o=await createImageBitmap(i);i.close(),o.width>0&&o.height>0?this.on.video.decode&&this.on.video.decode({timestamp:t,bitmap:o}):o.close()},error:i=>{this.on.video.error&&this.on.video.error(i)}}),this.videoDecoder.configure(this.videoDecoderConfig)},push:e=>{this.pendingChunks.push({type:"video",init:e})},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}const d=new c;d.on.audio.decode=s=>postMessage({type:"audio",action:"onDecode",data:s}),d.on.audio.error=s=>postMessage({type:"audio",action:"onError",data:s}),d.on.video.decode=s=>postMessage({type:"video",action:"onDecode",data:s}),d.on.video.error=s=>postMessage({type:"video",action:"onError",data:s}),onmessage=s=>{const{type:e,action:i,data:t}=s.data;if(e){const o=d[e][i];o&&o(t)}else{const o=d[i];o&&o(t)}}})();
|
|
2
|
+
`,D=typeof self<"u"&&self.Blob&&new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",C],{type:"text/javascript;charset=utf-8"});function B(l){let t;try{if(t=D&&(self.URL||self.webkitURL).createObjectURL(D),!t)throw"";const s=new Worker(t,{name:l?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(C),{name:l?.name})}}class S{worker=new B;on={audio:{},video:{}};constructor(){this.worker.onmessage=t=>{const{type:s,action:e,data:i}=t.data;switch(s){case"audio":e==="onDecode"&&this.on.audio.decode&&this.on.audio.decode(i),e==="onError"&&this.on.audio.error&&this.on.audio.error(i);break;case"video":e==="onDecode"&&this.on.video.decode&&this.on.video.decode(i),e==="onError"&&this.on.video.error&&this.on.video.error(i);break}}}init=t=>this.worker.postMessage({action:"init",data:t});setFrameTrack=t=>this.worker.postMessage({action:"setFrameTrack",data:t});audio={init:t=>this.worker.postMessage({type:"audio",action:"init",data:t}),push:t=>this.worker.postMessage({type:"audio",action:"push",data:t}),flush:()=>this.worker.postMessage({type:"audio",action:"flush"}),destroy:()=>{this.worker.postMessage({type:"audio",action:"destroy"})}};video={init:t=>this.worker.postMessage({type:"video",action:"init",data:t}),push:t=>this.worker.postMessage({type:"video",action:"push",data:t}),flush:()=>this.worker.postMessage({type:"video",action:"flush"}),destroy:()=>{this.worker.postMessage({type:"video",action:"destroy",data:{}})}};destroy=()=>{this.worker.postMessage({action:"destroy"}),this.worker.terminate()}}var E=Object.defineProperty,G=(l,t,s)=>t in l?E(l,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):l[t]=s,m=(l,t,s)=>G(l,typeof t!="symbol"?t+"":t,s);class O{constructor(t,s){m(this,"inputStream",new MediaStream),m(this,"outputStream",new MediaStream),m(this,"inputGain",1),m(this,"enhanceGain",1),m(this,"bgsGain",1),m(this,"bgmGain",1),m(this,"outputGain",1),m(this,"mixAudioMap",new Map),m(this,"audioContext",new AudioContext),m(this,"sourceNode"),m(this,"inputGainNode"),m(this,"enhanceGainNode"),m(this,"bgsGainNode"),m(this,"bgmGainNode"),m(this,"analyserNode"),m(this,"analyserArrayData"),m(this,"outputGainNode"),m(this,"destinationNode"),m(this,"filterStream",e=>e),m(this,"stop",()=>{{const e=this.inputStream.getTracks();for(const i of e)i.stop(),this.inputStream.removeTrack(i)}}),m(this,"getStream",()=>this.filterStream(this.outputStream)),m(this,"setMute",(e=!0)=>{e?this.analyserNode.disconnect(this.outputGainNode):this.analyserNode.connect(this.outputGainNode)}),m(this,"setInputGain",e=>{this.inputGain=e,this.inputGainNode.gain.setValueAtTime(e,this.audioContext.currentTime)}),m(this,"setEnhanceGain",async e=>{this.enhanceGain=e+1,this.enhanceGainNode.gain.setValueAtTime(this.enhanceGain,this.audioContext.currentTime)}),m(this,"setBgsGain",e=>{this.bgsGain=e,this.bgsGainNode.gain.setValueAtTime(e,this.audioContext.currentTime)}),m(this,"setBgmGain",e=>{this.bgmGain=e,this.bgmGainNode.gain.setValueAtTime(e,this.audioContext.currentTime)}),m(this,"setOutputGain",e=>{this.outputGain=e,this.outputGainNode.gain.setValueAtTime(this.outputGain,this.audioContext.currentTime)}),m(this,"getVolume",()=>{const{analyserNode:e,analyserArrayData:i}=this;e.getByteFrequencyData(i);let n=0;for(let r=0;r<i.length;r++)n+=i[r];return Math.ceil(n/i.length)}),m(this,"mixAudio",(e,i="bgm")=>new Promise(async(n,r)=>{try{{const d=this.mixAudioMap.get(i);d&&d.stop()}const a=i==="bgs"?this.bgsGainNode:this.bgmGainNode,o=this.audioContext.createBufferSource();this.mixAudioMap.set(i,o),o.buffer=e,o.connect(a),o.onended=()=>{o.disconnect(a),this.mixAudioMap.delete(i),n(!0)},o.start(0)}catch(a){r(a)}})),m(this,"mixAudioStop",e=>{const i=this.mixAudioMap.get(e);i?.stop()}),m(this,"changeMix",(e,i)=>{const n=e==="bgs"?this.bgsGainNode:this.bgmGainNode;i?n.connect(this.destinationNode):n.disconnect(this.destinationNode)}),s&&(this.audioContext=s),this.inputStream=t,this.sourceNode=this.audioContext.createMediaStreamSource(this.inputStream),this.inputGainNode=this.audioContext.createGain(),this.inputGainNode.gain.setValueAtTime(this.inputGain,this.audioContext.currentTime),this.enhanceGainNode=this.audioContext.createGain(),this.enhanceGainNode.gain.setValueAtTime(this.enhanceGain,this.audioContext.currentTime),this.bgsGainNode=this.audioContext.createGain(),this.bgsGainNode.gain.setValueAtTime(this.bgsGain,this.audioContext.currentTime),this.bgmGainNode=this.audioContext.createGain(),this.bgmGainNode.gain.setValueAtTime(this.bgmGain,this.audioContext.currentTime),this.analyserNode=this.audioContext.createAnalyser(),this.analyserNode.fftSize=512,this.analyserArrayData=new Uint8Array(this.analyserNode.frequencyBinCount),this.outputGainNode=this.audioContext.createGain(),this.outputGainNode.gain.setValueAtTime(this.outputGain,this.audioContext.currentTime),this.destinationNode=this.audioContext.createMediaStreamDestination(),this.outputStream=this.destinationNode.stream;{const{sourceNode:e,inputGainNode:i,enhanceGainNode:n,bgsGainNode:r,bgmGainNode:a,analyserNode:o,outputGainNode:d,destinationNode:c}=this;e.connect(i),i.connect(n),n.connect(o),r.connect(o),a.connect(o),n.connect(c),r.connect(c),a.connect(c),o.connect(d),d.connect(this.audioContext.destination)}this.setMute(!0),this.audioContext.resume()}}const W=async(l,t)=>{try{const{format:s,numberOfChannels:e,numberOfFrames:i,sampleRate:n}=t,r=l.createBuffer(e,i,n);for(let a=0;a<e;a++){const o=t.allocationSize({planeIndex:a}),d=new Uint8Array(o);t.copyTo(d,{planeIndex:a});const c=new DataView(d.buffer),h=r.getChannelData(a);for(let p=0;p<i;p++){let u;switch(s){case"s16":case"s16-planar":u=c.getInt16(p*2,!0)/32768;break;case"f32":case"f32-planar":u=c.getFloat32(p*4,!0);break;case"u8":case"u8-planar":u=(c.getUint8(p)-128)/128;break;default:throw new Error(`Unsupported audio format: ${s}`)}h[p]=Math.max(-1,Math.min(1,u))}}return r}catch(s){throw console.error("Failed to convert AudioData to AudioBuffer:",s),s}};class j{prAudioStream;audioContext;destination;stream=new MediaStream;nextStartTime=0;pendingSources=[];constructor(){}init=t=>{t||(t=new(window.AudioContext||window.webkitAudioContext)),this.audioContext=t,this.destination=this.audioContext.createMediaStreamDestination(),this.stream=new MediaStream,this.stream.addTrack(this.destination.stream.getAudioTracks()[0]),this.prAudioStream=new O(this.stream,this.audioContext),this.nextStartTime=0,this.pendingSources=[]};async push(t){const{audioData:s,playbackRate:e=1}=t;try{if(!this.audioContext||!this.destination)return;let i=await W(this.audioContext,s);if(!i)return;const n=this.audioContext.createBufferSource();n.buffer=i,n.playbackRate.value=e;const r=-1200*Math.log2(e);n.detune.value=r,n.connect(this.destination);const a=Math.max(this.nextStartTime,this.audioContext.currentTime),o=i.duration/e;this.nextStartTime=a+o,n.start(a),this.pendingSources.push(n),n.onended=()=>{this.pendingSources=this.pendingSources.filter(d=>d!==n)},this.audioContext.state==="suspended"&&await this.audioContext.resume()}finally{s.close()}}getStream=()=>this.prAudioStream?.getStream();destroy(){this.audioContext?.close(),this.audioContext=void 0,this.destination=void 0,this.nextStartTime=0,this.prAudioStream?.stop(),this.pendingSources.forEach(t=>t.stop()),this.pendingSources=[]}}const M=`(function(){"use strict";class o{writable;writer;cutOption;pause=!1;constructor(){}init=({writable:t})=>{this.destroy(),this.writable=t,this.writer=this.writable.getWriter()};push=async t=>{if(this.pause)return;const{timestamp:s}=t;let{bitmap:i}=t;if(this.cutOption){const{sx:n=0,sy:c=0,sw:h=i.width,sh:u=i.height}=this.cutOption;i=await createImageBitmap(i,n,c,h,u)}const r=new VideoFrame(i,{timestamp:s});this.cutOption&&i.close(),this.writer.write(r),r.close()};setCut=t=>{this.cutOption=t};setPause=t=>{this.pause=t};destroy=()=>{this.writable=void 0,this.writer=void 0,this.cutOption=void 0}}const a=new o;onmessage=e=>{const{action:t,data:s}=e.data,i=a[t];i&&i(s)}})();
|
|
3
|
+
`,R=typeof self<"u"&&self.Blob&&new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",M],{type:"text/javascript;charset=utf-8"});function z(l){let t;try{if(t=R&&(self.URL||self.webkitURL).createObjectURL(R),!t)throw"";const s=new Worker(t,{name:l?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(M),{name:l?.name})}}class P{worker=new z;constructor(){}init=({writable:t})=>this.worker.postMessage({action:"init",data:{writable:t}},[t]);push=t=>this.worker.postMessage({action:"push",data:t});setCut=async t=>this.worker.postMessage({action:"setCut",data:t});setPause=t=>this.worker.postMessage({action:"setPause",data:t});destroy=()=>{this.worker.postMessage({action:"destroy",data:{}}),this.worker.terminate()}}const q=l=>{const t=l.toLowerCase();return t.includes(".m3u8")||t.includes("hls")||t.includes("master.m3u8")||t.match(/index\d*\.m3u8/)?"hls":t.includes(".mpd")||t.includes("dash")?"dash":t.startsWith("rtmp://")||t.startsWith("rtmps://")?"rtmp":t.includes(".flv")||t.includes("flv")&&!t.includes("flash")?"flv":"unknown"},I=l=>{const t=l?.getTracks()||[];for(const s of t)s.stop()},L=()=>{const l=new MediaStreamTrackGenerator({kind:"video"}),t=new MediaStream([l]),s=new P;return s.init({writable:l.writable}),{worker:s,stream:t,destroy:()=>{s.destroy(),I(t)}}};class ${resolvesMap=new Map;index=0;constructor(){}add=(t,s=()=>!1,e=0)=>new Promise(i=>{if(s())return i(!0);this.resolvesMap.has(t)||this.resolvesMap.set(t,new Map),this.index++;const a=`${this.index}`;if(e=Math.max(0,e),e===0){this.resolvesMap.get(t)?.set(a,{resolve:i,timer:0});return}const o=window.setTimeout(()=>{this.emit(t)},e);this.resolvesMap.get(t)?.set(a,{resolve:i,timer:o})});emit=async t=>{const s=this.resolvesMap.get(t);if(!s)return;const e=[...s.keys()];for(const i of e){const n=s.get(i);n&&(clearTimeout(n.timer),n.resolve(),s.delete(i))}}}const H=(l,t)=>{const s=new Uint8Array(l),e=new Uint8Array(t),i=new Uint8Array(11+s.length+e.length);let n=0;return i[n++]=1,i[n++]=s[1],i[n++]=s[2],i[n++]=s[3],i[n++]=255,i[n++]=225,i[n++]=s.length>>8&255,i[n++]=s.length&255,i.set(s,n),n+=s.length,i[n++]=1,i[n++]=e.length>>8&255,i[n++]=e.length&255,i.set(e,n),i},F=l=>{let t=0;const s=new DataView(l.buffer),e=s.getUint8(t);if(t=t+1,e!==1)throw new Error("Invalid AVC version");const i=s.getUint8(t)&255;t=t+1;const n=s.getUint8(t)&255;t=t+1;const r=s.getUint8(t)&255;t=t+1;const d=`avc1.${Array.from([i,n,r],b=>b.toString(16).padStart(2,"0")).join("")}`,c=(s.getUint8(t)&3)-1;t=t+1;const h=s.getUint8(t)&31;t=t+1;const p=s.getUint16(t,!1);t=t+2;const u=new Uint8Array(s.buffer.slice(t,t+p));t=t+p;const g=s.getUint8(t)&31;t=t+1;const f=s.getUint16(t,!1);t=t+2;const y=new Uint8Array(s.buffer.slice(t,t+f));return t=t+f,{version:e,codec:d,profile:i,compatibility:n,level:r,lengthSizeMinusOne:c,numOfSequenceParameterSets:h,sequenceParameterSetLength:p,sps:u,numOfPictureParameterSets:g,pictureParameterSetLength:f,pps:y}},K=l=>{const t=new Uint8Array(4+l.length);return new DataView(t.buffer).setUint32(0,l.length,!1),t.set(l,4),t},X=l=>{let t=0;for(const i of l)t+=i.length;const s=new Uint8Array(t);let e=0;for(const i of l){const n=i;s.set(n,e),e+=n.length}return s},Y=l=>{const t=new DataView(l.buffer);let s=0,e,i,n;e=t.getUint32(s,!1),s+=4;{const r=t.getUint8(s),a=r>>7&1,o=r>>5&3,d=r&31;i={forbidden_zero_bit:a,nal_ref_idc:o,nal_unit_type:d},s+=1}{const r=e-1;n=new Uint8Array(t.buffer.slice(s,s+r))}return{size:e,header:i,data:n}};class V{#e={timeout:5*1e3,check:!1};#t;constructor(t={}){this.#e={...this.#e,...t}}check=(t,s)=>new Promise(async(e,i)=>{this.stop(),this.#t=new AbortController;const n=window.setTimeout(()=>{this.#t?.abort("Timeout."),i({status:"timeout",reason:""})},this.#e.timeout);try{const r=await fetch(t,{...s,method:"HEAD",signal:this.#t?.signal});r.status===200?e({status:"successed",reason:""}):i({status:"failed",reason:`${r.status}`})}catch(r){i({status:"error",reason:r.message})}clearTimeout(n)});request=async(t,s)=>new Promise(async(e,i)=>{try{this.#e.check&&await this.check(t,s),this.#t=new AbortController;const n=await fetch(t,{...s,signal:this.#t?.signal});e(n)}catch(n){this.stop(),i(n)}});stop=()=>{this.#t?.signal.aborted===!1&&this.#t.abort("Actively stop.")}}class Q{option={debug:!1,frameTrack:!1};prFetch=new V;prResolves=new $;url="";demuxerWorker;decoderWorker;audioPlayer;renderWorker;stream;on={demuxer:{},decoder:{}};cutRenders=new Map;trackGenerator;constructor(t={}){const{debug:s=!1}=t;this.option.debug=s}start=async t=>{this.stop(),this.url=t;const s=q(t);if(s==="unknown")throw new Error("This address cannot be parsed.");switch(this.init(s),s){case"flv":this.flv.start();break;case"hls":this.hls.start();break}};stop=async()=>{try{clearInterval(this.hls.getSegmentsTimer),this.prFetch.stop()}catch(s){console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: error",s)}this.demuxerWorker?.destroy(),this.decoderWorker?.destroy(),this.renderWorker?.destroy();const t=[...this.cutRenders.keys()];for(const s of t)this.cutRenders.get(s)?.worker.destroy(),this.cutRenders.delete(s);I(this.stream),this.audioPlayer?.destroy()};getStream=()=>this.stream;setPause=t=>{this.renderWorker?.setPause(t)};setMute=t=>this.audioPlayer?.prAudioStream?.setMute(t);setFrameTrack=t=>{this.decoderWorker?.setFrameTrack(t)};isReady=()=>{const t=()=>this.stream?.active===!0;return this.prResolves.add("isReady",t)};cut={create:(t,s)=>{let e=this.cutRenders.get(t);return e?(e.worker.setCut(s),e.worker.setPause(!1),e):(e=L(),e.worker.setCut(s),this.cutRenders.set(t,e),e)},getStream:t=>this.cutRenders.get(t)?.stream,setPause:(t,s)=>{this.cutRenders.get(t)?.worker.setPause(s)},remove:t=>{this.cutRenders.get(t)?.destroy(),this.cutRenders.delete(t)}};init=t=>{this.initDecoder(t),this.initRender(),this.initDemuxer(t),this.audioPlayer=new j,this.audioPlayer.init()};initDemuxer=t=>{this.demuxerWorker=new A,this.demuxerWorker.init(t),this.demuxerWorker.on.debug=s=>{this.option.debug&&console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: debug",s)},this.demuxerWorker.on.info=s=>{this.option.debug&&console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: info",s),this.on.demuxer.info&&this.on.demuxer.info(s)},this.demuxerWorker.on.config=s=>{this.option.debug&&console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: config",s),this.on.demuxer.config&&this.on.demuxer.config(s);const{kind:e}=s;switch(e){case"audio":{const{codec:i,sampleRate:n,numberOfChannels:r}=s;this.decoderWorker?.audio.init({codec:i,sampleRate:n,numberOfChannels:r})}break;case"video":{const{codec:i,description:n}=s;this.decoderWorker?.video.init({codec:i,description:n})}break}},this.demuxerWorker.on.chunk=s=>{if(this.on.demuxer.chunk&&this.on.demuxer.chunk(s),!this.decoderWorker)return;const{kind:e}=s;switch(e){case"audio":{const{type:i,dts:n,data:r}=s,a=n*1;this.decoderWorker.audio.push({type:i,timestamp:a,data:r})}break;case"video":{const{type:i,dts:n,data:r,nalus:a=[]}=s,o=n*1e3;this.decoderWorker.video.push({type:i,timestamp:o,data:r});for(const d of a){if(d.byteLength<=4)continue;const{header:c,data:h}=Y(d),{nal_unit_type:p}=c;p===6&&this.on.demuxer.sei&&this.on.demuxer.sei(h)}}break}}};initDecoder=t=>{this.decoderWorker=new S,this.decoderWorker.init(t),this.decoderWorker.on.debug=s=>{this.option.debug&&console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: debug",s)},this.decoderWorker.on.audio.decode=s=>{this.audioPlayer?.push(s),this.on.decoder.audio&&this.on.decoder.audio(s)},this.decoderWorker.on.audio.error=s=>{this.option.debug&&console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m","color:#0097ff;","------->pr-player: audio.error ",s),this.on.error&&this.on.error(s)},this.decoderWorker.on.video.decode=async s=>{this.renderWorker?.push(s);const e=[...this.cutRenders.keys()];for(const i of e)this.cutRenders.get(i)?.worker.push(s);this.on.decoder.video&&this.on.decoder.video(s),s.bitmap.close()},this.decoderWorker.on.video.error=s=>{this.stop(),this.on.error&&this.on.error(s)}};initRender=()=>{const{worker:t,stream:s}=L();this.renderWorker=t,this.stream=s,this.renderWorker.setPause(!1)};flv={start:async()=>{try{let t=await this.prFetch.request(this.url);if(t.status!==200&&(await new Promise(e=>setTimeout(()=>e(!0),500)),t=await this.prFetch.request(this.url)),t.status!==200&&(await new Promise(e=>setTimeout(()=>e(!0),500)),t=await this.prFetch.request(this.url)),t.status!==200)throw new Error("request is error.");const s=t.body?.getReader();if(!s)throw new Error("reader is error.");for(;;){const{done:e,value:i}=await s.read();if(i&&this.demuxerWorker?.push(i),e)break}}catch(t){if(t?.name!=="AbortError")throw Error(t);this.on.error&&this.on.error(t)}}};hls={isLive:!1,urls:[],url:"",getSegmentsTimer:0,parse:async t=>{const i=new TextDecoder("utf-8").decode(t).split(`
|
|
4
|
+
`).map(c=>c.replace("\r","")),n=this.url.substring(0,this.url.lastIndexOf("/")+1);let r=4,a=0,o=!1;const d=[];for(const c of i)c.startsWith("#EXTINF:")?r=parseFloat(c.split(":")[1].split(",")[0]):c.startsWith("#EXT-X-TARGETDURATION:")?a=parseInt(c.split(":")[1]):c.startsWith("#EXT-X-ENDLIST")?o=!1:c.startsWith("#EXT-X-MEDIA-SEQUENCE:")?o=!0:c.includes(".ts")&&!c.startsWith("#")&&d.push({url:c.startsWith("http")?c:n+c,duration:r,isLive:o});return{baseUrl:n,targetDuration:a,isLive:o,segments:d}},getSegments:async()=>{try{const t=new V;let s=await t.request(this.url);if(s.status!==200&&(await new Promise(i=>setTimeout(()=>i(!0),500)),s=await t.request(this.url)),s.status!==200&&(await new Promise(i=>setTimeout(()=>i(!0),500)),s=await t.request(this.url)),s.status!==200)throw new Error("request is error.");const e=s.body?.getReader();if(!e)throw new Error("reader is error.");for(;;){const{done:i,value:n}=await e.read();if(n){const r=await this.hls.parse(n),{segments:a=[],isLive:o=!1}=r;this.hls.isLive=o,o===!1&&(this.option.frameTrack=!1);let d=Array.from(a,h=>h.url);const c=d.findIndex(h=>h===this.hls.url);c!==-1&&(d=d.slice(c+1)),this.hls.urls=d}if(i)break}}catch(t){this.on.error&&this.on.error(t)}},start:async()=>{try{for(await this.hls.getSegments(),this.hls.getSegmentsTimer=window.setInterval(this.hls.getSegments,500),this.hls.isLive===!1&&(clearInterval(this.hls.getSegmentsTimer),this.decoderWorker?.setFrameTrack(!1));;){const t=this.hls.urls.shift();if(t){this.hls.url=t;const e=(await this.prFetch.request(t)).body?.getReader();if(!e)throw new Error("segment reader is error.");for(;;){const{done:i,value:n}=await e.read();if(n&&this.demuxerWorker?.push(n),i)break}}else await new Promise(s=>setTimeout(()=>s(!0),300))}}catch(t){if(t?.name!=="AbortError")throw Error(t)}}}}class J{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const Z=l=>{let t="unknown";switch(l){case 1:case 2:case 27:case 36:t="video";break;case 3:case 4:case 15:t="audio";break;case 6:t="subtitle";break;case 134:t="ad";break}return t};class tt{pat;pmt;audioConfig;videoConfig;payloadMap=new Map;on={};constructor(){}parse=async t=>{let s=0;for(;!(s+188>t.byteLength);){if(t.getInt8(s)!=71){s++;continue}await this.parsePacket(t,s),s+=188}return s};parsePacket=async(t,s)=>{if(s+188>t.byteLength)throw new Error("Invalid TS packet");if(t.getUint8(s)!==71)throw new Error("Invalid TS packet");let e=s;const i=this.parseHeader(t,e);e+=4;const{transport_error_indicator:n,pid:r,payload_unit_start_indicator:a,adaptation_field_control:o}=i;if(n===1||r===void 0)return;let d=184;if(o===2||o===3){const c=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=c,d-=c}if(o===3&&(d-=1),o===1||o===3){const c=new Uint8Array(t.buffer.slice(e,e+d));if(r===0)return this.parsePAT(t,e);{const{programs:u=[]}=this.pat||{};if(u.find(f=>f.pmt_pid===r))return this.parsePMT(t,e)}const{streams:h=[]}=this.pmt||{},p=h.find(u=>u.elementary_pid===r);if(p){if(a===1){const u=this.payloadMap.get(r);if(u){switch(p.kind){case"audio":{const g=await this.parseAudio(u);this.on.chunk&&this.on.chunk(g)}break;case"video":{const g=await this.parseVideo(u);this.on.chunk&&this.on.chunk(g),await new Promise(f=>setTimeout(()=>f(!0),0))}break}this.payloadMap.delete(r)}}{this.payloadMap.has(r)||this.payloadMap.set(r,new Uint8Array);const u=this.payloadMap.get(r),g=new Uint8Array(u.byteLength+c.byteLength);g.set(u,0),g.set(c,u.byteLength),this.payloadMap.set(r,g)}}}};parseHeader=(t,s)=>{let e=s;const i=t.getUint8(e),n=t.getUint8(e+1),r=t.getUint8(e+2),a=t.getUint8(e+3),o=(n&128)>>7;if(o===1)return{sync_byte:i,transport_error_indicator:o};const d=(n&64)>>6,c=(n&32)>>5,h=(n&31)<<8|r,p=(a&192)>>6,u=a>>4&3,g=a&15;return{sync_byte:i,transport_error_indicator:o,payload_unit_start_indicator:d,transport_priority:c,pid:h,transport_scrambling_control:p,adaptation_field_control:u,continuity_counter:g}};parsePAT=(t,s)=>{let e=s,i;{const a=t.getUint8(e);e+=1;const o=t.getUint8(e);if(e+=1,o!==0)throw new Error("Invalid PAT table_id");const d=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const h=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const u=t.getUint8(e);e+=1;const g=t.getUint8(e);e+=1,i={pointer_field:a,table_id:o,section_length:d,transport_stream_id:c,version_number:h,current_next_indicator:p,section_number:u,last_section_number:g}}const n=[];{const a=i.section_length-5-4,o=e+a;for(;e<o;){const d=t.getUint16(e),c=t.getUint16(e+2)&8191;e+=4,d!==0&&c>=32&&c<=8190&&n.push({program_number:d,pmt_pid:c})}}const r=t.getUint32(e);this.pat={header:i,programs:n,crc32:r},this.on.debug&&this.on.debug({pat:this.pat})};parsePMT=(t,s)=>{let e=s,i;{const a=t.getUint8(e);e+=1;const o=t.getUint8(e);if(e+=1,o!==2)throw new Error("Invalid PMT table_id");const d=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const h=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const u=t.getUint8(e);e+=1;const g=t.getUint8(e);e+=1;const f=t.getUint16(e)&8191;e+=2;const y=t.getUint16(e)&4095;e+=2,i={pointer_field:a,table_id:o,section_length:d,transport_stream_id:c,version_number:h,current_next_indicator:p,section_number:u,last_section_number:g,pcr_pid:f,program_info_length:y}}const n=[];{const a=i.section_length-9-4,o=e+a;for(;e<o;){const d=t.getUint8(e),c=Z(d),h=t.getUint16(e+1)&8191,p=t.getUint16(e+3)&4095;if(e+=5,h<32||h>8190){console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);continue}n.push({kind:c,stream_type:d,elementary_pid:h,es_info_length:p})}}const r=t.getUint32(e);this.pmt={header:i,streams:n,crc32:r},this.on.debug&&this.on.debug({pmt:this.pmt})};parseAdaptationField=(t,s)=>{let e=s,i,n,r,a;const o=t.getUint8(e),d=!!(o&128),c=!!(o&64),h=!!(o&32),p=!!(o&16),u=!!(o&8),g=!!(o&4),f=!!(o&2),y=!!(o&1);e+=1;const b=(k,_)=>{let w=BigInt(0);w|=BigInt(k.getUint16(_))<<25n,w|=BigInt(k.getUint16(_+1))<<17n,w|=BigInt(k.getUint16(_+2))<<9n,w|=BigInt(k.getUint16(_+3))<<1n,w|=BigInt(k.getUint16(_+4)>>7);const ot=(k.getUint16(_+4)&1)<<8|k.getUint16(_+5);return w=w*300n+BigInt(ot),w};if(p&&(i=b(t,e),e+=6),u&&(n=b(t,e),e+=6),g&&(r=t.getInt8(e),e+=1),f){const k=t.getUint8(e);e+=1,a=new Uint8Array(t.buffer,e,k),e+=k}return{discontinuity_indicator:d,random_access_indicator:c,elementary_stream_priority_indicator:h,pcr_flag:p,opcr_flag:u,splicing_point_flag:g,transport_private_data_flag:f,adaptation_field_extension_flag:y,pcr:i,opcr:n,splice_countdown:r,transport_private_data:a}};parseAudio=async t=>{const s=new DataView(t.buffer);let e=0,i,n;{const r=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!r)throw new Error("invalid ts audio payload.");const a=s.getUint8(e);e+=1;const o=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let d,c,h,p,u;{const y=s.getUint8(e);e+=1,d=y>>4&3,c=(y>>3&1)===1,h=(y>>2&1)===1,p=(y>>1&1)===1,u=(y&1)===1}let g,f;{const y=s.getUint8(e);e+=1;const b=y>>6,k=s.getUint8(e);e+=1,(b&2)===2&&(g=this.parsePtsDts(s,e)),(b&1)===1?f=this.parsePtsDts(s,e+5):f=g,e+=k}i={stream_id:a,pes_packet_length:o,scrambling_control:d,priority:c,data_alignment:h,copyright:p,original_copy:u,pts:g,dts:f}}n=t.slice(e);{if(!this.audioConfig&&s.getUint8(e)===255){const h=s.getUint8(e+2),p=s.getUint8(e+3);let u,g;g=h>>2&15,u=(h&1)<<2|p>>6;const f=`mp4a.40.${u}`,b=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][g];this.audioConfig={kind:"audio",codec:f,sampleRate:b,numberOfChannels:u},this.on.config&&this.on.config(this.audioConfig)}const{dts:r=0,pts:a=0}=i,o=a-r,d=n.slice(7);return{kind:"audio",type:"key",dts:r,pts:a,cts:o,data:d}}};parseVideo=async t=>{const s=new DataView(t.buffer);let e=0,i,n;{const r=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!r)throw new Error("invalid ts video payload.");const a=s.getUint8(e);e+=1;const o=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let d,c,h,p,u;{const y=s.getUint8(e);e+=1,d=y>>4&3,c=(y>>3&1)===1,h=(y>>2&1)===1,p=(y>>1&1)===1,u=(y&1)===1}let g,f;{const y=s.getUint8(e);e+=1;const b=y>>6,k=s.getUint8(e);e+=1,(b&2)===2&&(g=this.parsePtsDts(s,e)),(b&1)===1?f=this.parsePtsDts(s,e+5):f=g,e+=k}i={stream_id:a,pes_packet_length:o,scrambling_control:d,priority:c,data_alignment:h,copyright:p,original_copy:u,pts:g,dts:f}}n=t.slice(e);{const r=this.getNalus(n);if(!this.videoConfig){let u,g;if(u=r.find(y=>y.type===7)?.nalu.slice(4),g=r.find(y=>y.type===8)?.nalu.slice(4),u&&g){const f=H(u,g),{codec:y}=F(f);this.videoConfig={kind:"video",codec:y,description:f,sps:u,pps:g},this.on.config&&this.on.config(this.videoConfig)}}const a=[];let o="delta";for(const u of r){const{type:g,nalu:f}=u;switch(g){case 6:case 9:a.push(f);break;case 1:o="delta",a.push(f);break;case 5:o="key",a.push(f);break}}const d=X(a),{dts:c=0,pts:h=0}=i,p=h-c;return{kind:"video",type:o,dts:c,pts:h,cts:p,data:d,nalus:a}}};parsePtsDts(t,s){const e=t.getUint8(s),i=t.getUint8(s+1),n=t.getUint8(s+2),r=t.getUint8(s+3),a=t.getUint8(s+4),o=(BigInt(e)&0b00001110n)<<29n|(BigInt(i)&0b11111111n)<<22n|(BigInt(n)&0b11111110n)<<14n|(BigInt(r)&0b11111111n)<<7n|(BigInt(a)&0b11111110n)>>1n;return Number(o)/90}getNalus=t=>{const s=[];let e=0;for(;!(e+4>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}e+=3;let i=e;const n=t[e]&31;for(e+=1;!(e+1>t.byteLength);){if(t[e]!==0||t[e+1]!==0||t[e+2]!==1){e+=1;continue}break}let r=e-i;if(t[e-1]===0&&(r-=1),r!==0){const a=t.slice(i,i+r),o=K(a);s.push({type:n,nalu:o})}}return s}}const v=(l,t)=>l.getUint8(t)<<16|l.getUint8(t+1)<<8|l.getUint8(t+2);class et{audioConfig;videoConfig;header;textDecoder=new TextDecoder("utf-8");on={};constructor(){}parse=async t=>{let s=0;for(this.header||(this.parseHeader(t,s),s+=9);this.isSurplusTag(t,s)!==!1;){const i=this.parseTagHeader(t,s+4),{tagType:n,dataSize:r,timestamp:a}=i;if(n){const o=this.parseTagBody(n,t,s+4+11,r);switch(n){case"script":this.on.info&&this.on.info(o);break;case"audio":{const{accPacketType:d}=o;if(d===0){const{codec:c,sampleRate:h,channelConfiguration:p}=o;this.audioConfig={kind:"audio",codec:c,sampleRate:h,numberOfChannels:p},this.on.config&&this.on.config(this.audioConfig)}else{const{cts:c,data:h}=o,p="key",u=c===void 0?void 0:c+a;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:a,pts:u,cts:c,data:h})}}break;case"video":{const{avcPacketType:d}=o;if(d===0){const{codec:c,sps:h,pps:p,data:u}=o;this.videoConfig={kind:"video",codec:c,description:u,sps:h,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:c,cts:h,data:p,nalus:u}=o,g=c===1?"key":"delta",f=h===void 0?void 0:h+a;this.on.chunk&&this.on.chunk({kind:"video",type:g,dts:a,pts:f,cts:h,data:p,nalus:u})}}break}s=s+4+11+r}await new Promise(o=>setTimeout(()=>o(!0),8))}return s};parseHeader=(t,s)=>{let e,i,n,r;e=t.getUint8(s)<<16|t.getUint8(s+1)<<8|t.getUint8(s+2),i=t.getUint8(3);{const o=t.getUint8(0).toString(2).padStart(5,"0").split(""),[,,d,,c]=o;n={audio:c==="1",video:d==="1"}}r=t.getUint32(5),this.header={signature:e,version:i,flags:n,dataOffset:r}};isSurplusTag=(t,s)=>{let e=!0;const i=t.byteLength;if(s+4>i)e=!1;else if(s+4+11>i)e=!1;else{const n=v(t,s+4+1);s+4+11+n>i&&(e=!1)}return e};parseTagHeader=(t,s)=>{let e,i,n,r,a;{const o=t.getUint8(s);let d;switch(o){case 18:d="script";break;case 8:d="audio";break;case 9:d="video";break}e=d}return i=v(t,s+1),n=v(t,s+4),r=t.getUint8(s+7),a=v(t,s+8),{tagType:e,dataSize:i,timestamp:n,timestampExtended:r,streamID:a}};parseTagBody=(t,s,e,i)=>{let n;switch(t){case"script":n=this.parseMetaData(s,e);break;case"audio":n=this.parseAudio(s,e,i);break;case"video":n=this.parseVideo(s,e,i);break}return n};parseMetaData=(t,s)=>{let e=s;{if(t.getUint8(e)!==2)throw new Error("Invalid AMF type for onMetaData (expected 0x02)");e=e+1}const i=t.getUint16(e,!1);e=e+2;{const a=new Int8Array(t.buffer.slice(e,e+i));if((this.textDecoder?.decode(a)||"")!=="onMetaData")throw new Error("Expected 'onMetaData' string");e=e+i}const n=this.getAmfType(t,e);return e=e+1,this.getAMFValue(t,e,n).value};parseAudio=(t,s,e)=>{let i=s;const n=t.getUint8(i),r=n>>4&15,a=n>>2&3,o=n>>1&1,d=n&1;i=i+1;const c=t.getUint8(i);i=i+1;const h=e,p=new Uint8Array(t.buffer.slice(i,i+h));if(r===10&&c===0){const u=t.getUint8(i),g=t.getUint8(i+1),f=u>>3&31,y=(u&7)<<1|g>>7,b=g>>3&15,k=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],_=`mp4a.40.${f}`,w=k[y];return{soundFormat:r,soundRate:a,soundSize:o,soundType:d,accPacketType:c,data:p,samplingFrequencyIndex:y,channelConfiguration:b,codec:_,sampleRate:w}}return{soundFormat:r,soundRate:a,soundSize:o,soundType:d,accPacketType:c,data:p}};parseVideo=(t,s,e)=>{let i=s;const n=t.getUint8(i),r=n>>4&15,a=n&15;i=i+1;const o=t.getUint8(i);i=i+1;const d=v(t,i);i=i+3;const c=e-5,h=new Uint8Array(t.buffer.slice(i,i+c));switch(a){case 7:if(o===0){const p=F(h);return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h,...p}}else if(o===1){const p=[],u=i+e-5;for(;!(i+4>u);){const g=t.getUint32(i,!1),f=new Uint8Array(t.buffer.slice(i,i+4+g));i+=4+g,p.push(f)}return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:r,codecID:a,avcPacketType:o,cts:d,data:h}};getAmfType=(t,s)=>t.getUint8(s);getAMFName=(t,s,e)=>{const i=new Uint8Array(t.buffer.slice(s,s+e));return this.textDecoder?.decode(i)||""};getAMFValue=(t,s,e)=>{let i=s,n,r=0;switch(e){case 0:n=t.getFloat64(i,!1),r=8;break;case 1:n=!!t.getUint8(i),r=1;break;case 2:{n="";const o=t.getUint16(i,!1);i=i+2;const d=new Int8Array(t.buffer,i,o).filter(h=>h!==0);n=(this.textDecoder?.decode(d)||"").trim(),r=2+o}break;case 3:for(n={};i<t.byteLength;){const o=t.getUint16(i,!1);if(o===0)break;i=i+2;const d=this.getAMFName(t,i,o);i=i+o;const c=this.getAmfType(t,i);if(c===6)break;i=i+1;const h=this.getAMFValue(t,i,c);i=i+h.length,n[d]=h.value,r=2+o+1+h.length}break;case 8:{n={};const o=t.getUint32(i,!1);i=i+4;for(let d=0;d<o;d++){const c=t.getUint16(i,!1);i=i+2;const h=this.getAMFName(t,i,c);i=i+c;const p=this.getAmfType(t,i);i=i+1;const u=this.getAMFValue(t,i,p);i=i+u.length,n[h]=u.value,r=2+c+1+u.length}}break;case 10:{n=[];const o=t.getUint32(i,!1);i=i+4;for(let d=0;d<o;d++){const c=this.getAmfType(t,i);i=i+1;const h=this.getAMFValue(t,i,c);i=i+h.length,n.push(h.value),r=1+h.length}}break}return{amfType:e,length:r,value:n}}}class st{pattern;cacher=new J;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new et;break;case"hls":this.parser=new tt;break;default:throw new Error("is error pattern.")}this.parser.on.debug=s=>this.on.debug&&this.on.debug(s),this.parser.on.info=s=>this.on.info&&this.on.info(s),this.parser.on.config=s=>this.on.config&&this.on.config(s),this.parser.on.chunk=s=>{this.cacher.pushChunk(s),this.on.chunk&&this.on.chunk(s)}};push=t=>{this.cacher.push(t),this.isParseing===!1&&this.parse()};destroy=()=>{this.cacher.destroy(),this.isParseing=!1,this.offset=0};parse=async()=>{try{if(this.isParseing=!0,!this.pattern)throw new Error("You need to set the pattern.");if(!this.parser)throw new Error("You need to init parser.");for(;;){const t=this.cacher.next(this.offset);if(this.offset=0,!t)break;this.offset=await this.parser.parse(t)}this.isParseing=!1}catch{this.destroy()}}}class it{pattern="flv";audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];isProcessing=!1;decodeTimer=0;frameTrack=!1;isFrameTrack=!1;fameTrackOption={flv:[20,50],hls:[200,300],dash:[50,100],rtmp:[50,100]};decodingSpeed=16;fps=0;firstVideoChunkTimestamp;secondVideoChunkTimestamp;decodingSpeedRatio=1;maxDecodingSpeedRatio=2;lastRenderTime;nextRenderTime;on={audio:{},video:{}};constructor(){}init=t=>{this.destroy(),this.pattern=t,this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()};setFrameTrack=t=>{this.frameTrack=t,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};initDecodeInterval=()=>{let t=this.decodingSpeed/this.decodingSpeedRatio;const s=this.baseTime+performance.now();if(this.lastRenderTime||(this.lastRenderTime=s),this.fps=Math.round(1e3/(s-this.lastRenderTime)),this.lastRenderTime=s,this.nextRenderTime){const e=this.lastRenderTime-this.nextRenderTime;t-=e}this.nextRenderTime=this.lastRenderTime+t,this.decodeTimer=setTimeout(()=>{this.decode(),this.initDecodeInterval()},t)};decode=()=>{if(this.isProcessing!==!0){for(this.isProcessing=!0;;){const t=this.pendingChunks.shift(),s=this.pendingChunks.length;if(this.frameTrack){const[n,r]=this.fameTrackOption[this.pattern];if(s<=n&&(this.isFrameTrack=!1),s>=r&&(this.isFrameTrack=!0),this.isFrameTrack){const a=Math.min(1+(s-n)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(a.toFixed(1))}else this.decodingSpeedRatio=1}if(this.on.debug){const{decodingSpeed:n,decodingSpeedRatio:r,fps:a}=this;this.on.debug({decodingSpeed:n,decodingSpeedRatio:r,fps:a})}if(!t)break;const{type:e,init:i}=t;switch(e){case"audio":this.decodeAudio(i);break;case"video":this.decodeVideo(i);break}if(e==="video")break}this.isProcessing=!1}};decodeAudio=t=>{if(!this.audioDecoder)return;const s=new EncodedAudioChunk(t);this.audioDecoder.decode(s)};decodeVideo=t=>{if(this.videoDecoder&&(t.type==="key"&&(this.hasKeyFrame=!0),this.firstVideoChunkTimestamp?this.secondVideoChunkTimestamp||(this.secondVideoChunkTimestamp=t.timestamp,this.decodingSpeed=(this.secondVideoChunkTimestamp-this.firstVideoChunkTimestamp)/1e3):this.firstVideoChunkTimestamp=t.timestamp,this.hasKeyFrame)){const s=new EncodedVideoChunk(t);this.videoDecoder.decode(s)}};destroy=()=>{this.audio.destroy(),this.video.destroy(),clearInterval(this.decodeTimer)};audio={init:t=>{this.audio.destroy(),this.audioDecoderConfig={...t},this.audioDecoder=new AudioDecoder({output:s=>{const e=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:s,playbackRate:e})},error:s=>{this.on.audio.error&&this.on.audio.error(s)}}),this.audioDecoder.configure(this.audioDecoderConfig)},push:t=>{this.pendingChunks.push({type:"audio",init:t})},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:t=>{this.video.destroy(),this.videoDecoderConfig={...t},this.videoDecoder=new VideoDecoder({output:async s=>{const e=s.timestamp+this.baseTime*1e3,i=await createImageBitmap(s);s.close(),i.width>0&&i.height>0?this.on.video.decode&&this.on.video.decode({timestamp:e,bitmap:i}):i.close()},error:s=>{this.on.video.error&&this.on.video.error(s)}}),this.videoDecoder.configure(this.videoDecoderConfig)},push:t=>{this.pendingChunks.push({type:"video",init:t})},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}class nt{writable;writer;cutOption;pause=!1;constructor(){}init=({writable:t})=>{this.destroy(),this.writable=t,this.writer=this.writable.getWriter()};push=async t=>{if(this.pause)return;const{timestamp:s}=t;let{bitmap:e}=t;if(this.cutOption){const{sx:n=0,sy:r=0,sw:a=e.width,sh:o=e.height}=this.cutOption;e=await createImageBitmap(e,n,r,a,o)}const i=new VideoFrame(e,{timestamp:s});this.cutOption&&e.close(),this.writer.write(i),i.close()};setCut=t=>{this.cutOption=t};setPause=t=>{this.pause=t};destroy=()=>{this.writable=void 0,this.writer=void 0,this.cutOption=void 0}}U.Decoder=it,U.DecoderWorker=S,U.Demuxer=st,U.DemuxerWorker=A,U.PrPlayer=Q,U.Render=nt,U.RenderWorker=P,Object.defineProperty(U,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenderWorker } from './render/RenderWorker';
|
|
2
|
-
export declare const getFormatFromUrlPattern: (url: string) => "
|
|
2
|
+
export declare const getFormatFromUrlPattern: (url: string) => "hls" | "dash" | "rtmp" | "flv" | "unknown";
|
|
3
3
|
export declare const stopStream: (stream: MediaStream | undefined) => void;
|
|
4
4
|
export declare const createStreamGenerator: () => {
|
|
5
5
|
worker: RenderWorker;
|
package/dist/type.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Pattern = 'hls' | 'dash' | 'rtmp' | 'flv';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pr-player",
|
|
3
|
-
"description": "对 flv 格式的地址进行解析 并输出
|
|
4
|
-
"version": "0.2.
|
|
3
|
+
"description": "对 flv 格式的地址进行解析 并输出 MediaStream,提供 demuxer 层(info、chunk、sei)回调、 decoder 层(audio、video)回调 ,提供 cut 等相关能力,以支持根据业务层 SEI 对视频进行剪切渲染。",
|
|
4
|
+
"version": "0.2.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|