pr-player 0.2.15 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PrPlayer.d.ts +11 -10
- package/dist/index.js +479 -439
- package/dist/index.umd.cjs +4 -4
- package/dist/render/Render.d.ts +21 -9
- package/dist/render/RenderWorker.d.ts +14 -5
- package/dist/tools.d.ts +0 -6
- package/package.json +3 -4
package/dist/index.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
const D = '(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;parser;on={};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.info=y=>postMessage({action:"on.info",data:y}),A.on.config=y=>postMessage({action:"on.config",data:y}),A.on.chunk=y=>postMessage({action:"on.chunk",data:y}),A.on.debug=y=>postMessage({action:"on.debug",data:y}),onmessage=y=>{const{action:t,data:s}=y.data,e=A[t];e&&e(s)}})();\n', _ = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", D], { type: "text/javascript;charset=utf-8" });
|
|
2
|
-
function
|
|
1
|
+
const x = '(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>100&&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;parser;on={};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.info=y=>postMessage({action:"on.info",data:y}),A.on.config=y=>postMessage({action:"on.config",data:y}),A.on.chunk=y=>postMessage({action:"on.chunk",data:y}),A.on.debug=y=>postMessage({action:"on.debug",data:y}),onmessage=y=>{const{action:t,data:s}=y.data,e=A[t];e&&e(s)}})();\n', _ = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", x], { type: "text/javascript;charset=utf-8" });
|
|
2
|
+
function R(p) {
|
|
3
3
|
let t;
|
|
4
4
|
try {
|
|
5
5
|
if (t = _ && (self.URL || self.webkitURL).createObjectURL(_), !t) throw "";
|
|
6
6
|
const s = new Worker(t, {
|
|
7
|
-
name:
|
|
7
|
+
name: p?.name
|
|
8
8
|
});
|
|
9
9
|
return s.addEventListener("error", () => {
|
|
10
10
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
11
11
|
}), s;
|
|
12
12
|
} catch {
|
|
13
13
|
return new Worker(
|
|
14
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
14
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(x),
|
|
15
15
|
{
|
|
16
|
-
name:
|
|
16
|
+
name: p?.name
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
class
|
|
22
|
-
worker = new
|
|
21
|
+
class I {
|
|
22
|
+
worker = new R();
|
|
23
23
|
on = {};
|
|
24
24
|
constructor() {
|
|
25
25
|
this.worker.onmessage = (t) => {
|
|
@@ -46,29 +46,29 @@ class V {
|
|
|
46
46
|
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
const
|
|
50
|
-
`, C = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",
|
|
51
|
-
function
|
|
49
|
+
const M = `(function(){"use strict";class r{pattern="flv";audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;baseTime=0;pendingChunks=[];currentChunk;isProcessing=!1;decodeTimer=0;frameTrack=!1;isFrameTrack=!1;fameTrackOption={flv:[30,50],hls:[200,300],dash:[50,100],rtmp:[50,100]};decodingSpeedRatio=1;maxDecodingSpeedRatio=2;decodingSpeed=16;fps=0;firstVideoChunkTimestamp;secondVideoChunkTimestamp;frameStartTime;lastRenderTime;nextRenderTime;on={audio:{},video:{}};constructor(){}init=e=>{this.destroy(),this.pattern=e,this.baseTime=new Date().getTime()-performance.now(),this.initDecodeInterval()};initAudio=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)};initVideo=e=>{this.video.destroy(),this.videoDecoderConfig={...e},this.videoDecoder=new VideoDecoder({output:async i=>{this.frameStartTime||(this.frameStartTime=i.timestamp);const t=i.timestamp-this.frameStartTime+this.baseTime*1e3,s=await createImageBitmap(i);i.close(),s.width>0&&s.height>0?(this.on.video.decode&&this.on.video.decode({timestamp:t,bitmap:s}),this.currentChunk&&this.currentChunk.kind==="video"&&this.currentChunk.nalus&&this.on.nalus&&this.on.nalus(this.currentChunk.nalus)):s.close()},error:i=>{this.on.video.error&&this.on.video.error(i)}}),this.videoDecoder.configure(this.videoDecoderConfig)};setFrameTrack=e=>{this.frameTrack=e,this.frameTrack===!1&&(this.decodingSpeedRatio=1)};push=e=>{this.pendingChunks.push(e)};destroy=()=>{this.audio.destroy(),this.video.destroy(),this.pendingChunks=[],this.firstVideoChunkTimestamp=void 0,this.secondVideoChunkTimestamp=void 0,this.frameStartTime=void 0,this.lastRenderTime=void 0,this.nextRenderTime=void 0,clearInterval(this.decodeTimer)};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;this.currentChunk=this.pendingChunks.shift(),!!this.currentChunk;){const e=this.pendingChunks.length;if(this.frameTrack){const[s,n]=this.fameTrackOption[this.pattern];if(e<=s&&(this.isFrameTrack=!1),e>=n&&(this.isFrameTrack=!0),this.isFrameTrack){const a=Math.min(1+(e-s)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(a.toFixed(1))}else this.decodingSpeedRatio=1}if(this.on.analysis){const{decodingSpeed:s,decodingSpeedRatio:n,fps:a}=this;this.on.analysis({decodingSpeed:s,decodingSpeedRatio:n,fps:a,cacheLength:e})}const{kind:i,init:t}=this.currentChunk;switch(i){case"audio":this.decodeAudio(t);break;case"video":this.decodeVideo(t);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.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)}};audio={flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}const d=new r;d.on.audio.decode=o=>postMessage({action:"on.audio.decode",data:o},[o.audioData]),d.on.audio.error=o=>postMessage({action:"on.audio.error",data:o}),d.on.video.decode=o=>postMessage({action:"on.video.decode",data:o},[o.bitmap]),d.on.video.error=o=>postMessage({action:"on.video.error",data:o}),d.on.nalus=o=>postMessage({action:"on.nalus",data:o}),d.on.analysis=o=>postMessage({action:"on.analysis",data:o}),onmessage=o=>{const{action:e,data:i}=o.data,t=d[e];t&&t(i)}})();
|
|
50
|
+
`, C = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", M], { type: "text/javascript;charset=utf-8" });
|
|
51
|
+
function V(p) {
|
|
52
52
|
let t;
|
|
53
53
|
try {
|
|
54
54
|
if (t = C && (self.URL || self.webkitURL).createObjectURL(C), !t) throw "";
|
|
55
55
|
const s = new Worker(t, {
|
|
56
|
-
name:
|
|
56
|
+
name: p?.name
|
|
57
57
|
});
|
|
58
58
|
return s.addEventListener("error", () => {
|
|
59
59
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
60
60
|
}), s;
|
|
61
61
|
} catch {
|
|
62
62
|
return new Worker(
|
|
63
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
63
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(M),
|
|
64
64
|
{
|
|
65
|
-
name:
|
|
65
|
+
name: p?.name
|
|
66
66
|
}
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
class
|
|
71
|
-
worker = new
|
|
70
|
+
class L {
|
|
71
|
+
worker = new V();
|
|
72
72
|
on = { audio: {}, video: {} };
|
|
73
73
|
constructor() {
|
|
74
74
|
this.worker.onmessage = (t) => {
|
|
@@ -104,98 +104,136 @@ class N {
|
|
|
104
104
|
this.worker.postMessage({ action: "destroy" }), this.worker.terminate();
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
const D = `(function(){"use strict";class h{renderMap=new Map;constructor(){}push=async t=>{const{timestamp:s}=t,{bitmap:e}=t;if(e.height===0||e.width===0)return e.close();const n=[...this.renderMap.keys()];for(const i of n){const a=this.renderMap.get(i);if(!a)continue;const{pause:f=!1,writer:c,option:d}=a;if(f!==!0)if(i==="default"||!d){const o=new VideoFrame(e,{timestamp:s});c.write(o),o.close()}else{const{sx:o=0,sy:w=0,sw:y=e.width,sh:M=e.height}=d,u=await createImageBitmap(e,o,w,y,M),p=new VideoFrame(u,{timestamp:s});u.close(),c.write(p),p.close()}}e.close()};addCut=t=>{const{key:s,writable:e,option:n}={key:"default",...t},i=e.getWriter();this.renderMap.set(s,{writable:e,writer:i,option:n,pause:!1})};delCut=t=>{this.renderMap.delete(t)};setCut=t=>{const{key:s,cutOption:e}={key:"default",...t},n=this.renderMap.get(s);n&&this.renderMap.set(s,{...n,option:e})};setPause=t=>{const{key:s,pause:e}={key:"default",...t},n=this.renderMap.get(s);n&&this.renderMap.set(s,{...n,pause:e})};destroy=()=>{this.renderMap=new Map}}const l=new h;onmessage=r=>{const{action:t,data:s}=r.data,e=l[t];e&&e(s)}})();
|
|
108
|
+
`, v = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", D], { type: "text/javascript;charset=utf-8" });
|
|
109
|
+
function N(p) {
|
|
110
|
+
let t;
|
|
111
|
+
try {
|
|
112
|
+
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
113
|
+
const s = new Worker(t, {
|
|
114
|
+
name: p?.name
|
|
115
|
+
});
|
|
116
|
+
return s.addEventListener("error", () => {
|
|
117
|
+
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
118
|
+
}), s;
|
|
119
|
+
} catch {
|
|
120
|
+
return new Worker(
|
|
121
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(D),
|
|
122
|
+
{
|
|
123
|
+
name: p?.name
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
class F {
|
|
129
|
+
worker = new N();
|
|
130
|
+
constructor() {
|
|
131
|
+
}
|
|
132
|
+
push = (t) => this.worker.postMessage({ action: "push", data: t }, [t.bitmap]);
|
|
133
|
+
addCut = (t) => this.worker.postMessage({ action: "addCut", data: t }, [t.writable]);
|
|
134
|
+
delCut = (t) => this.worker.postMessage({ action: "delCut", data: t });
|
|
135
|
+
setCut = (t) => this.worker.postMessage({ action: "setCut", data: t });
|
|
136
|
+
setPause = (t) => this.worker.postMessage({ action: "setPause", data: t });
|
|
137
|
+
destroy = () => {
|
|
138
|
+
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
var B = Object.defineProperty, G = (p, t, s) => t in p ? B(p, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : p[t] = s, m = (p, t, s) => G(p, typeof t != "symbol" ? t + "" : t, s);
|
|
142
|
+
class W {
|
|
109
143
|
constructor(t, s) {
|
|
110
|
-
|
|
144
|
+
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", /* @__PURE__ */ new Map()), m(this, "audioContext", new AudioContext()), m(this, "sourceNode"), m(this, "highPassNode"), m(this, "lowPassNode"), 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", () => {
|
|
111
145
|
{
|
|
112
146
|
const e = this.inputStream.getTracks();
|
|
113
147
|
for (const i of e)
|
|
114
148
|
i.stop(), this.inputStream.removeTrack(i);
|
|
115
149
|
}
|
|
116
|
-
}),
|
|
150
|
+
}), m(this, "pause", async (e) => {
|
|
151
|
+
const i = this.inputStream.getTracks();
|
|
152
|
+
for (const n of i)
|
|
153
|
+
n.enabled = !e;
|
|
154
|
+
}), m(this, "getStream", () => this.filterStream(this.outputStream)), m(this, "setMute", (e = !0) => {
|
|
117
155
|
e ? this.analyserNode.disconnect(this.outputGainNode) : this.analyserNode.connect(this.outputGainNode);
|
|
118
|
-
}),
|
|
156
|
+
}), m(this, "setInputGain", (e) => {
|
|
119
157
|
this.inputGain = e, this.inputGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
120
|
-
}),
|
|
158
|
+
}), m(this, "setEnhanceGain", async (e) => {
|
|
121
159
|
this.enhanceGain = e + 1, this.enhanceGainNode.gain.setValueAtTime(this.enhanceGain, this.audioContext.currentTime);
|
|
122
|
-
}),
|
|
160
|
+
}), m(this, "setBgsGain", (e) => {
|
|
123
161
|
this.bgsGain = e, this.bgsGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
124
|
-
}),
|
|
162
|
+
}), m(this, "setBgmGain", (e) => {
|
|
125
163
|
this.bgmGain = e, this.bgmGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
126
|
-
}),
|
|
164
|
+
}), m(this, "setOutputGain", (e) => {
|
|
127
165
|
this.outputGain = e, this.outputGainNode.gain.setValueAtTime(this.outputGain, this.audioContext.currentTime);
|
|
128
|
-
}),
|
|
166
|
+
}), m(this, "getVolume", () => {
|
|
129
167
|
const { analyserNode: e, analyserArrayData: i } = this;
|
|
130
168
|
e.getByteFrequencyData(i);
|
|
131
169
|
let n = 0;
|
|
132
|
-
for (let
|
|
133
|
-
n += i[
|
|
170
|
+
for (let o = 0; o < i.length; o++)
|
|
171
|
+
n += i[o];
|
|
134
172
|
return Math.ceil(n / i.length);
|
|
135
|
-
}),
|
|
173
|
+
}), m(this, "mixAudio", (e, i = "bgm") => new Promise(async (n, o) => {
|
|
136
174
|
try {
|
|
137
175
|
{
|
|
138
176
|
const d = this.mixAudioMap.get(i);
|
|
139
177
|
d && d.stop();
|
|
140
178
|
}
|
|
141
|
-
const a = i === "bgs" ? this.bgsGainNode : this.bgmGainNode,
|
|
142
|
-
this.mixAudioMap.set(i,
|
|
143
|
-
|
|
144
|
-
},
|
|
179
|
+
const a = i === "bgs" ? this.bgsGainNode : this.bgmGainNode, r = this.audioContext.createBufferSource();
|
|
180
|
+
this.mixAudioMap.set(i, r), r.buffer = e, r.connect(a), r.onended = () => {
|
|
181
|
+
r.disconnect(a), this.mixAudioMap.delete(i), n(!0);
|
|
182
|
+
}, r.start(0);
|
|
145
183
|
} catch (a) {
|
|
146
|
-
|
|
184
|
+
o(a);
|
|
147
185
|
}
|
|
148
|
-
})),
|
|
186
|
+
})), m(this, "mixAudioStop", (e) => {
|
|
149
187
|
const i = this.mixAudioMap.get(e);
|
|
150
188
|
i?.stop();
|
|
151
|
-
}),
|
|
189
|
+
}), m(this, "changeMix", (e, i) => {
|
|
152
190
|
const n = e === "bgs" ? this.bgsGainNode : this.bgmGainNode;
|
|
153
191
|
i ? n.connect(this.destinationNode) : n.disconnect(this.destinationNode);
|
|
154
|
-
}), 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;
|
|
192
|
+
}), s && (this.audioContext = s), this.inputStream = t, this.sourceNode = this.audioContext.createMediaStreamSource(this.inputStream), this.highPassNode = this.audioContext.createBiquadFilter(), this.highPassNode.type = "highpass", this.highPassNode.frequency.value = 100, this.lowPassNode = this.audioContext.createBiquadFilter(), this.lowPassNode.type = "lowpass", this.lowPassNode.frequency.value = 8e3, 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;
|
|
155
193
|
{
|
|
156
|
-
const { sourceNode: e,
|
|
157
|
-
e.connect(i), i.connect(n), n.connect(o),
|
|
194
|
+
const { sourceNode: e, highPassNode: i, lowPassNode: n, inputGainNode: o, enhanceGainNode: a, bgsGainNode: r, bgmGainNode: d, analyserNode: c, outputGainNode: h, destinationNode: l } = this;
|
|
195
|
+
e.connect(i), i.connect(n), n.connect(o), o.connect(a), a.connect(c), r.connect(c), d.connect(c), a.connect(l), r.connect(l), d.connect(l), c.connect(h), h.connect(this.audioContext.destination);
|
|
158
196
|
}
|
|
159
197
|
this.setMute(!0), this.audioContext.resume();
|
|
160
198
|
}
|
|
161
199
|
}
|
|
162
|
-
const E = async (
|
|
200
|
+
const E = async (p, t) => {
|
|
163
201
|
try {
|
|
164
|
-
const { format: s, numberOfChannels: e, numberOfFrames: i, sampleRate: n } = t,
|
|
202
|
+
const { format: s, numberOfChannels: e, numberOfFrames: i, sampleRate: n } = t, o = p.createBuffer(e, i, n);
|
|
165
203
|
for (let a = 0; a < e; a++) {
|
|
166
|
-
const
|
|
204
|
+
const r = t.allocationSize({ planeIndex: a }), d = new Uint8Array(r);
|
|
167
205
|
t.copyTo(d, { planeIndex: a });
|
|
168
|
-
const c = new DataView(d.buffer),
|
|
169
|
-
for (let
|
|
170
|
-
let
|
|
206
|
+
const c = new DataView(d.buffer), h = o.getChannelData(a);
|
|
207
|
+
for (let l = 0; l < i; l++) {
|
|
208
|
+
let u;
|
|
171
209
|
switch (s) {
|
|
172
210
|
case "s16":
|
|
173
211
|
// 16-bit signed PCM (范围: -32768 ~ 32767)
|
|
174
212
|
case "s16-planar":
|
|
175
|
-
|
|
213
|
+
u = c.getInt16(l * 2, !0) / 32768;
|
|
176
214
|
break;
|
|
177
215
|
case "f32":
|
|
178
216
|
// 32-bit float (范围: -1.0 ~ 1.0)
|
|
179
217
|
case "f32-planar":
|
|
180
|
-
|
|
218
|
+
u = c.getFloat32(l * 4, !0);
|
|
181
219
|
break;
|
|
182
220
|
case "u8":
|
|
183
221
|
// 8-bit unsigned (范围: 0 ~ 255)
|
|
184
222
|
case "u8-planar":
|
|
185
|
-
|
|
223
|
+
u = (c.getUint8(l) - 128) / 128;
|
|
186
224
|
break;
|
|
187
225
|
default:
|
|
188
226
|
throw new Error(`Unsupported audio format: ${s}`);
|
|
189
227
|
}
|
|
190
|
-
|
|
228
|
+
h[l] = Math.max(-1, Math.min(1, u));
|
|
191
229
|
}
|
|
192
230
|
}
|
|
193
|
-
return
|
|
231
|
+
return o;
|
|
194
232
|
} catch (s) {
|
|
195
233
|
throw console.error("Failed to convert AudioData to AudioBuffer:", s), s;
|
|
196
234
|
}
|
|
197
235
|
};
|
|
198
|
-
class
|
|
236
|
+
class O {
|
|
199
237
|
prAudioStream;
|
|
200
238
|
audioContext;
|
|
201
239
|
destination;
|
|
@@ -205,7 +243,7 @@ class W {
|
|
|
205
243
|
constructor() {
|
|
206
244
|
}
|
|
207
245
|
init = (t) => {
|
|
208
|
-
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
|
|
246
|
+
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 W(this.stream, this.audioContext), this.nextStartTime = 0, this.pendingSources = [];
|
|
209
247
|
};
|
|
210
248
|
async push(t) {
|
|
211
249
|
const { audioData: s, playbackRate: e = 1 } = t;
|
|
@@ -214,10 +252,10 @@ class W {
|
|
|
214
252
|
if (s.close(), !i) return;
|
|
215
253
|
const n = this.audioContext.createBufferSource();
|
|
216
254
|
n.buffer = i, n.playbackRate.value = e;
|
|
217
|
-
const
|
|
218
|
-
n.detune.value =
|
|
219
|
-
const a = Math.max(this.nextStartTime, this.audioContext.currentTime),
|
|
220
|
-
this.nextStartTime = a +
|
|
255
|
+
const o = -1200 * Math.log2(e);
|
|
256
|
+
n.detune.value = o, n.connect(this.destination);
|
|
257
|
+
const a = Math.max(this.nextStartTime, this.audioContext.currentTime), r = i.duration / e;
|
|
258
|
+
this.nextStartTime = a + r, n.start(a), this.pendingSources.push(n), n.onended = () => {
|
|
221
259
|
this.pendingSources = this.pendingSources.filter((d) => d !== n);
|
|
222
260
|
}, this.audioContext.state === "suspended" && await this.audioContext.resume();
|
|
223
261
|
}
|
|
@@ -226,53 +264,15 @@ class W {
|
|
|
226
264
|
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 = [];
|
|
227
265
|
}
|
|
228
266
|
}
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
function j(l) {
|
|
232
|
-
let t;
|
|
233
|
-
try {
|
|
234
|
-
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
235
|
-
const s = new Worker(t, {
|
|
236
|
-
name: l?.name
|
|
237
|
-
});
|
|
238
|
-
return s.addEventListener("error", () => {
|
|
239
|
-
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
240
|
-
}), s;
|
|
241
|
-
} catch {
|
|
242
|
-
return new Worker(
|
|
243
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(R),
|
|
244
|
-
{
|
|
245
|
-
name: l?.name
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
class z {
|
|
251
|
-
worker = new j();
|
|
252
|
-
constructor() {
|
|
253
|
-
}
|
|
254
|
-
init = ({ writable: t }) => this.worker.postMessage({ action: "init", data: { writable: t } }, [t]);
|
|
255
|
-
push = (t) => this.worker.postMessage({ action: "push", data: t });
|
|
256
|
-
setCut = async (t) => this.worker.postMessage({ action: "setCut", data: t });
|
|
257
|
-
setPause = (t) => this.worker.postMessage({ action: "setPause", data: t });
|
|
258
|
-
destroy = () => {
|
|
259
|
-
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
const q = (l) => {
|
|
263
|
-
const t = l.toLowerCase();
|
|
267
|
+
const j = (p) => {
|
|
268
|
+
const t = p.toLowerCase();
|
|
264
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";
|
|
265
|
-
},
|
|
266
|
-
const t =
|
|
270
|
+
}, z = (p) => {
|
|
271
|
+
const t = p?.getTracks() || [];
|
|
267
272
|
for (const s of t)
|
|
268
273
|
s.stop();
|
|
269
|
-
}, A = () => {
|
|
270
|
-
const l = new MediaStreamTrackGenerator({ kind: "video" }), t = new MediaStream([l]), s = new z();
|
|
271
|
-
return s.init({ writable: l.writable }), { worker: s, stream: t, destroy: () => {
|
|
272
|
-
s.destroy(), M(t);
|
|
273
|
-
} };
|
|
274
274
|
};
|
|
275
|
-
class
|
|
275
|
+
class q {
|
|
276
276
|
resolvesMap = /* @__PURE__ */ new Map();
|
|
277
277
|
index = 0;
|
|
278
278
|
constructor() {
|
|
@@ -292,10 +292,10 @@ class $ {
|
|
|
292
292
|
this.resolvesMap.get(t)?.set(a, { resolve: i, timer: 0 });
|
|
293
293
|
return;
|
|
294
294
|
}
|
|
295
|
-
const
|
|
295
|
+
const r = window.setTimeout(() => {
|
|
296
296
|
this.emit(t);
|
|
297
297
|
}, e);
|
|
298
|
-
this.resolvesMap.get(t)?.set(a, { resolve: i, timer:
|
|
298
|
+
this.resolvesMap.get(t)?.set(a, { resolve: i, timer: r });
|
|
299
299
|
});
|
|
300
300
|
emit = async (t) => {
|
|
301
301
|
const s = this.resolvesMap.get(t);
|
|
@@ -307,118 +307,122 @@ class $ {
|
|
|
307
307
|
}
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
|
-
const
|
|
311
|
-
const s = new Uint8Array(
|
|
310
|
+
const $ = (p, t) => {
|
|
311
|
+
const s = new Uint8Array(p), e = new Uint8Array(t), i = new Uint8Array(11 + s.length + e.length);
|
|
312
312
|
let n = 0;
|
|
313
313
|
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;
|
|
314
|
-
},
|
|
314
|
+
}, S = (p) => {
|
|
315
315
|
let t = 0;
|
|
316
|
-
const s = new DataView(
|
|
316
|
+
const s = new DataView(p.buffer), e = s.getUint8(t);
|
|
317
317
|
if (t = t + 1, e !== 1) throw new Error("Invalid AVC version");
|
|
318
318
|
const i = s.getUint8(t) & 255;
|
|
319
319
|
t = t + 1;
|
|
320
320
|
const n = s.getUint8(t) & 255;
|
|
321
321
|
t = t + 1;
|
|
322
|
-
const
|
|
322
|
+
const o = s.getUint8(t) & 255;
|
|
323
323
|
t = t + 1;
|
|
324
|
-
const d = `avc1.${Array.from([i, n,
|
|
324
|
+
const d = `avc1.${Array.from([i, n, o], (b) => b.toString(16).padStart(2, "0")).join("")}`, c = (s.getUint8(t) & 3) - 1;
|
|
325
325
|
t = t + 1;
|
|
326
|
-
const
|
|
326
|
+
const h = s.getUint8(t) & 31;
|
|
327
327
|
t = t + 1;
|
|
328
|
-
const
|
|
328
|
+
const l = s.getUint16(t, !1);
|
|
329
329
|
t = t + 2;
|
|
330
|
-
const
|
|
331
|
-
t = t +
|
|
330
|
+
const u = new Uint8Array(s.buffer.slice(t, t + l));
|
|
331
|
+
t = t + l;
|
|
332
332
|
const g = s.getUint8(t) & 31;
|
|
333
333
|
t = t + 1;
|
|
334
334
|
const f = s.getUint16(t, !1);
|
|
335
335
|
t = t + 2;
|
|
336
|
-
const
|
|
337
|
-
return t = t + f, { version: e, codec: d, profile: i, compatibility: n, level:
|
|
338
|
-
},
|
|
339
|
-
const t = new Uint8Array(4 +
|
|
340
|
-
return new DataView(t.buffer).setUint32(0,
|
|
341
|
-
},
|
|
336
|
+
const y = new Uint8Array(s.buffer.slice(t, t + f));
|
|
337
|
+
return t = t + f, { version: e, codec: d, profile: i, compatibility: n, level: o, lengthSizeMinusOne: c, numOfSequenceParameterSets: h, sequenceParameterSetLength: l, sps: u, numOfPictureParameterSets: g, pictureParameterSetLength: f, pps: y };
|
|
338
|
+
}, H = (p) => {
|
|
339
|
+
const t = new Uint8Array(4 + p.length);
|
|
340
|
+
return new DataView(t.buffer).setUint32(0, p.length, !1), t.set(p, 4), t;
|
|
341
|
+
}, K = (p) => {
|
|
342
342
|
let t = 0;
|
|
343
|
-
for (const i of
|
|
343
|
+
for (const i of p)
|
|
344
344
|
t += i.length;
|
|
345
345
|
const s = new Uint8Array(t);
|
|
346
346
|
let e = 0;
|
|
347
|
-
for (const i of
|
|
347
|
+
for (const i of p) {
|
|
348
348
|
const n = i;
|
|
349
349
|
s.set(n, e), e += n.length;
|
|
350
350
|
}
|
|
351
351
|
return s;
|
|
352
|
-
},
|
|
353
|
-
const t = new DataView(
|
|
352
|
+
}, X = (p) => {
|
|
353
|
+
const t = new DataView(p.buffer);
|
|
354
354
|
let s = 0, e, i, n;
|
|
355
355
|
e = t.getUint32(s, !1), s += 4;
|
|
356
356
|
{
|
|
357
|
-
const
|
|
358
|
-
i = { forbidden_zero_bit: a, nal_ref_idc:
|
|
357
|
+
const o = t.getUint8(s), a = o >> 7 & 1, r = o >> 5 & 3, d = o & 31;
|
|
358
|
+
i = { forbidden_zero_bit: a, nal_ref_idc: r, nal_unit_type: d }, s += 1;
|
|
359
359
|
}
|
|
360
360
|
{
|
|
361
|
-
const
|
|
362
|
-
n = new Uint8Array(t.buffer.slice(s, s +
|
|
361
|
+
const o = e - 1;
|
|
362
|
+
n = new Uint8Array(t.buffer.slice(s, s + o));
|
|
363
363
|
}
|
|
364
364
|
return { size: e, header: i, data: n };
|
|
365
365
|
};
|
|
366
|
-
class
|
|
366
|
+
class A {
|
|
367
367
|
#e = {
|
|
368
|
-
timeout: 5 * 1e3
|
|
368
|
+
timeout: 5 * 1e3,
|
|
369
|
+
check: !1
|
|
369
370
|
};
|
|
370
|
-
#t;
|
|
371
|
+
#t = null;
|
|
372
|
+
// 实例变量:统一管理当前请求的中止
|
|
371
373
|
constructor(t = {}) {
|
|
372
374
|
this.#e = { ...this.#e, ...t };
|
|
373
375
|
}
|
|
374
376
|
/**
|
|
375
|
-
*
|
|
376
|
-
* @param input string | URL | Request
|
|
377
|
-
* @param init RequestInit
|
|
377
|
+
* 检查资源可用性(HEAD 请求)—— 用实例变量控制器
|
|
378
378
|
*/
|
|
379
|
-
|
|
380
|
-
this
|
|
381
|
-
const n =
|
|
382
|
-
this.#t?.abort(
|
|
383
|
-
},
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
379
|
+
#s = (t, s) => new Promise(async (e) => {
|
|
380
|
+
this.#t = new AbortController();
|
|
381
|
+
const { signal: i } = this.#t, n = this.#e.timeout, o = setTimeout(() => {
|
|
382
|
+
this.#t?.abort(`Timeout (${n}ms)`);
|
|
383
|
+
}, n);
|
|
384
|
+
await fetch(t, { cache: "no-store", ...s, method: "HEAD", signal: i }).then((a) => {
|
|
385
|
+
clearTimeout(o), e({ status: a.status === 200 ? "successed" : "failed", reason: a.status === 200 ? "" : `HTTP ${a.status}` });
|
|
386
|
+
}).catch((a) => {
|
|
387
|
+
if (clearTimeout(o), a.name === "AbortError") {
|
|
388
|
+
const r = i.reason || "Actively stopped";
|
|
389
|
+
e({
|
|
390
|
+
status: r.includes("Timeout") ? "timeout" : "stopped",
|
|
391
|
+
reason: r
|
|
392
|
+
});
|
|
393
|
+
} else
|
|
394
|
+
e({ status: "error", reason: a.message });
|
|
395
|
+
});
|
|
391
396
|
});
|
|
392
397
|
/**
|
|
393
|
-
*
|
|
394
|
-
* @param input string | URL | Request
|
|
395
|
-
* @param init RequestInit
|
|
398
|
+
* 发起数据请求(GET/POST 等)—— 用实例变量控制器
|
|
396
399
|
*/
|
|
397
|
-
request =
|
|
400
|
+
request = (t, s) => new Promise(async (e, i) => {
|
|
398
401
|
try {
|
|
399
|
-
|
|
400
|
-
const n = await fetch(t, { ...s, signal:
|
|
401
|
-
e(
|
|
402
|
+
this.stop(), this.#e.check && await this.#s(t), this.#t = new AbortController();
|
|
403
|
+
const { signal: n } = this.#t, o = await fetch(t, { cache: "no-store", ...s, signal: n });
|
|
404
|
+
e(o);
|
|
402
405
|
} catch (n) {
|
|
403
|
-
|
|
406
|
+
i(n);
|
|
404
407
|
}
|
|
405
408
|
});
|
|
406
|
-
/**
|
|
407
|
-
* stop
|
|
408
|
-
*/
|
|
409
409
|
stop = () => {
|
|
410
|
-
this.#t?.signal.aborted === !1
|
|
410
|
+
if (this.#t?.signal.aborted === !1) {
|
|
411
|
+
const t = new Error("Actively stopped.");
|
|
412
|
+
t.name = "AbortError", this.#t.abort(t);
|
|
413
|
+
}
|
|
411
414
|
};
|
|
412
415
|
}
|
|
413
|
-
class
|
|
416
|
+
class tt {
|
|
414
417
|
option = {
|
|
415
418
|
debug: !1,
|
|
416
419
|
frameTrack: !1
|
|
417
420
|
};
|
|
418
|
-
prFetch = new
|
|
419
|
-
getSegmentsFetch = new
|
|
420
|
-
prResolves = new
|
|
421
|
+
prFetch = new A();
|
|
422
|
+
getSegmentsFetch = new A();
|
|
423
|
+
prResolves = new q();
|
|
421
424
|
url = "";
|
|
425
|
+
start_resolve;
|
|
422
426
|
demuxerWorker;
|
|
423
427
|
decoderWorker;
|
|
424
428
|
audioPlayer;
|
|
@@ -438,7 +442,7 @@ class et {
|
|
|
438
442
|
*/
|
|
439
443
|
start = async (t) => {
|
|
440
444
|
await this.stop(), this.url = t;
|
|
441
|
-
const s =
|
|
445
|
+
const s = j(t);
|
|
442
446
|
if (s === "unknown") throw new Error("This address cannot be parsed.");
|
|
443
447
|
switch (this.init(s), s) {
|
|
444
448
|
case "flv":
|
|
@@ -455,14 +459,10 @@ class et {
|
|
|
455
459
|
stop = async () => {
|
|
456
460
|
try {
|
|
457
461
|
this.url = "", clearInterval(this.hls.getSegmentsTimer), this.prFetch.stop(), this.getSegmentsFetch.stop();
|
|
458
|
-
} catch (
|
|
459
|
-
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: error",
|
|
462
|
+
} catch (t) {
|
|
463
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: error", t);
|
|
460
464
|
}
|
|
461
|
-
this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy();
|
|
462
|
-
const t = [...this.cutRenders.keys()];
|
|
463
|
-
for (const s of t)
|
|
464
|
-
this.cutRenders.get(s)?.worker.destroy(), this.cutRenders.delete(s);
|
|
465
|
-
M(this.stream), this.audioPlayer?.destroy();
|
|
465
|
+
this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy(), this.cutRenders = /* @__PURE__ */ new Map(), z(this.stream), this.audioPlayer?.destroy();
|
|
466
466
|
};
|
|
467
467
|
/**
|
|
468
468
|
* 获取媒体流
|
|
@@ -473,13 +473,20 @@ class et {
|
|
|
473
473
|
* @param pause: boolean
|
|
474
474
|
*/
|
|
475
475
|
setPause = (t) => {
|
|
476
|
-
this.renderWorker?.setPause(t);
|
|
476
|
+
this.renderWorker?.setPause({ pause: t });
|
|
477
477
|
};
|
|
478
478
|
/**
|
|
479
479
|
* 是否静音 默认为true
|
|
480
480
|
* @param state?: boolean
|
|
481
481
|
*/
|
|
482
482
|
setMute = (t) => this.audioPlayer?.prAudioStream?.setMute(t);
|
|
483
|
+
/**
|
|
484
|
+
* 设置输出音量
|
|
485
|
+
* @param gain
|
|
486
|
+
*/
|
|
487
|
+
setOutputGain = (t) => {
|
|
488
|
+
this.audioPlayer?.prAudioStream?.setOutputGain(t);
|
|
489
|
+
};
|
|
483
490
|
/**
|
|
484
491
|
* 是否开启追帧
|
|
485
492
|
* @param frameTrack?: boolean
|
|
@@ -499,38 +506,38 @@ class et {
|
|
|
499
506
|
* 创建剪切
|
|
500
507
|
*/
|
|
501
508
|
create: (t, s) => {
|
|
502
|
-
|
|
503
|
-
return
|
|
509
|
+
const e = new MediaStreamTrackGenerator({ kind: "video" }), i = new MediaStream([e]);
|
|
510
|
+
return this.renderWorker?.addCut({ key: t, writable: e.writable, option: s }), this.cutRenders.set(t, { stream: i }), i;
|
|
504
511
|
},
|
|
505
512
|
/**
|
|
506
513
|
* 获取媒体流
|
|
507
514
|
*/
|
|
508
515
|
getStream: (t) => this.cutRenders.get(t)?.stream,
|
|
509
516
|
/**
|
|
510
|
-
*
|
|
511
|
-
* @param pause: boolean
|
|
517
|
+
* 移除剪切
|
|
512
518
|
*/
|
|
513
|
-
|
|
514
|
-
this.
|
|
519
|
+
remove: (t) => {
|
|
520
|
+
this.renderWorker?.delCut(t), this.cutRenders.delete(t);
|
|
515
521
|
},
|
|
516
522
|
/**
|
|
517
|
-
*
|
|
523
|
+
* 设置暂停
|
|
524
|
+
* @param pause: boolean
|
|
518
525
|
*/
|
|
519
|
-
|
|
520
|
-
this.
|
|
526
|
+
setPause: (t, s) => {
|
|
527
|
+
this.renderWorker?.setPause({ key: t, pause: s });
|
|
521
528
|
}
|
|
522
529
|
};
|
|
523
530
|
/**
|
|
524
531
|
* 初始化
|
|
525
532
|
*/
|
|
526
533
|
init = (t) => {
|
|
527
|
-
this.initDecoder(t), this.initRender(), this.initDemuxer(t), this.audioPlayer = new
|
|
534
|
+
this.initDecoder(t), this.initRender(), this.initDemuxer(t), this.audioPlayer = new O(), this.audioPlayer.init();
|
|
528
535
|
};
|
|
529
536
|
/**
|
|
530
537
|
* 初始化解复器
|
|
531
538
|
*/
|
|
532
539
|
initDemuxer = (t) => {
|
|
533
|
-
this.demuxerWorker = new
|
|
540
|
+
this.demuxerWorker = new I(), this.demuxerWorker.init(t), this.demuxerWorker.on.debug = (s) => {
|
|
534
541
|
this.option.debug && this.on.debug && this.on.debug(s);
|
|
535
542
|
}, this.demuxerWorker.on.info = (s) => {
|
|
536
543
|
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);
|
|
@@ -540,8 +547,8 @@ class et {
|
|
|
540
547
|
switch (e) {
|
|
541
548
|
case "audio":
|
|
542
549
|
{
|
|
543
|
-
const { codec: i, sampleRate: n, numberOfChannels:
|
|
544
|
-
this.decoderWorker?.initAudio({ codec: i, sampleRate: n, numberOfChannels:
|
|
550
|
+
const { codec: i, sampleRate: n, numberOfChannels: o } = s;
|
|
551
|
+
this.decoderWorker?.initAudio({ codec: i, sampleRate: n, numberOfChannels: o });
|
|
545
552
|
}
|
|
546
553
|
break;
|
|
547
554
|
case "video":
|
|
@@ -557,14 +564,14 @@ class et {
|
|
|
557
564
|
switch (e) {
|
|
558
565
|
case "audio":
|
|
559
566
|
{
|
|
560
|
-
const { type: i, dts: n, data:
|
|
561
|
-
this.decoderWorker.push({ kind: e, init: { type: i, timestamp: a, data:
|
|
567
|
+
const { type: i, dts: n, data: o } = s, a = n * 1e3;
|
|
568
|
+
this.decoderWorker.push({ kind: e, init: { type: i, timestamp: a, data: o } });
|
|
562
569
|
}
|
|
563
570
|
break;
|
|
564
571
|
case "video":
|
|
565
572
|
{
|
|
566
|
-
const { type: i, dts: n, data:
|
|
567
|
-
this.decoderWorker.push({ kind: e, init: { type: i, timestamp:
|
|
573
|
+
const { type: i, dts: n, data: o, nalus: a = [] } = s, r = n * 1e3;
|
|
574
|
+
this.decoderWorker.push({ kind: e, init: { type: i, timestamp: r, data: o }, nalus: a });
|
|
568
575
|
}
|
|
569
576
|
break;
|
|
570
577
|
}
|
|
@@ -574,25 +581,21 @@ class et {
|
|
|
574
581
|
* 初始化解码器
|
|
575
582
|
*/
|
|
576
583
|
initDecoder = (t) => {
|
|
577
|
-
this.decoderWorker = new
|
|
584
|
+
this.decoderWorker = new L(), this.decoderWorker.init(t);
|
|
578
585
|
const { frameTrack: s = !1 } = this.option;
|
|
579
586
|
this.decoderWorker.setFrameTrack(s), this.decoderWorker.on.audio.decode = (e) => {
|
|
580
587
|
this.audioPlayer?.push(e), this.on.decoder.audio && this.on.decoder.audio(e);
|
|
581
588
|
}, this.decoderWorker.on.audio.error = (e) => {
|
|
582
589
|
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: audio.error ", e), this.on.error && this.on.error(e);
|
|
583
590
|
}, this.decoderWorker.on.video.decode = async (e) => {
|
|
584
|
-
this.renderWorker?.push(e);
|
|
585
|
-
const i = [...this.cutRenders.keys()];
|
|
586
|
-
for (const n of i)
|
|
587
|
-
this.cutRenders.get(n)?.worker.push(e);
|
|
588
|
-
this.on.decoder.video && this.on.decoder.video(e), e.bitmap.close();
|
|
591
|
+
this.start_resolve && (this.start_resolve(!0), this.start_resolve = void 0), this.renderWorker?.push(e), this.on.decoder.video && this.on.decoder.video(e);
|
|
589
592
|
}, this.decoderWorker.on.video.error = (e) => {
|
|
590
593
|
this.on.error && this.on.error(e);
|
|
591
594
|
}, this.decoderWorker.on.nalus = async (e) => {
|
|
592
595
|
for (const i of e) {
|
|
593
596
|
if (i.byteLength <= 4) continue;
|
|
594
|
-
const { header: n, data:
|
|
595
|
-
a === 6 && this.on.decoder.sei && this.on.decoder.sei(
|
|
597
|
+
const { header: n, data: o } = X(i), { nal_unit_type: a } = n;
|
|
598
|
+
a === 6 && this.on.decoder.sei && this.on.decoder.sei(o);
|
|
596
599
|
}
|
|
597
600
|
}, this.decoderWorker.on.analysis = (e) => {
|
|
598
601
|
this.on.decoder.analysis && this.on.decoder.analysis(e);
|
|
@@ -602,25 +605,36 @@ class et {
|
|
|
602
605
|
* 初始化渲染器
|
|
603
606
|
*/
|
|
604
607
|
initRender = () => {
|
|
605
|
-
|
|
606
|
-
|
|
608
|
+
this.renderWorker = new F();
|
|
609
|
+
const t = new MediaStreamTrackGenerator({ kind: "video" }), s = new MediaStream([t]);
|
|
610
|
+
this.renderWorker?.addCut({ writable: t.writable }), this.stream = s, this.renderWorker?.setPause({ pause: !1 });
|
|
607
611
|
};
|
|
608
612
|
flv = {
|
|
609
|
-
start: async () => {
|
|
613
|
+
start: () => new Promise(async (t, s) => {
|
|
610
614
|
try {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
const s = t.body?.getReader();
|
|
614
|
-
if (!s) throw new Error("reader is error.");
|
|
615
|
+
this.start_resolve = t;
|
|
616
|
+
let e, i = 0;
|
|
615
617
|
for (; ; ) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
+
i += 1;
|
|
619
|
+
try {
|
|
620
|
+
e = await this.prFetch.request(this.url);
|
|
621
|
+
} catch (o) {
|
|
622
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error", o);
|
|
623
|
+
}
|
|
624
|
+
if (e?.status === 200 || i === 3) break;
|
|
625
|
+
await new Promise((o) => setTimeout(() => o(!0), 500));
|
|
618
626
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
627
|
+
if (!e || e.status !== 200) return s("request is error.");
|
|
628
|
+
const n = e.body?.getReader();
|
|
629
|
+
if (!n) return s("reader is error.");
|
|
630
|
+
for (; ; ) {
|
|
631
|
+
const { done: o, value: a } = await n.read();
|
|
632
|
+
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
633
|
+
}
|
|
634
|
+
} catch (e) {
|
|
635
|
+
e.name !== "AbortError" && s(e);
|
|
622
636
|
}
|
|
623
|
-
}
|
|
637
|
+
})
|
|
624
638
|
};
|
|
625
639
|
hls = {
|
|
626
640
|
isLive: !1,
|
|
@@ -630,65 +644,75 @@ class et {
|
|
|
630
644
|
parse: async (t) => {
|
|
631
645
|
const i = new TextDecoder("utf-8").decode(t).split(`
|
|
632
646
|
`).map((c) => c.replace("\r", "")), n = this.url.substring(0, this.url.lastIndexOf("/") + 1);
|
|
633
|
-
let
|
|
647
|
+
let o = 4, a = 0, r = !1;
|
|
634
648
|
const d = [];
|
|
635
649
|
for (const c of i)
|
|
636
|
-
c.startsWith("#EXTINF:") ?
|
|
650
|
+
c.startsWith("#EXTINF:") ? o = parseFloat(c.split(":")[1].split(",")[0]) : c.startsWith("#EXT-X-TARGETDURATION:") ? a = parseInt(c.split(":")[1]) : c.startsWith("#EXT-X-ENDLIST") ? r = !1 : c.startsWith("#EXT-X-MEDIA-SEQUENCE:") ? r = !0 : c.includes(".ts") && !c.startsWith("#") && d.push({
|
|
637
651
|
url: c.startsWith("http") ? c : n + c,
|
|
638
|
-
duration:
|
|
639
|
-
isLive:
|
|
652
|
+
duration: o,
|
|
653
|
+
isLive: r
|
|
640
654
|
});
|
|
641
|
-
return { baseUrl: n, targetDuration: a, isLive:
|
|
655
|
+
return { baseUrl: n, targetDuration: a, isLive: r, segments: d };
|
|
642
656
|
},
|
|
643
657
|
getSegments: async () => {
|
|
644
658
|
try {
|
|
645
|
-
let t =
|
|
646
|
-
if (t.status !== 200 && (await new Promise((e) => setTimeout(() => e(!0), 500)), t = await this.getSegmentsFetch.request(this.url)), t.status !== 200 && (await new Promise((e) => setTimeout(() => e(!0), 500)), t = await this.getSegmentsFetch.request(this.url)), t.status !== 200) throw new Error("request is error.");
|
|
647
|
-
const s = t.body?.getReader();
|
|
648
|
-
if (!s) throw new Error("reader is error.");
|
|
659
|
+
let t, s = 0;
|
|
649
660
|
for (; ; ) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
const d = o.findIndex((c) => c === this.hls.url);
|
|
656
|
-
d !== -1 && (o = o.slice(d + 1)), this.hls.urls = o;
|
|
661
|
+
s += 1;
|
|
662
|
+
try {
|
|
663
|
+
t = await this.getSegmentsFetch.request(this.url);
|
|
664
|
+
} catch (i) {
|
|
665
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error", i);
|
|
657
666
|
}
|
|
658
|
-
if (
|
|
667
|
+
if (t?.status === 200 || s === 3) break;
|
|
668
|
+
await new Promise((i) => setTimeout(() => i(!0), 500));
|
|
669
|
+
}
|
|
670
|
+
if (!t || t.status !== 200) throw new Error("request is error.");
|
|
671
|
+
const e = t.body?.getReader();
|
|
672
|
+
if (!e) throw new Error("reader is error.");
|
|
673
|
+
for (; ; ) {
|
|
674
|
+
const { done: i, value: n } = await e.read();
|
|
675
|
+
if (n) {
|
|
676
|
+
const o = await this.hls.parse(n), { segments: a = [], isLive: r = !1 } = o;
|
|
677
|
+
this.hls.isLive = r, r === !1 && (this.option.frameTrack = !1);
|
|
678
|
+
let d = Array.from(a, (h) => h.url);
|
|
679
|
+
const c = d.findIndex((h) => h === this.hls.url);
|
|
680
|
+
c !== -1 && (d = d.slice(c + 1)), this.hls.urls = d;
|
|
681
|
+
}
|
|
682
|
+
if (i || this.url === "") break;
|
|
659
683
|
}
|
|
660
684
|
} catch (t) {
|
|
661
|
-
this.on.error && this.on.error(t);
|
|
685
|
+
t.name !== "AbortError" && this.on.error && this.on.error(t);
|
|
662
686
|
}
|
|
663
687
|
},
|
|
664
|
-
start: async () => {
|
|
688
|
+
start: () => new Promise(async (t, s) => {
|
|
665
689
|
try {
|
|
666
|
-
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)); ; ) {
|
|
667
|
-
const
|
|
668
|
-
if (
|
|
669
|
-
this.hls.url =
|
|
670
|
-
const
|
|
671
|
-
if (!
|
|
690
|
+
for (this.start_resolve = t, this.hls.url = "", this.hls.urls = [], 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)); ; ) {
|
|
691
|
+
const e = this.hls.urls.shift();
|
|
692
|
+
if (e) {
|
|
693
|
+
this.hls.url = e;
|
|
694
|
+
const n = (await this.prFetch.request(e)).body?.getReader();
|
|
695
|
+
if (!n) throw new Error("segment reader is error.");
|
|
672
696
|
for (; ; ) {
|
|
673
|
-
const { done:
|
|
674
|
-
if (
|
|
697
|
+
const { done: o, value: a } = await n.read();
|
|
698
|
+
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
675
699
|
}
|
|
676
700
|
} else
|
|
677
|
-
await new Promise((
|
|
701
|
+
await new Promise((i) => setTimeout(() => i(!0), 300));
|
|
678
702
|
}
|
|
679
|
-
} catch (
|
|
680
|
-
|
|
703
|
+
} catch (e) {
|
|
704
|
+
e.name !== "AbortError" && s(e);
|
|
681
705
|
}
|
|
682
|
-
}
|
|
706
|
+
})
|
|
683
707
|
};
|
|
684
708
|
}
|
|
685
|
-
class
|
|
709
|
+
class Y {
|
|
686
710
|
pendingPayloads = [];
|
|
687
711
|
// 所有原始分段数据
|
|
688
712
|
payload = new Uint8Array(0);
|
|
689
713
|
// 当前正在复解的原始数据
|
|
690
714
|
chunks = [];
|
|
691
|
-
// 复解后的数据
|
|
715
|
+
// 复解后的数据 用于重播使用
|
|
692
716
|
push = (t) => {
|
|
693
717
|
this.pendingPayloads.push(t);
|
|
694
718
|
};
|
|
@@ -700,15 +724,15 @@ class Q {
|
|
|
700
724
|
return e.set(this.payload, 0), e.set(s, this.payload.byteLength), this.payload = e, new DataView(this.payload.buffer);
|
|
701
725
|
};
|
|
702
726
|
pushChunk = (t) => {
|
|
703
|
-
this.chunks.push(t), this.chunks.length >
|
|
727
|
+
this.chunks.push(t), this.chunks.length > 100 && this.chunks.shift();
|
|
704
728
|
};
|
|
705
729
|
destroy = () => {
|
|
706
730
|
this.pendingPayloads = [], this.payload = new Uint8Array(0), this.chunks = [];
|
|
707
731
|
};
|
|
708
732
|
}
|
|
709
|
-
const
|
|
733
|
+
const Q = (p) => {
|
|
710
734
|
let t = "unknown";
|
|
711
|
-
switch (
|
|
735
|
+
switch (p) {
|
|
712
736
|
case 1:
|
|
713
737
|
case 2:
|
|
714
738
|
case 27:
|
|
@@ -729,7 +753,7 @@ const J = (l) => {
|
|
|
729
753
|
}
|
|
730
754
|
return t;
|
|
731
755
|
};
|
|
732
|
-
class
|
|
756
|
+
class J {
|
|
733
757
|
pat;
|
|
734
758
|
pmt;
|
|
735
759
|
audioConfig;
|
|
@@ -757,46 +781,46 @@ class Z {
|
|
|
757
781
|
let e = s;
|
|
758
782
|
const i = this.parseHeader(t, e);
|
|
759
783
|
e += 4;
|
|
760
|
-
const { transport_error_indicator: n, pid:
|
|
761
|
-
if (n === 1 ||
|
|
784
|
+
const { transport_error_indicator: n, pid: o, payload_unit_start_indicator: a, adaptation_field_control: r } = i;
|
|
785
|
+
if (n === 1 || o === void 0) return;
|
|
762
786
|
let d = 184;
|
|
763
|
-
if (
|
|
787
|
+
if (r === 2 || r === 3) {
|
|
764
788
|
const c = t.getUint8(e);
|
|
765
789
|
e += 1, this.parseAdaptationField(t, e), e += c, d -= c;
|
|
766
790
|
}
|
|
767
|
-
if (
|
|
791
|
+
if (r === 3 && (d -= 1), r === 1 || r === 3) {
|
|
768
792
|
const c = new Uint8Array(t.buffer.slice(e, e + d));
|
|
769
|
-
if (
|
|
793
|
+
if (o === 0) return this.parsePAT(t, e);
|
|
770
794
|
{
|
|
771
|
-
const { programs:
|
|
772
|
-
if (
|
|
795
|
+
const { programs: u = [] } = this.pat || {};
|
|
796
|
+
if (u.find((f) => f.pmt_pid === o)) return this.parsePMT(t, e);
|
|
773
797
|
}
|
|
774
|
-
const { streams:
|
|
775
|
-
if (
|
|
798
|
+
const { streams: h = [] } = this.pmt || {}, l = h.find((u) => u.elementary_pid === o);
|
|
799
|
+
if (l) {
|
|
776
800
|
if (a === 1) {
|
|
777
|
-
const
|
|
778
|
-
if (
|
|
779
|
-
switch (
|
|
801
|
+
const u = this.payloadMap.get(o);
|
|
802
|
+
if (u) {
|
|
803
|
+
switch (l.kind) {
|
|
780
804
|
case "audio":
|
|
781
805
|
{
|
|
782
|
-
const g = await this.parseAudio(
|
|
806
|
+
const g = await this.parseAudio(u);
|
|
783
807
|
this.on.chunk && this.on.chunk(g);
|
|
784
808
|
}
|
|
785
809
|
break;
|
|
786
810
|
case "video":
|
|
787
811
|
{
|
|
788
|
-
const g = await this.parseVideo(
|
|
812
|
+
const g = await this.parseVideo(u);
|
|
789
813
|
this.on.chunk && this.on.chunk(g), await new Promise((f) => setTimeout(() => f(!0), 0));
|
|
790
814
|
}
|
|
791
815
|
break;
|
|
792
816
|
}
|
|
793
|
-
this.payloadMap.delete(
|
|
817
|
+
this.payloadMap.delete(o);
|
|
794
818
|
}
|
|
795
819
|
}
|
|
796
820
|
{
|
|
797
|
-
this.payloadMap.has(
|
|
798
|
-
const
|
|
799
|
-
g.set(
|
|
821
|
+
this.payloadMap.has(o) || this.payloadMap.set(o, new Uint8Array());
|
|
822
|
+
const u = this.payloadMap.get(o), g = new Uint8Array(u.byteLength + c.byteLength);
|
|
823
|
+
g.set(u, 0), g.set(c, u.byteLength), this.payloadMap.set(o, g);
|
|
800
824
|
}
|
|
801
825
|
}
|
|
802
826
|
}
|
|
@@ -804,10 +828,10 @@ class Z {
|
|
|
804
828
|
// Header
|
|
805
829
|
parseHeader = (t, s) => {
|
|
806
830
|
let e = s;
|
|
807
|
-
const i = t.getUint8(e), n = t.getUint8(e + 1),
|
|
808
|
-
if (
|
|
809
|
-
const d = (n & 64) >> 6, c = (n & 32) >> 5,
|
|
810
|
-
return { sync_byte: i, transport_error_indicator:
|
|
831
|
+
const i = t.getUint8(e), n = t.getUint8(e + 1), o = t.getUint8(e + 2), a = t.getUint8(e + 3), r = (n & 128) >> 7;
|
|
832
|
+
if (r === 1) return { sync_byte: i, transport_error_indicator: r };
|
|
833
|
+
const d = (n & 64) >> 6, c = (n & 32) >> 5, h = (n & 31) << 8 | o, l = (a & 192) >> 6, u = a >> 4 & 3, g = a & 15;
|
|
834
|
+
return { sync_byte: i, transport_error_indicator: r, payload_unit_start_indicator: d, transport_priority: c, pid: h, transport_scrambling_control: l, adaptation_field_control: u, continuity_counter: g };
|
|
811
835
|
};
|
|
812
836
|
// PAT表
|
|
813
837
|
parsePAT = (t, s) => {
|
|
@@ -815,29 +839,29 @@ class Z {
|
|
|
815
839
|
{
|
|
816
840
|
const a = t.getUint8(e);
|
|
817
841
|
e += 1;
|
|
818
|
-
const
|
|
819
|
-
if (e += 1,
|
|
842
|
+
const r = t.getUint8(e);
|
|
843
|
+
if (e += 1, r !== 0) throw new Error("Invalid PAT table_id");
|
|
820
844
|
const d = t.getUint16(e) & 4095;
|
|
821
845
|
e += 2;
|
|
822
846
|
const c = t.getUint16(e);
|
|
823
847
|
e += 2;
|
|
824
|
-
const
|
|
848
|
+
const h = (t.getUint8(e) & 62) >> 1, l = t.getUint8(e) & 1;
|
|
825
849
|
e += 1;
|
|
826
|
-
const
|
|
850
|
+
const u = t.getUint8(e);
|
|
827
851
|
e += 1;
|
|
828
852
|
const g = t.getUint8(e);
|
|
829
|
-
e += 1, i = { pointer_field: a, table_id:
|
|
853
|
+
e += 1, i = { pointer_field: a, table_id: r, section_length: d, transport_stream_id: c, version_number: h, current_next_indicator: l, section_number: u, last_section_number: g };
|
|
830
854
|
}
|
|
831
855
|
const n = [];
|
|
832
856
|
{
|
|
833
|
-
const a = i.section_length - 5 - 4,
|
|
834
|
-
for (; e <
|
|
857
|
+
const a = i.section_length - 5 - 4, r = e + a;
|
|
858
|
+
for (; e < r; ) {
|
|
835
859
|
const d = t.getUint16(e), c = t.getUint16(e + 2) & 8191;
|
|
836
860
|
e += 4, d !== 0 && c >= 32 && c <= 8190 && n.push({ program_number: d, pmt_pid: c });
|
|
837
861
|
}
|
|
838
862
|
}
|
|
839
|
-
const
|
|
840
|
-
this.pat = { header: i, programs: n, crc32:
|
|
863
|
+
const o = t.getUint32(e);
|
|
864
|
+
this.pat = { header: i, programs: n, crc32: o }, this.on.debug && this.on.debug({ pat: this.pat });
|
|
841
865
|
};
|
|
842
866
|
// PMT表
|
|
843
867
|
parsePMT = (t, s) => {
|
|
@@ -845,132 +869,132 @@ class Z {
|
|
|
845
869
|
{
|
|
846
870
|
const a = t.getUint8(e);
|
|
847
871
|
e += 1;
|
|
848
|
-
const
|
|
849
|
-
if (e += 1,
|
|
872
|
+
const r = t.getUint8(e);
|
|
873
|
+
if (e += 1, r !== 2) throw new Error("Invalid PMT table_id");
|
|
850
874
|
const d = t.getUint16(e) & 4095;
|
|
851
875
|
e += 2;
|
|
852
876
|
const c = t.getUint16(e);
|
|
853
877
|
e += 2;
|
|
854
|
-
const
|
|
878
|
+
const h = (t.getUint8(e) & 62) >> 1, l = t.getUint8(e) & 1;
|
|
855
879
|
e += 1;
|
|
856
|
-
const
|
|
880
|
+
const u = t.getUint8(e);
|
|
857
881
|
e += 1;
|
|
858
882
|
const g = t.getUint8(e);
|
|
859
883
|
e += 1;
|
|
860
884
|
const f = t.getUint16(e) & 8191;
|
|
861
885
|
e += 2;
|
|
862
|
-
const
|
|
863
|
-
e += 2, i = { pointer_field: a, table_id:
|
|
886
|
+
const y = t.getUint16(e) & 4095;
|
|
887
|
+
e += 2, i = { pointer_field: a, table_id: r, section_length: d, transport_stream_id: c, version_number: h, current_next_indicator: l, section_number: u, last_section_number: g, pcr_pid: f, program_info_length: y };
|
|
864
888
|
}
|
|
865
889
|
const n = [];
|
|
866
890
|
{
|
|
867
|
-
const a = i.section_length - 9 - 4,
|
|
868
|
-
for (; e <
|
|
869
|
-
const d = t.getUint8(e), c =
|
|
870
|
-
if (e += 5,
|
|
871
|
-
console.warn(`Invalid elementary_pid: 0x${
|
|
891
|
+
const a = i.section_length - 9 - 4, r = e + a;
|
|
892
|
+
for (; e < r; ) {
|
|
893
|
+
const d = t.getUint8(e), c = Q(d), h = t.getUint16(e + 1) & 8191, l = t.getUint16(e + 3) & 4095;
|
|
894
|
+
if (e += 5, h < 32 || h > 8190) {
|
|
895
|
+
console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);
|
|
872
896
|
continue;
|
|
873
897
|
}
|
|
874
|
-
n.push({ kind: c, stream_type: d, elementary_pid:
|
|
898
|
+
n.push({ kind: c, stream_type: d, elementary_pid: h, es_info_length: l });
|
|
875
899
|
}
|
|
876
900
|
}
|
|
877
|
-
const
|
|
878
|
-
this.pmt = { header: i, streams: n, crc32:
|
|
901
|
+
const o = t.getUint32(e);
|
|
902
|
+
this.pmt = { header: i, streams: n, crc32: o }, this.on.debug && this.on.debug({ pmt: this.pmt });
|
|
879
903
|
};
|
|
880
904
|
// AdaptationField
|
|
881
905
|
parseAdaptationField = (t, s) => {
|
|
882
|
-
let e = s, i, n,
|
|
883
|
-
const
|
|
906
|
+
let e = s, i, n, o, a;
|
|
907
|
+
const r = t.getUint8(e), d = !!(r & 128), c = !!(r & 64), h = !!(r & 32), l = !!(r & 16), u = !!(r & 8), g = !!(r & 4), f = !!(r & 2), y = !!(r & 1);
|
|
884
908
|
e += 1;
|
|
885
909
|
const b = (k, w) => {
|
|
886
910
|
let U = BigInt(0);
|
|
887
911
|
U |= BigInt(k.getUint16(w)) << 25n, U |= BigInt(k.getUint16(w + 1)) << 17n, U |= BigInt(k.getUint16(w + 2)) << 9n, U |= BigInt(k.getUint16(w + 3)) << 1n, U |= BigInt(k.getUint16(w + 4) >> 7);
|
|
888
|
-
const
|
|
889
|
-
return U = U * 300n + BigInt(
|
|
912
|
+
const P = (k.getUint16(w + 4) & 1) << 8 | k.getUint16(w + 5);
|
|
913
|
+
return U = U * 300n + BigInt(P), U;
|
|
890
914
|
};
|
|
891
|
-
if (
|
|
915
|
+
if (l && (i = b(t, e), e += 6), u && (n = b(t, e), e += 6), g && (o = t.getInt8(e), e += 1), f) {
|
|
892
916
|
const k = t.getUint8(e);
|
|
893
917
|
e += 1, a = new Uint8Array(t.buffer, e, k), e += k;
|
|
894
918
|
}
|
|
895
|
-
return { discontinuity_indicator: d, random_access_indicator: c, elementary_stream_priority_indicator:
|
|
919
|
+
return { discontinuity_indicator: d, random_access_indicator: c, elementary_stream_priority_indicator: h, pcr_flag: l, opcr_flag: u, splicing_point_flag: g, transport_private_data_flag: f, adaptation_field_extension_flag: y, pcr: i, opcr: n, splice_countdown: o, transport_private_data: a };
|
|
896
920
|
};
|
|
897
921
|
parseAudio = async (t) => {
|
|
898
922
|
const s = new DataView(t.buffer);
|
|
899
923
|
let e = 0, i, n;
|
|
900
924
|
{
|
|
901
|
-
const
|
|
902
|
-
if (e += 3, !
|
|
925
|
+
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
926
|
+
if (e += 3, !o)
|
|
903
927
|
throw new Error("invalid ts audio payload.");
|
|
904
928
|
const a = s.getUint8(e);
|
|
905
929
|
e += 1;
|
|
906
|
-
const
|
|
930
|
+
const r = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
907
931
|
e += 2;
|
|
908
|
-
let d, c,
|
|
932
|
+
let d, c, h, l, u;
|
|
909
933
|
{
|
|
910
|
-
const
|
|
911
|
-
e += 1, d =
|
|
934
|
+
const y = s.getUint8(e);
|
|
935
|
+
e += 1, d = y >> 4 & 3, c = (y >> 3 & 1) === 1, h = (y >> 2 & 1) === 1, l = (y >> 1 & 1) === 1, u = (y & 1) === 1;
|
|
912
936
|
}
|
|
913
937
|
let g, f;
|
|
914
938
|
{
|
|
915
|
-
const
|
|
939
|
+
const y = s.getUint8(e);
|
|
916
940
|
e += 1;
|
|
917
|
-
const b =
|
|
941
|
+
const b = y >> 6, k = s.getUint8(e);
|
|
918
942
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
919
943
|
}
|
|
920
|
-
i = { stream_id: a, pes_packet_length:
|
|
944
|
+
i = { stream_id: a, pes_packet_length: r, scrambling_control: d, priority: c, data_alignment: h, copyright: l, original_copy: u, pts: g, dts: f };
|
|
921
945
|
}
|
|
922
946
|
n = t.slice(e);
|
|
923
947
|
{
|
|
924
948
|
if (!this.audioConfig && s.getUint8(e) === 255) {
|
|
925
|
-
const
|
|
926
|
-
let
|
|
927
|
-
g =
|
|
928
|
-
const f = `mp4a.40.${
|
|
929
|
-
this.audioConfig = { kind: "audio", codec: f, sampleRate: b, numberOfChannels:
|
|
949
|
+
const h = s.getUint8(e + 2), l = s.getUint8(e + 3);
|
|
950
|
+
let u, g;
|
|
951
|
+
g = h >> 2 & 15, u = (h & 1) << 2 | l >> 6;
|
|
952
|
+
const f = `mp4a.40.${u}`, b = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350][g];
|
|
953
|
+
this.audioConfig = { kind: "audio", codec: f, sampleRate: b, numberOfChannels: u }, this.on.config && this.on.config(this.audioConfig);
|
|
930
954
|
}
|
|
931
|
-
const { dts:
|
|
932
|
-
return { kind: "audio", type: "key", dts:
|
|
955
|
+
const { dts: o = 0, pts: a = 0 } = i, r = a - o, d = n.slice(7);
|
|
956
|
+
return { kind: "audio", type: "key", dts: o, pts: a, cts: r, data: d };
|
|
933
957
|
}
|
|
934
958
|
};
|
|
935
959
|
parseVideo = async (t) => {
|
|
936
960
|
const s = new DataView(t.buffer);
|
|
937
961
|
let e = 0, i, n;
|
|
938
962
|
{
|
|
939
|
-
const
|
|
940
|
-
if (e += 3, !
|
|
963
|
+
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
964
|
+
if (e += 3, !o)
|
|
941
965
|
throw new Error("invalid ts video payload.");
|
|
942
966
|
const a = s.getUint8(e);
|
|
943
967
|
e += 1;
|
|
944
|
-
const
|
|
968
|
+
const r = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
945
969
|
e += 2;
|
|
946
|
-
let d, c,
|
|
970
|
+
let d, c, h, l, u;
|
|
947
971
|
{
|
|
948
|
-
const
|
|
949
|
-
e += 1, d =
|
|
972
|
+
const y = s.getUint8(e);
|
|
973
|
+
e += 1, d = y >> 4 & 3, c = (y >> 3 & 1) === 1, h = (y >> 2 & 1) === 1, l = (y >> 1 & 1) === 1, u = (y & 1) === 1;
|
|
950
974
|
}
|
|
951
975
|
let g, f;
|
|
952
976
|
{
|
|
953
|
-
const
|
|
977
|
+
const y = s.getUint8(e);
|
|
954
978
|
e += 1;
|
|
955
|
-
const b =
|
|
979
|
+
const b = y >> 6, k = s.getUint8(e);
|
|
956
980
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
957
981
|
}
|
|
958
|
-
i = { stream_id: a, pes_packet_length:
|
|
982
|
+
i = { stream_id: a, pes_packet_length: r, scrambling_control: d, priority: c, data_alignment: h, copyright: l, original_copy: u, pts: g, dts: f };
|
|
959
983
|
}
|
|
960
984
|
n = t.slice(e);
|
|
961
985
|
{
|
|
962
|
-
const
|
|
986
|
+
const o = this.getNalus(n);
|
|
963
987
|
if (!this.videoConfig) {
|
|
964
|
-
let
|
|
965
|
-
if (
|
|
966
|
-
const f =
|
|
967
|
-
this.videoConfig = { kind: "video", codec:
|
|
988
|
+
let u, g;
|
|
989
|
+
if (u = o.find((y) => y.type === 7)?.nalu.slice(4), g = o.find((y) => y.type === 8)?.nalu.slice(4), u && g) {
|
|
990
|
+
const f = $(u, g), { codec: y } = S(f);
|
|
991
|
+
this.videoConfig = { kind: "video", codec: y, description: f, sps: u, pps: g }, this.on.config && this.on.config(this.videoConfig);
|
|
968
992
|
}
|
|
969
993
|
}
|
|
970
994
|
const a = [];
|
|
971
|
-
let
|
|
972
|
-
for (const
|
|
973
|
-
const { type: g, nalu: f } =
|
|
995
|
+
let r = "delta";
|
|
996
|
+
for (const u of o) {
|
|
997
|
+
const { type: g, nalu: f } = u;
|
|
974
998
|
switch (g) {
|
|
975
999
|
case 6:
|
|
976
1000
|
// sei
|
|
@@ -978,23 +1002,23 @@ class Z {
|
|
|
978
1002
|
a.push(f);
|
|
979
1003
|
break;
|
|
980
1004
|
case 1:
|
|
981
|
-
|
|
1005
|
+
r = "delta", a.push(f);
|
|
982
1006
|
break;
|
|
983
1007
|
case 5:
|
|
984
|
-
|
|
1008
|
+
r = "key", a.push(f);
|
|
985
1009
|
break;
|
|
986
1010
|
}
|
|
987
1011
|
}
|
|
988
|
-
const d =
|
|
989
|
-
return { kind: "video", type:
|
|
1012
|
+
const d = K(a), { dts: c = 0, pts: h = 0 } = i, l = h - c;
|
|
1013
|
+
return { kind: "video", type: r, dts: c, pts: h, cts: l, data: d, nalus: a };
|
|
990
1014
|
}
|
|
991
1015
|
};
|
|
992
1016
|
/**
|
|
993
1017
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
994
1018
|
*/
|
|
995
1019
|
parsePtsDts(t, s) {
|
|
996
|
-
const e = t.getUint8(s), i = t.getUint8(s + 1), n = t.getUint8(s + 2),
|
|
997
|
-
return Number(
|
|
1020
|
+
const e = t.getUint8(s), i = t.getUint8(s + 1), n = t.getUint8(s + 2), o = t.getUint8(s + 3), a = t.getUint8(s + 4), r = (BigInt(e) & 0b00001110n) << 29n | (BigInt(i) & 0b11111111n) << 22n | (BigInt(n) & 0b11111110n) << 14n | (BigInt(o) & 0b11111111n) << 7n | (BigInt(a) & 0b11111110n) >> 1n;
|
|
1021
|
+
return Number(r) / 90;
|
|
998
1022
|
}
|
|
999
1023
|
getNalus = (t) => {
|
|
1000
1024
|
const s = [];
|
|
@@ -1014,17 +1038,17 @@ class Z {
|
|
|
1014
1038
|
}
|
|
1015
1039
|
break;
|
|
1016
1040
|
}
|
|
1017
|
-
let
|
|
1018
|
-
if (t[e - 1] === 0 && (
|
|
1019
|
-
const a = t.slice(i, i +
|
|
1020
|
-
s.push({ type: n, nalu:
|
|
1041
|
+
let o = e - i;
|
|
1042
|
+
if (t[e - 1] === 0 && (o -= 1), o !== 0) {
|
|
1043
|
+
const a = t.slice(i, i + o), r = H(a);
|
|
1044
|
+
s.push({ type: n, nalu: r });
|
|
1021
1045
|
}
|
|
1022
1046
|
}
|
|
1023
1047
|
return s;
|
|
1024
1048
|
};
|
|
1025
1049
|
}
|
|
1026
|
-
const T = (
|
|
1027
|
-
class
|
|
1050
|
+
const T = (p, t) => p.getUint8(t) << 16 | p.getUint8(t + 1) << 8 | p.getUint8(t + 2);
|
|
1051
|
+
class Z {
|
|
1028
1052
|
audioConfig;
|
|
1029
1053
|
videoConfig;
|
|
1030
1054
|
header;
|
|
@@ -1036,53 +1060,53 @@ class tt {
|
|
|
1036
1060
|
parse = async (t) => {
|
|
1037
1061
|
let s = 0;
|
|
1038
1062
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
1039
|
-
const i = this.parseTagHeader(t, s + 4), { tagType: n, dataSize:
|
|
1063
|
+
const i = this.parseTagHeader(t, s + 4), { tagType: n, dataSize: o, timestamp: a } = i;
|
|
1040
1064
|
if (n) {
|
|
1041
|
-
const
|
|
1065
|
+
const r = this.parseTagBody(n, t, s + 4 + 11, o);
|
|
1042
1066
|
switch (n) {
|
|
1043
1067
|
case "script":
|
|
1044
|
-
this.on.info && this.on.info(
|
|
1068
|
+
this.on.info && this.on.info(r);
|
|
1045
1069
|
break;
|
|
1046
1070
|
case "audio":
|
|
1047
1071
|
{
|
|
1048
|
-
const { accPacketType: d } =
|
|
1072
|
+
const { accPacketType: d } = r;
|
|
1049
1073
|
if (d === 0) {
|
|
1050
|
-
const { codec: c, sampleRate:
|
|
1051
|
-
this.audioConfig = { kind: "audio", codec: c, sampleRate:
|
|
1074
|
+
const { codec: c, sampleRate: h, channelConfiguration: l } = r;
|
|
1075
|
+
this.audioConfig = { kind: "audio", codec: c, sampleRate: h, numberOfChannels: l }, this.on.config && this.on.config(this.audioConfig);
|
|
1052
1076
|
} else {
|
|
1053
|
-
const { cts: c, data:
|
|
1054
|
-
this.on.chunk && this.on.chunk({ kind: "audio", type:
|
|
1077
|
+
const { cts: c, data: h } = r, l = "key", u = c === void 0 ? void 0 : c + a;
|
|
1078
|
+
this.on.chunk && this.on.chunk({ kind: "audio", type: l, dts: a, pts: u, cts: c, data: h });
|
|
1055
1079
|
}
|
|
1056
1080
|
}
|
|
1057
1081
|
break;
|
|
1058
1082
|
case "video":
|
|
1059
1083
|
{
|
|
1060
|
-
const { avcPacketType: d } =
|
|
1084
|
+
const { avcPacketType: d } = r;
|
|
1061
1085
|
if (d === 0) {
|
|
1062
|
-
const { codec: c, sps:
|
|
1063
|
-
this.videoConfig = { kind: "video", codec: c, description:
|
|
1086
|
+
const { codec: c, sps: h, pps: l, data: u } = r;
|
|
1087
|
+
this.videoConfig = { kind: "video", codec: c, description: u, sps: h, pps: l }, this.on.config && this.on.config(this.videoConfig);
|
|
1064
1088
|
} else {
|
|
1065
|
-
const { frameType: c, cts:
|
|
1066
|
-
this.on.chunk && this.on.chunk({ kind: "video", type: g, dts: a, pts: f, cts:
|
|
1089
|
+
const { frameType: c, cts: h, data: l, nalus: u } = r, g = c === 1 ? "key" : "delta", f = h === void 0 ? void 0 : h + a;
|
|
1090
|
+
this.on.chunk && this.on.chunk({ kind: "video", type: g, dts: a, pts: f, cts: h, data: l, nalus: u });
|
|
1067
1091
|
}
|
|
1068
1092
|
}
|
|
1069
1093
|
break;
|
|
1070
1094
|
}
|
|
1071
|
-
s = s + 4 + 11 +
|
|
1095
|
+
s = s + 4 + 11 + o;
|
|
1072
1096
|
}
|
|
1073
|
-
await new Promise((
|
|
1097
|
+
await new Promise((r) => setTimeout(() => r(!0), 8));
|
|
1074
1098
|
}
|
|
1075
1099
|
return s;
|
|
1076
1100
|
};
|
|
1077
1101
|
// Header
|
|
1078
1102
|
parseHeader = (t, s) => {
|
|
1079
|
-
let e, i, n,
|
|
1103
|
+
let e, i, n, o;
|
|
1080
1104
|
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2), i = t.getUint8(3);
|
|
1081
1105
|
{
|
|
1082
|
-
const
|
|
1106
|
+
const r = t.getUint8(0).toString(2).padStart(5, "0").split(""), [, , d, , c] = r;
|
|
1083
1107
|
n = { audio: c === "1", video: d === "1" };
|
|
1084
1108
|
}
|
|
1085
|
-
|
|
1109
|
+
o = t.getUint32(5), this.header = { signature: e, version: i, flags: n, dataOffset: o };
|
|
1086
1110
|
};
|
|
1087
1111
|
// 是否是完整tag
|
|
1088
1112
|
isSurplusTag = (t, s) => {
|
|
@@ -1099,11 +1123,11 @@ class tt {
|
|
|
1099
1123
|
return e;
|
|
1100
1124
|
};
|
|
1101
1125
|
parseTagHeader = (t, s) => {
|
|
1102
|
-
let e, i, n,
|
|
1126
|
+
let e, i, n, o, a;
|
|
1103
1127
|
{
|
|
1104
|
-
const
|
|
1128
|
+
const r = t.getUint8(s);
|
|
1105
1129
|
let d;
|
|
1106
|
-
switch (
|
|
1130
|
+
switch (r) {
|
|
1107
1131
|
case 18:
|
|
1108
1132
|
d = "script";
|
|
1109
1133
|
break;
|
|
@@ -1116,7 +1140,7 @@ class tt {
|
|
|
1116
1140
|
}
|
|
1117
1141
|
e = d;
|
|
1118
1142
|
}
|
|
1119
|
-
return i = T(t, s + 1), n = T(t, s + 4),
|
|
1143
|
+
return i = T(t, s + 1), n = T(t, s + 4), o = t.getUint8(s + 7), a = T(t, s + 8), { tagType: e, dataSize: i, timestamp: n, timestampExtended: o, streamID: a };
|
|
1120
1144
|
};
|
|
1121
1145
|
parseTagBody = (t, s, e, i) => {
|
|
1122
1146
|
let n;
|
|
@@ -1151,44 +1175,44 @@ class tt {
|
|
|
1151
1175
|
};
|
|
1152
1176
|
parseAudio = (t, s, e) => {
|
|
1153
1177
|
let i = s;
|
|
1154
|
-
const n = t.getUint8(i),
|
|
1178
|
+
const n = t.getUint8(i), o = n >> 4 & 15, a = n >> 2 & 3, r = n >> 1 & 1, d = n & 1;
|
|
1155
1179
|
i = i + 1;
|
|
1156
1180
|
const c = t.getUint8(i);
|
|
1157
1181
|
i = i + 1;
|
|
1158
|
-
const
|
|
1159
|
-
if (
|
|
1160
|
-
const
|
|
1161
|
-
return { soundFormat:
|
|
1182
|
+
const h = e, l = new Uint8Array(t.buffer.slice(i, i + h));
|
|
1183
|
+
if (o === 10 && c === 0) {
|
|
1184
|
+
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], w = `mp4a.40.${f}`, U = k[y];
|
|
1185
|
+
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l, samplingFrequencyIndex: y, channelConfiguration: b, codec: w, sampleRate: U };
|
|
1162
1186
|
}
|
|
1163
|
-
return { soundFormat:
|
|
1187
|
+
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l };
|
|
1164
1188
|
};
|
|
1165
1189
|
parseVideo = (t, s, e) => {
|
|
1166
1190
|
let i = s;
|
|
1167
|
-
const n = t.getUint8(i),
|
|
1191
|
+
const n = t.getUint8(i), o = n >> 4 & 15, a = n & 15;
|
|
1168
1192
|
i = i + 1;
|
|
1169
|
-
const
|
|
1193
|
+
const r = t.getUint8(i);
|
|
1170
1194
|
i = i + 1;
|
|
1171
1195
|
const d = T(t, i);
|
|
1172
1196
|
i = i + 3;
|
|
1173
|
-
const c = e - 5,
|
|
1197
|
+
const c = e - 5, h = new Uint8Array(t.buffer.slice(i, i + c));
|
|
1174
1198
|
switch (a) {
|
|
1175
1199
|
case 7:
|
|
1176
|
-
if (
|
|
1177
|
-
const
|
|
1178
|
-
return { frameType:
|
|
1179
|
-
} else if (
|
|
1180
|
-
const
|
|
1181
|
-
for (; !(i + 4 >
|
|
1200
|
+
if (r === 0) {
|
|
1201
|
+
const l = S(h);
|
|
1202
|
+
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, ...l };
|
|
1203
|
+
} else if (r === 1) {
|
|
1204
|
+
const l = [], u = i + e - 5;
|
|
1205
|
+
for (; !(i + 4 > u); ) {
|
|
1182
1206
|
const g = t.getUint32(i, !1), f = new Uint8Array(t.buffer.slice(i, i + 4 + g));
|
|
1183
|
-
i += 4 + g,
|
|
1207
|
+
i += 4 + g, l.push(f);
|
|
1184
1208
|
}
|
|
1185
|
-
return { frameType:
|
|
1209
|
+
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, nalus: l };
|
|
1186
1210
|
}
|
|
1187
1211
|
break;
|
|
1188
1212
|
default:
|
|
1189
1213
|
throw new Error("Unsupported codecID");
|
|
1190
1214
|
}
|
|
1191
|
-
return { frameType:
|
|
1215
|
+
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h };
|
|
1192
1216
|
};
|
|
1193
1217
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1194
1218
|
getAMFName = (t, s, e) => {
|
|
@@ -1196,74 +1220,74 @@ class tt {
|
|
|
1196
1220
|
return this.textDecoder?.decode(i) || "";
|
|
1197
1221
|
};
|
|
1198
1222
|
getAMFValue = (t, s, e) => {
|
|
1199
|
-
let i = s, n,
|
|
1223
|
+
let i = s, n, o = 0;
|
|
1200
1224
|
switch (e) {
|
|
1201
1225
|
case 0:
|
|
1202
|
-
n = t.getFloat64(i, !1),
|
|
1226
|
+
n = t.getFloat64(i, !1), o = 8;
|
|
1203
1227
|
break;
|
|
1204
1228
|
case 1:
|
|
1205
|
-
n = !!t.getUint8(i),
|
|
1229
|
+
n = !!t.getUint8(i), o = 1;
|
|
1206
1230
|
break;
|
|
1207
1231
|
case 2:
|
|
1208
1232
|
{
|
|
1209
1233
|
n = "";
|
|
1210
|
-
const
|
|
1234
|
+
const r = t.getUint16(i, !1);
|
|
1211
1235
|
i = i + 2;
|
|
1212
|
-
const d = new Int8Array(t.buffer, i,
|
|
1213
|
-
n = (this.textDecoder?.decode(d) || "").trim(),
|
|
1236
|
+
const d = new Int8Array(t.buffer, i, r).filter((h) => h !== 0);
|
|
1237
|
+
n = (this.textDecoder?.decode(d) || "").trim(), o = 2 + r;
|
|
1214
1238
|
}
|
|
1215
1239
|
break;
|
|
1216
1240
|
case 3:
|
|
1217
1241
|
for (n = {}; i < t.byteLength; ) {
|
|
1218
|
-
const
|
|
1219
|
-
if (
|
|
1242
|
+
const r = t.getUint16(i, !1);
|
|
1243
|
+
if (r === 0) break;
|
|
1220
1244
|
i = i + 2;
|
|
1221
|
-
const d = this.getAMFName(t, i,
|
|
1222
|
-
i = i +
|
|
1245
|
+
const d = this.getAMFName(t, i, r);
|
|
1246
|
+
i = i + r;
|
|
1223
1247
|
const c = this.getAmfType(t, i);
|
|
1224
1248
|
if (c === 6) break;
|
|
1225
1249
|
i = i + 1;
|
|
1226
|
-
const
|
|
1227
|
-
i = i +
|
|
1250
|
+
const h = this.getAMFValue(t, i, c);
|
|
1251
|
+
i = i + h.length, n[d] = h.value, o = 2 + r + 1 + h.length;
|
|
1228
1252
|
}
|
|
1229
1253
|
break;
|
|
1230
1254
|
case 8:
|
|
1231
1255
|
{
|
|
1232
1256
|
n = {};
|
|
1233
|
-
const
|
|
1257
|
+
const r = t.getUint32(i, !1);
|
|
1234
1258
|
i = i + 4;
|
|
1235
|
-
for (let d = 0; d <
|
|
1259
|
+
for (let d = 0; d < r; d++) {
|
|
1236
1260
|
const c = t.getUint16(i, !1);
|
|
1237
1261
|
i = i + 2;
|
|
1238
|
-
const
|
|
1262
|
+
const h = this.getAMFName(t, i, c);
|
|
1239
1263
|
i = i + c;
|
|
1240
|
-
const
|
|
1264
|
+
const l = this.getAmfType(t, i);
|
|
1241
1265
|
i = i + 1;
|
|
1242
|
-
const
|
|
1243
|
-
i = i +
|
|
1266
|
+
const u = this.getAMFValue(t, i, l);
|
|
1267
|
+
i = i + u.length, n[h] = u.value, o = 2 + c + 1 + u.length;
|
|
1244
1268
|
}
|
|
1245
1269
|
}
|
|
1246
1270
|
break;
|
|
1247
1271
|
case 10:
|
|
1248
1272
|
{
|
|
1249
1273
|
n = [];
|
|
1250
|
-
const
|
|
1274
|
+
const r = t.getUint32(i, !1);
|
|
1251
1275
|
i = i + 4;
|
|
1252
|
-
for (let d = 0; d <
|
|
1276
|
+
for (let d = 0; d < r; d++) {
|
|
1253
1277
|
const c = this.getAmfType(t, i);
|
|
1254
1278
|
i = i + 1;
|
|
1255
|
-
const
|
|
1256
|
-
i = i +
|
|
1279
|
+
const h = this.getAMFValue(t, i, c);
|
|
1280
|
+
i = i + h.length, n.push(h.value), o = 1 + h.length;
|
|
1257
1281
|
}
|
|
1258
1282
|
}
|
|
1259
1283
|
break;
|
|
1260
1284
|
}
|
|
1261
|
-
return { amfType: e, length:
|
|
1285
|
+
return { amfType: e, length: o, value: n };
|
|
1262
1286
|
};
|
|
1263
1287
|
}
|
|
1264
|
-
class
|
|
1288
|
+
class et {
|
|
1265
1289
|
pattern;
|
|
1266
|
-
cacher = new
|
|
1290
|
+
cacher = new Y();
|
|
1267
1291
|
isParseing = !1;
|
|
1268
1292
|
offset = 0;
|
|
1269
1293
|
parser;
|
|
@@ -1273,10 +1297,10 @@ class st {
|
|
|
1273
1297
|
init = (t) => {
|
|
1274
1298
|
switch (this.destroy(), this.pattern = t, this.pattern) {
|
|
1275
1299
|
case "flv":
|
|
1276
|
-
this.parser = new
|
|
1300
|
+
this.parser = new Z();
|
|
1277
1301
|
break;
|
|
1278
1302
|
case "hls":
|
|
1279
|
-
this.parser = new
|
|
1303
|
+
this.parser = new J();
|
|
1280
1304
|
break;
|
|
1281
1305
|
default:
|
|
1282
1306
|
throw new Error("is error pattern.");
|
|
@@ -1308,7 +1332,7 @@ class st {
|
|
|
1308
1332
|
}
|
|
1309
1333
|
};
|
|
1310
1334
|
}
|
|
1311
|
-
class
|
|
1335
|
+
class st {
|
|
1312
1336
|
pattern = "flv";
|
|
1313
1337
|
audioDecoderConfig;
|
|
1314
1338
|
audioDecoder;
|
|
@@ -1402,22 +1426,20 @@ class it {
|
|
|
1402
1426
|
};
|
|
1403
1427
|
decode = () => {
|
|
1404
1428
|
if (this.isProcessing !== !0) {
|
|
1405
|
-
for (this.isProcessing = !0; ; ) {
|
|
1406
|
-
this.currentChunk = this.pendingChunks.shift();
|
|
1429
|
+
for (this.isProcessing = !0; this.currentChunk = this.pendingChunks.shift(), !!this.currentChunk; ) {
|
|
1407
1430
|
const t = this.pendingChunks.length;
|
|
1408
1431
|
if (this.frameTrack) {
|
|
1409
1432
|
const [i, n] = this.fameTrackOption[this.pattern];
|
|
1410
1433
|
if (t <= i && (this.isFrameTrack = !1), t >= n && (this.isFrameTrack = !0), this.isFrameTrack) {
|
|
1411
|
-
const
|
|
1412
|
-
this.decodingSpeedRatio = Number(
|
|
1434
|
+
const o = Math.min(1 + (t - i) / 100, this.maxDecodingSpeedRatio);
|
|
1435
|
+
this.decodingSpeedRatio = Number(o.toFixed(1));
|
|
1413
1436
|
} else
|
|
1414
1437
|
this.decodingSpeedRatio = 1;
|
|
1415
1438
|
}
|
|
1416
1439
|
if (this.on.analysis) {
|
|
1417
|
-
const { decodingSpeed: i, decodingSpeedRatio: n, fps:
|
|
1418
|
-
this.on.analysis({ decodingSpeed: i, decodingSpeedRatio: n, fps:
|
|
1440
|
+
const { decodingSpeed: i, decodingSpeedRatio: n, fps: o } = this;
|
|
1441
|
+
this.on.analysis({ decodingSpeed: i, decodingSpeedRatio: n, fps: o, cacheLength: t });
|
|
1419
1442
|
}
|
|
1420
|
-
if (!this.currentChunk) break;
|
|
1421
1443
|
const { kind: s, init: e } = this.currentChunk;
|
|
1422
1444
|
switch (s) {
|
|
1423
1445
|
case "audio":
|
|
@@ -1460,49 +1482,67 @@ class it {
|
|
|
1460
1482
|
}
|
|
1461
1483
|
};
|
|
1462
1484
|
}
|
|
1463
|
-
class
|
|
1464
|
-
|
|
1465
|
-
writer;
|
|
1466
|
-
cutOption;
|
|
1467
|
-
pause = !1;
|
|
1485
|
+
class it {
|
|
1486
|
+
renderMap = /* @__PURE__ */ new Map();
|
|
1468
1487
|
constructor() {
|
|
1469
1488
|
}
|
|
1470
|
-
init = ({ writable: t }) => {
|
|
1471
|
-
this.destroy(), this.writable = t, this.writer = this.writable.getWriter();
|
|
1472
|
-
};
|
|
1473
1489
|
push = async (t) => {
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1490
|
+
const { timestamp: s } = t, { bitmap: e } = t;
|
|
1491
|
+
if (e.height === 0 || e.width === 0)
|
|
1492
|
+
return e.close();
|
|
1493
|
+
const i = [...this.renderMap.keys()];
|
|
1494
|
+
for (const n of i) {
|
|
1495
|
+
const o = this.renderMap.get(n);
|
|
1496
|
+
if (!o) continue;
|
|
1497
|
+
const { pause: a = !1, writer: r, option: d } = o;
|
|
1498
|
+
if (a !== !0)
|
|
1499
|
+
if (n === "default" || !d) {
|
|
1500
|
+
const c = new VideoFrame(e, { timestamp: s });
|
|
1501
|
+
r.write(c), c.close();
|
|
1502
|
+
} else {
|
|
1503
|
+
const { sx: c = 0, sy: h = 0, sw: l = e.width, sh: u = e.height } = d, g = await createImageBitmap(e, c, h, l, u), f = new VideoFrame(g, { timestamp: s });
|
|
1504
|
+
g.close(), r.write(f), f.close();
|
|
1505
|
+
}
|
|
1480
1506
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1507
|
+
e.close();
|
|
1508
|
+
};
|
|
1509
|
+
/**
|
|
1510
|
+
* 增加剪切
|
|
1511
|
+
*/
|
|
1512
|
+
addCut = (t) => {
|
|
1513
|
+
const { key: s, writable: e, option: i } = { key: "default", ...t }, n = e.getWriter();
|
|
1514
|
+
this.renderMap.set(s, { writable: e, writer: n, option: i, pause: !1 });
|
|
1515
|
+
};
|
|
1516
|
+
/**
|
|
1517
|
+
* 删除剪切
|
|
1518
|
+
*/
|
|
1519
|
+
delCut = (t) => {
|
|
1520
|
+
this.renderMap.delete(t);
|
|
1483
1521
|
};
|
|
1484
1522
|
/**
|
|
1485
1523
|
* 设置剪切
|
|
1486
1524
|
*/
|
|
1487
1525
|
setCut = (t) => {
|
|
1488
|
-
|
|
1526
|
+
const { key: s, cutOption: e } = { key: "default", ...t }, i = this.renderMap.get(s);
|
|
1527
|
+
i && this.renderMap.set(s, { ...i, option: e });
|
|
1489
1528
|
};
|
|
1490
1529
|
/**
|
|
1491
1530
|
* 设置暂停
|
|
1492
1531
|
*/
|
|
1493
1532
|
setPause = (t) => {
|
|
1494
|
-
|
|
1533
|
+
const { key: s, pause: e } = { key: "default", ...t }, i = this.renderMap.get(s);
|
|
1534
|
+
i && this.renderMap.set(s, { ...i, pause: e });
|
|
1495
1535
|
};
|
|
1496
1536
|
destroy = () => {
|
|
1497
|
-
this.
|
|
1537
|
+
this.renderMap = /* @__PURE__ */ new Map();
|
|
1498
1538
|
};
|
|
1499
1539
|
}
|
|
1500
1540
|
export {
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1541
|
+
st as Decoder,
|
|
1542
|
+
L as DecoderWorker,
|
|
1543
|
+
et as Demuxer,
|
|
1544
|
+
I as DemuxerWorker,
|
|
1545
|
+
tt as PrPlayer,
|
|
1546
|
+
it as Render,
|
|
1547
|
+
F as RenderWorker
|
|
1508
1548
|
};
|