pr-player 0.2.14 → 0.3.0
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 +486 -450
- 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,78 +243,36 @@ 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;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this.
|
|
222
|
-
|
|
223
|
-
}, this.audioContext.state === "suspended" && await this.audioContext.resume();
|
|
224
|
-
} finally {
|
|
225
|
-
s.close();
|
|
226
|
-
}
|
|
250
|
+
if (!this.audioContext || !this.destination) return;
|
|
251
|
+
let i = await E(this.audioContext, s);
|
|
252
|
+
if (s.close(), !i) return;
|
|
253
|
+
const n = this.audioContext.createBufferSource();
|
|
254
|
+
n.buffer = i, n.playbackRate.value = e;
|
|
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 = () => {
|
|
259
|
+
this.pendingSources = this.pendingSources.filter((d) => d !== n);
|
|
260
|
+
}, this.audioContext.state === "suspended" && await this.audioContext.resume();
|
|
227
261
|
}
|
|
228
262
|
getStream = () => this.prAudioStream?.getStream();
|
|
229
263
|
destroy() {
|
|
230
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 = [];
|
|
231
265
|
}
|
|
232
266
|
}
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
function j(l) {
|
|
236
|
-
let t;
|
|
237
|
-
try {
|
|
238
|
-
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
239
|
-
const s = new Worker(t, {
|
|
240
|
-
name: l?.name
|
|
241
|
-
});
|
|
242
|
-
return s.addEventListener("error", () => {
|
|
243
|
-
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
244
|
-
}), s;
|
|
245
|
-
} catch {
|
|
246
|
-
return new Worker(
|
|
247
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(R),
|
|
248
|
-
{
|
|
249
|
-
name: l?.name
|
|
250
|
-
}
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
class z {
|
|
255
|
-
worker = new j();
|
|
256
|
-
constructor() {
|
|
257
|
-
}
|
|
258
|
-
init = ({ writable: t }) => this.worker.postMessage({ action: "init", data: { writable: t } }, [t]);
|
|
259
|
-
push = (t) => this.worker.postMessage({ action: "push", data: t });
|
|
260
|
-
setCut = async (t) => this.worker.postMessage({ action: "setCut", data: t });
|
|
261
|
-
setPause = (t) => this.worker.postMessage({ action: "setPause", data: t });
|
|
262
|
-
destroy = () => {
|
|
263
|
-
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
const q = (l) => {
|
|
267
|
-
const t = l.toLowerCase();
|
|
267
|
+
const j = (p) => {
|
|
268
|
+
const t = p.toLowerCase();
|
|
268
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";
|
|
269
|
-
},
|
|
270
|
-
const t =
|
|
270
|
+
}, z = (p) => {
|
|
271
|
+
const t = p?.getTracks() || [];
|
|
271
272
|
for (const s of t)
|
|
272
273
|
s.stop();
|
|
273
|
-
}, A = () => {
|
|
274
|
-
const l = new MediaStreamTrackGenerator({ kind: "video" }), t = new MediaStream([l]), s = new z();
|
|
275
|
-
return s.init({ writable: l.writable }), { worker: s, stream: t, destroy: () => {
|
|
276
|
-
s.destroy(), M(t);
|
|
277
|
-
} };
|
|
278
274
|
};
|
|
279
|
-
class
|
|
275
|
+
class q {
|
|
280
276
|
resolvesMap = /* @__PURE__ */ new Map();
|
|
281
277
|
index = 0;
|
|
282
278
|
constructor() {
|
|
@@ -296,10 +292,10 @@ class $ {
|
|
|
296
292
|
this.resolvesMap.get(t)?.set(a, { resolve: i, timer: 0 });
|
|
297
293
|
return;
|
|
298
294
|
}
|
|
299
|
-
const
|
|
295
|
+
const r = window.setTimeout(() => {
|
|
300
296
|
this.emit(t);
|
|
301
297
|
}, e);
|
|
302
|
-
this.resolvesMap.get(t)?.set(a, { resolve: i, timer:
|
|
298
|
+
this.resolvesMap.get(t)?.set(a, { resolve: i, timer: r });
|
|
303
299
|
});
|
|
304
300
|
emit = async (t) => {
|
|
305
301
|
const s = this.resolvesMap.get(t);
|
|
@@ -311,118 +307,122 @@ class $ {
|
|
|
311
307
|
}
|
|
312
308
|
};
|
|
313
309
|
}
|
|
314
|
-
const
|
|
315
|
-
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);
|
|
316
312
|
let n = 0;
|
|
317
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;
|
|
318
|
-
},
|
|
314
|
+
}, S = (p) => {
|
|
319
315
|
let t = 0;
|
|
320
|
-
const s = new DataView(
|
|
316
|
+
const s = new DataView(p.buffer), e = s.getUint8(t);
|
|
321
317
|
if (t = t + 1, e !== 1) throw new Error("Invalid AVC version");
|
|
322
318
|
const i = s.getUint8(t) & 255;
|
|
323
319
|
t = t + 1;
|
|
324
320
|
const n = s.getUint8(t) & 255;
|
|
325
321
|
t = t + 1;
|
|
326
|
-
const
|
|
322
|
+
const o = s.getUint8(t) & 255;
|
|
327
323
|
t = t + 1;
|
|
328
|
-
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;
|
|
329
325
|
t = t + 1;
|
|
330
|
-
const
|
|
326
|
+
const h = s.getUint8(t) & 31;
|
|
331
327
|
t = t + 1;
|
|
332
|
-
const
|
|
328
|
+
const l = s.getUint16(t, !1);
|
|
333
329
|
t = t + 2;
|
|
334
|
-
const
|
|
335
|
-
t = t +
|
|
330
|
+
const u = new Uint8Array(s.buffer.slice(t, t + l));
|
|
331
|
+
t = t + l;
|
|
336
332
|
const g = s.getUint8(t) & 31;
|
|
337
333
|
t = t + 1;
|
|
338
334
|
const f = s.getUint16(t, !1);
|
|
339
335
|
t = t + 2;
|
|
340
|
-
const
|
|
341
|
-
return t = t + f, { version: e, codec: d, profile: i, compatibility: n, level:
|
|
342
|
-
},
|
|
343
|
-
const t = new Uint8Array(4 +
|
|
344
|
-
return new DataView(t.buffer).setUint32(0,
|
|
345
|
-
},
|
|
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) => {
|
|
346
342
|
let t = 0;
|
|
347
|
-
for (const i of
|
|
343
|
+
for (const i of p)
|
|
348
344
|
t += i.length;
|
|
349
345
|
const s = new Uint8Array(t);
|
|
350
346
|
let e = 0;
|
|
351
|
-
for (const i of
|
|
347
|
+
for (const i of p) {
|
|
352
348
|
const n = i;
|
|
353
349
|
s.set(n, e), e += n.length;
|
|
354
350
|
}
|
|
355
351
|
return s;
|
|
356
|
-
},
|
|
357
|
-
const t = new DataView(
|
|
352
|
+
}, X = (p) => {
|
|
353
|
+
const t = new DataView(p.buffer);
|
|
358
354
|
let s = 0, e, i, n;
|
|
359
355
|
e = t.getUint32(s, !1), s += 4;
|
|
360
356
|
{
|
|
361
|
-
const
|
|
362
|
-
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;
|
|
363
359
|
}
|
|
364
360
|
{
|
|
365
|
-
const
|
|
366
|
-
n = new Uint8Array(t.buffer.slice(s, s +
|
|
361
|
+
const o = e - 1;
|
|
362
|
+
n = new Uint8Array(t.buffer.slice(s, s + o));
|
|
367
363
|
}
|
|
368
364
|
return { size: e, header: i, data: n };
|
|
369
365
|
};
|
|
370
|
-
class
|
|
366
|
+
class A {
|
|
371
367
|
#e = {
|
|
372
|
-
timeout: 5 * 1e3
|
|
368
|
+
timeout: 5 * 1e3,
|
|
369
|
+
check: !1
|
|
373
370
|
};
|
|
374
|
-
#t;
|
|
371
|
+
#t = null;
|
|
372
|
+
// 实例变量:统一管理当前请求的中止
|
|
375
373
|
constructor(t = {}) {
|
|
376
374
|
this.#e = { ...this.#e, ...t };
|
|
377
375
|
}
|
|
378
376
|
/**
|
|
379
|
-
*
|
|
380
|
-
* @param input string | URL | Request
|
|
381
|
-
* @param init RequestInit
|
|
377
|
+
* 检查资源可用性(HEAD 请求)—— 用实例变量控制器
|
|
382
378
|
*/
|
|
383
|
-
|
|
384
|
-
this
|
|
385
|
-
const n =
|
|
386
|
-
this.#t?.abort(
|
|
387
|
-
},
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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
|
+
});
|
|
395
396
|
});
|
|
396
397
|
/**
|
|
397
|
-
*
|
|
398
|
-
* @param input string | URL | Request
|
|
399
|
-
* @param init RequestInit
|
|
398
|
+
* 发起数据请求(GET/POST 等)—— 用实例变量控制器
|
|
400
399
|
*/
|
|
401
|
-
request =
|
|
400
|
+
request = (t, s) => new Promise(async (e, i) => {
|
|
402
401
|
try {
|
|
403
|
-
|
|
404
|
-
const n = await fetch(t, { ...s, signal:
|
|
405
|
-
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);
|
|
406
405
|
} catch (n) {
|
|
407
|
-
|
|
406
|
+
i(n);
|
|
408
407
|
}
|
|
409
408
|
});
|
|
410
|
-
/**
|
|
411
|
-
* stop
|
|
412
|
-
*/
|
|
413
409
|
stop = () => {
|
|
414
|
-
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
|
+
}
|
|
415
414
|
};
|
|
416
415
|
}
|
|
417
|
-
class
|
|
416
|
+
class tt {
|
|
418
417
|
option = {
|
|
419
418
|
debug: !1,
|
|
420
419
|
frameTrack: !1
|
|
421
420
|
};
|
|
422
|
-
prFetch = new
|
|
423
|
-
getSegmentsFetch = new
|
|
424
|
-
prResolves = new
|
|
421
|
+
prFetch = new A();
|
|
422
|
+
getSegmentsFetch = new A();
|
|
423
|
+
prResolves = new q();
|
|
425
424
|
url = "";
|
|
425
|
+
start_resolve;
|
|
426
426
|
demuxerWorker;
|
|
427
427
|
decoderWorker;
|
|
428
428
|
audioPlayer;
|
|
@@ -442,7 +442,7 @@ class et {
|
|
|
442
442
|
*/
|
|
443
443
|
start = async (t) => {
|
|
444
444
|
await this.stop(), this.url = t;
|
|
445
|
-
const s =
|
|
445
|
+
const s = j(t);
|
|
446
446
|
if (s === "unknown") throw new Error("This address cannot be parsed.");
|
|
447
447
|
switch (this.init(s), s) {
|
|
448
448
|
case "flv":
|
|
@@ -459,14 +459,10 @@ class et {
|
|
|
459
459
|
stop = async () => {
|
|
460
460
|
try {
|
|
461
461
|
this.url = "", clearInterval(this.hls.getSegmentsTimer), this.prFetch.stop(), this.getSegmentsFetch.stop();
|
|
462
|
-
} catch (
|
|
463
|
-
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);
|
|
464
464
|
}
|
|
465
|
-
this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy();
|
|
466
|
-
const t = [...this.cutRenders.keys()];
|
|
467
|
-
for (const s of t)
|
|
468
|
-
this.cutRenders.get(s)?.worker.destroy(), this.cutRenders.delete(s);
|
|
469
|
-
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();
|
|
470
466
|
};
|
|
471
467
|
/**
|
|
472
468
|
* 获取媒体流
|
|
@@ -477,13 +473,20 @@ class et {
|
|
|
477
473
|
* @param pause: boolean
|
|
478
474
|
*/
|
|
479
475
|
setPause = (t) => {
|
|
480
|
-
this.renderWorker?.setPause(t);
|
|
476
|
+
this.renderWorker?.setPause({ pause: t });
|
|
481
477
|
};
|
|
482
478
|
/**
|
|
483
479
|
* 是否静音 默认为true
|
|
484
480
|
* @param state?: boolean
|
|
485
481
|
*/
|
|
486
482
|
setMute = (t) => this.audioPlayer?.prAudioStream?.setMute(t);
|
|
483
|
+
/**
|
|
484
|
+
* 设置输出音量
|
|
485
|
+
* @param gain
|
|
486
|
+
*/
|
|
487
|
+
setOutputGain = (t) => {
|
|
488
|
+
this.audioPlayer?.prAudioStream?.setOutputGain(t);
|
|
489
|
+
};
|
|
487
490
|
/**
|
|
488
491
|
* 是否开启追帧
|
|
489
492
|
* @param frameTrack?: boolean
|
|
@@ -503,38 +506,38 @@ class et {
|
|
|
503
506
|
* 创建剪切
|
|
504
507
|
*/
|
|
505
508
|
create: (t, s) => {
|
|
506
|
-
|
|
507
|
-
|
|
509
|
+
const e = new MediaStreamTrackGenerator({ kind: "video" }), i = new MediaStream([e]);
|
|
510
|
+
this.renderWorker?.addCut({ key: t, writable: e.writable, option: s }), this.cutRenders.set(t, { stream: i });
|
|
508
511
|
},
|
|
509
512
|
/**
|
|
510
513
|
* 获取媒体流
|
|
511
514
|
*/
|
|
512
515
|
getStream: (t) => this.cutRenders.get(t)?.stream,
|
|
513
516
|
/**
|
|
514
|
-
*
|
|
515
|
-
* @param pause: boolean
|
|
517
|
+
* 移除剪切
|
|
516
518
|
*/
|
|
517
|
-
|
|
518
|
-
this.
|
|
519
|
+
remove: (t) => {
|
|
520
|
+
this.renderWorker?.delCut(t), this.cutRenders.delete(t);
|
|
519
521
|
},
|
|
520
522
|
/**
|
|
521
|
-
*
|
|
523
|
+
* 设置暂停
|
|
524
|
+
* @param pause: boolean
|
|
522
525
|
*/
|
|
523
|
-
|
|
524
|
-
this.
|
|
526
|
+
setPause: (t, s) => {
|
|
527
|
+
this.renderWorker?.setPause({ key: t, pause: s });
|
|
525
528
|
}
|
|
526
529
|
};
|
|
527
530
|
/**
|
|
528
531
|
* 初始化
|
|
529
532
|
*/
|
|
530
533
|
init = (t) => {
|
|
531
|
-
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();
|
|
532
535
|
};
|
|
533
536
|
/**
|
|
534
537
|
* 初始化解复器
|
|
535
538
|
*/
|
|
536
539
|
initDemuxer = (t) => {
|
|
537
|
-
this.demuxerWorker = new
|
|
540
|
+
this.demuxerWorker = new I(), this.demuxerWorker.init(t), this.demuxerWorker.on.debug = (s) => {
|
|
538
541
|
this.option.debug && this.on.debug && this.on.debug(s);
|
|
539
542
|
}, this.demuxerWorker.on.info = (s) => {
|
|
540
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);
|
|
@@ -544,8 +547,8 @@ class et {
|
|
|
544
547
|
switch (e) {
|
|
545
548
|
case "audio":
|
|
546
549
|
{
|
|
547
|
-
const { codec: i, sampleRate: n, numberOfChannels:
|
|
548
|
-
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 });
|
|
549
552
|
}
|
|
550
553
|
break;
|
|
551
554
|
case "video":
|
|
@@ -561,14 +564,14 @@ class et {
|
|
|
561
564
|
switch (e) {
|
|
562
565
|
case "audio":
|
|
563
566
|
{
|
|
564
|
-
const { type: i, dts: n, data:
|
|
565
|
-
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 } });
|
|
566
569
|
}
|
|
567
570
|
break;
|
|
568
571
|
case "video":
|
|
569
572
|
{
|
|
570
|
-
const { type: i, dts: n, data:
|
|
571
|
-
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 });
|
|
572
575
|
}
|
|
573
576
|
break;
|
|
574
577
|
}
|
|
@@ -578,25 +581,21 @@ class et {
|
|
|
578
581
|
* 初始化解码器
|
|
579
582
|
*/
|
|
580
583
|
initDecoder = (t) => {
|
|
581
|
-
this.decoderWorker = new
|
|
584
|
+
this.decoderWorker = new L(), this.decoderWorker.init(t);
|
|
582
585
|
const { frameTrack: s = !1 } = this.option;
|
|
583
586
|
this.decoderWorker.setFrameTrack(s), this.decoderWorker.on.audio.decode = (e) => {
|
|
584
587
|
this.audioPlayer?.push(e), this.on.decoder.audio && this.on.decoder.audio(e);
|
|
585
588
|
}, this.decoderWorker.on.audio.error = (e) => {
|
|
586
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);
|
|
587
590
|
}, this.decoderWorker.on.video.decode = async (e) => {
|
|
588
|
-
this.renderWorker?.push(e);
|
|
589
|
-
const i = [...this.cutRenders.keys()];
|
|
590
|
-
for (const n of i)
|
|
591
|
-
this.cutRenders.get(n)?.worker.push(e);
|
|
592
|
-
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);
|
|
593
592
|
}, this.decoderWorker.on.video.error = (e) => {
|
|
594
593
|
this.on.error && this.on.error(e);
|
|
595
594
|
}, this.decoderWorker.on.nalus = async (e) => {
|
|
596
595
|
for (const i of e) {
|
|
597
596
|
if (i.byteLength <= 4) continue;
|
|
598
|
-
const { header: n, data:
|
|
599
|
-
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);
|
|
600
599
|
}
|
|
601
600
|
}, this.decoderWorker.on.analysis = (e) => {
|
|
602
601
|
this.on.decoder.analysis && this.on.decoder.analysis(e);
|
|
@@ -606,25 +605,36 @@ class et {
|
|
|
606
605
|
* 初始化渲染器
|
|
607
606
|
*/
|
|
608
607
|
initRender = () => {
|
|
609
|
-
|
|
610
|
-
|
|
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 });
|
|
611
611
|
};
|
|
612
612
|
flv = {
|
|
613
|
-
start: async () => {
|
|
613
|
+
start: () => new Promise(async (t, s) => {
|
|
614
614
|
try {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
const s = t.body?.getReader();
|
|
618
|
-
if (!s) throw new Error("reader is error.");
|
|
615
|
+
this.start_resolve = t;
|
|
616
|
+
let e, i = 0;
|
|
619
617
|
for (; ; ) {
|
|
620
|
-
|
|
621
|
-
|
|
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));
|
|
622
626
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
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);
|
|
626
636
|
}
|
|
627
|
-
}
|
|
637
|
+
})
|
|
628
638
|
};
|
|
629
639
|
hls = {
|
|
630
640
|
isLive: !1,
|
|
@@ -634,65 +644,75 @@ class et {
|
|
|
634
644
|
parse: async (t) => {
|
|
635
645
|
const i = new TextDecoder("utf-8").decode(t).split(`
|
|
636
646
|
`).map((c) => c.replace("\r", "")), n = this.url.substring(0, this.url.lastIndexOf("/") + 1);
|
|
637
|
-
let
|
|
647
|
+
let o = 4, a = 0, r = !1;
|
|
638
648
|
const d = [];
|
|
639
649
|
for (const c of i)
|
|
640
|
-
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({
|
|
641
651
|
url: c.startsWith("http") ? c : n + c,
|
|
642
|
-
duration:
|
|
643
|
-
isLive:
|
|
652
|
+
duration: o,
|
|
653
|
+
isLive: r
|
|
644
654
|
});
|
|
645
|
-
return { baseUrl: n, targetDuration: a, isLive:
|
|
655
|
+
return { baseUrl: n, targetDuration: a, isLive: r, segments: d };
|
|
646
656
|
},
|
|
647
657
|
getSegments: async () => {
|
|
648
658
|
try {
|
|
649
|
-
let t =
|
|
650
|
-
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.");
|
|
651
|
-
const s = t.body?.getReader();
|
|
652
|
-
if (!s) throw new Error("reader is error.");
|
|
659
|
+
let t, s = 0;
|
|
653
660
|
for (; ; ) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
const d = o.findIndex((c) => c === this.hls.url);
|
|
660
|
-
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);
|
|
661
666
|
}
|
|
662
|
-
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;
|
|
663
683
|
}
|
|
664
684
|
} catch (t) {
|
|
665
|
-
this.on.error && this.on.error(t);
|
|
685
|
+
t.name !== "AbortError" && this.on.error && this.on.error(t);
|
|
666
686
|
}
|
|
667
687
|
},
|
|
668
|
-
start: async () => {
|
|
688
|
+
start: () => new Promise(async (t, s) => {
|
|
669
689
|
try {
|
|
670
|
-
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)); ; ) {
|
|
671
|
-
const
|
|
672
|
-
if (
|
|
673
|
-
this.hls.url =
|
|
674
|
-
const
|
|
675
|
-
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.");
|
|
676
696
|
for (; ; ) {
|
|
677
|
-
const { done:
|
|
678
|
-
if (
|
|
697
|
+
const { done: o, value: a } = await n.read();
|
|
698
|
+
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
679
699
|
}
|
|
680
700
|
} else
|
|
681
|
-
await new Promise((
|
|
701
|
+
await new Promise((i) => setTimeout(() => i(!0), 300));
|
|
682
702
|
}
|
|
683
|
-
} catch (
|
|
684
|
-
|
|
703
|
+
} catch (e) {
|
|
704
|
+
e.name !== "AbortError" && s(e);
|
|
685
705
|
}
|
|
686
|
-
}
|
|
706
|
+
})
|
|
687
707
|
};
|
|
688
708
|
}
|
|
689
|
-
class
|
|
709
|
+
class Y {
|
|
690
710
|
pendingPayloads = [];
|
|
691
711
|
// 所有原始分段数据
|
|
692
712
|
payload = new Uint8Array(0);
|
|
693
713
|
// 当前正在复解的原始数据
|
|
694
714
|
chunks = [];
|
|
695
|
-
// 复解后的数据
|
|
715
|
+
// 复解后的数据 用于重播使用
|
|
696
716
|
push = (t) => {
|
|
697
717
|
this.pendingPayloads.push(t);
|
|
698
718
|
};
|
|
@@ -704,15 +724,15 @@ class Q {
|
|
|
704
724
|
return e.set(this.payload, 0), e.set(s, this.payload.byteLength), this.payload = e, new DataView(this.payload.buffer);
|
|
705
725
|
};
|
|
706
726
|
pushChunk = (t) => {
|
|
707
|
-
this.chunks.push(t), this.chunks.length >
|
|
727
|
+
this.chunks.push(t), this.chunks.length > 100 && this.chunks.shift();
|
|
708
728
|
};
|
|
709
729
|
destroy = () => {
|
|
710
730
|
this.pendingPayloads = [], this.payload = new Uint8Array(0), this.chunks = [];
|
|
711
731
|
};
|
|
712
732
|
}
|
|
713
|
-
const
|
|
733
|
+
const Q = (p) => {
|
|
714
734
|
let t = "unknown";
|
|
715
|
-
switch (
|
|
735
|
+
switch (p) {
|
|
716
736
|
case 1:
|
|
717
737
|
case 2:
|
|
718
738
|
case 27:
|
|
@@ -733,7 +753,7 @@ const J = (l) => {
|
|
|
733
753
|
}
|
|
734
754
|
return t;
|
|
735
755
|
};
|
|
736
|
-
class
|
|
756
|
+
class J {
|
|
737
757
|
pat;
|
|
738
758
|
pmt;
|
|
739
759
|
audioConfig;
|
|
@@ -761,46 +781,46 @@ class Z {
|
|
|
761
781
|
let e = s;
|
|
762
782
|
const i = this.parseHeader(t, e);
|
|
763
783
|
e += 4;
|
|
764
|
-
const { transport_error_indicator: n, pid:
|
|
765
|
-
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;
|
|
766
786
|
let d = 184;
|
|
767
|
-
if (
|
|
787
|
+
if (r === 2 || r === 3) {
|
|
768
788
|
const c = t.getUint8(e);
|
|
769
789
|
e += 1, this.parseAdaptationField(t, e), e += c, d -= c;
|
|
770
790
|
}
|
|
771
|
-
if (
|
|
791
|
+
if (r === 3 && (d -= 1), r === 1 || r === 3) {
|
|
772
792
|
const c = new Uint8Array(t.buffer.slice(e, e + d));
|
|
773
|
-
if (
|
|
793
|
+
if (o === 0) return this.parsePAT(t, e);
|
|
774
794
|
{
|
|
775
|
-
const { programs:
|
|
776
|
-
if (
|
|
795
|
+
const { programs: u = [] } = this.pat || {};
|
|
796
|
+
if (u.find((f) => f.pmt_pid === o)) return this.parsePMT(t, e);
|
|
777
797
|
}
|
|
778
|
-
const { streams:
|
|
779
|
-
if (
|
|
798
|
+
const { streams: h = [] } = this.pmt || {}, l = h.find((u) => u.elementary_pid === o);
|
|
799
|
+
if (l) {
|
|
780
800
|
if (a === 1) {
|
|
781
|
-
const
|
|
782
|
-
if (
|
|
783
|
-
switch (
|
|
801
|
+
const u = this.payloadMap.get(o);
|
|
802
|
+
if (u) {
|
|
803
|
+
switch (l.kind) {
|
|
784
804
|
case "audio":
|
|
785
805
|
{
|
|
786
|
-
const g = await this.parseAudio(
|
|
806
|
+
const g = await this.parseAudio(u);
|
|
787
807
|
this.on.chunk && this.on.chunk(g);
|
|
788
808
|
}
|
|
789
809
|
break;
|
|
790
810
|
case "video":
|
|
791
811
|
{
|
|
792
|
-
const g = await this.parseVideo(
|
|
812
|
+
const g = await this.parseVideo(u);
|
|
793
813
|
this.on.chunk && this.on.chunk(g), await new Promise((f) => setTimeout(() => f(!0), 0));
|
|
794
814
|
}
|
|
795
815
|
break;
|
|
796
816
|
}
|
|
797
|
-
this.payloadMap.delete(
|
|
817
|
+
this.payloadMap.delete(o);
|
|
798
818
|
}
|
|
799
819
|
}
|
|
800
820
|
{
|
|
801
|
-
this.payloadMap.has(
|
|
802
|
-
const
|
|
803
|
-
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);
|
|
804
824
|
}
|
|
805
825
|
}
|
|
806
826
|
}
|
|
@@ -808,10 +828,10 @@ class Z {
|
|
|
808
828
|
// Header
|
|
809
829
|
parseHeader = (t, s) => {
|
|
810
830
|
let e = s;
|
|
811
|
-
const i = t.getUint8(e), n = t.getUint8(e + 1),
|
|
812
|
-
if (
|
|
813
|
-
const d = (n & 64) >> 6, c = (n & 32) >> 5,
|
|
814
|
-
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 };
|
|
815
835
|
};
|
|
816
836
|
// PAT表
|
|
817
837
|
parsePAT = (t, s) => {
|
|
@@ -819,29 +839,29 @@ class Z {
|
|
|
819
839
|
{
|
|
820
840
|
const a = t.getUint8(e);
|
|
821
841
|
e += 1;
|
|
822
|
-
const
|
|
823
|
-
if (e += 1,
|
|
842
|
+
const r = t.getUint8(e);
|
|
843
|
+
if (e += 1, r !== 0) throw new Error("Invalid PAT table_id");
|
|
824
844
|
const d = t.getUint16(e) & 4095;
|
|
825
845
|
e += 2;
|
|
826
846
|
const c = t.getUint16(e);
|
|
827
847
|
e += 2;
|
|
828
|
-
const
|
|
848
|
+
const h = (t.getUint8(e) & 62) >> 1, l = t.getUint8(e) & 1;
|
|
829
849
|
e += 1;
|
|
830
|
-
const
|
|
850
|
+
const u = t.getUint8(e);
|
|
831
851
|
e += 1;
|
|
832
852
|
const g = t.getUint8(e);
|
|
833
|
-
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 };
|
|
834
854
|
}
|
|
835
855
|
const n = [];
|
|
836
856
|
{
|
|
837
|
-
const a = i.section_length - 5 - 4,
|
|
838
|
-
for (; e <
|
|
857
|
+
const a = i.section_length - 5 - 4, r = e + a;
|
|
858
|
+
for (; e < r; ) {
|
|
839
859
|
const d = t.getUint16(e), c = t.getUint16(e + 2) & 8191;
|
|
840
860
|
e += 4, d !== 0 && c >= 32 && c <= 8190 && n.push({ program_number: d, pmt_pid: c });
|
|
841
861
|
}
|
|
842
862
|
}
|
|
843
|
-
const
|
|
844
|
-
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 });
|
|
845
865
|
};
|
|
846
866
|
// PMT表
|
|
847
867
|
parsePMT = (t, s) => {
|
|
@@ -849,132 +869,132 @@ class Z {
|
|
|
849
869
|
{
|
|
850
870
|
const a = t.getUint8(e);
|
|
851
871
|
e += 1;
|
|
852
|
-
const
|
|
853
|
-
if (e += 1,
|
|
872
|
+
const r = t.getUint8(e);
|
|
873
|
+
if (e += 1, r !== 2) throw new Error("Invalid PMT table_id");
|
|
854
874
|
const d = t.getUint16(e) & 4095;
|
|
855
875
|
e += 2;
|
|
856
876
|
const c = t.getUint16(e);
|
|
857
877
|
e += 2;
|
|
858
|
-
const
|
|
878
|
+
const h = (t.getUint8(e) & 62) >> 1, l = t.getUint8(e) & 1;
|
|
859
879
|
e += 1;
|
|
860
|
-
const
|
|
880
|
+
const u = t.getUint8(e);
|
|
861
881
|
e += 1;
|
|
862
882
|
const g = t.getUint8(e);
|
|
863
883
|
e += 1;
|
|
864
884
|
const f = t.getUint16(e) & 8191;
|
|
865
885
|
e += 2;
|
|
866
|
-
const
|
|
867
|
-
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 };
|
|
868
888
|
}
|
|
869
889
|
const n = [];
|
|
870
890
|
{
|
|
871
|
-
const a = i.section_length - 9 - 4,
|
|
872
|
-
for (; e <
|
|
873
|
-
const d = t.getUint8(e), c =
|
|
874
|
-
if (e += 5,
|
|
875
|
-
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)}`);
|
|
876
896
|
continue;
|
|
877
897
|
}
|
|
878
|
-
n.push({ kind: c, stream_type: d, elementary_pid:
|
|
898
|
+
n.push({ kind: c, stream_type: d, elementary_pid: h, es_info_length: l });
|
|
879
899
|
}
|
|
880
900
|
}
|
|
881
|
-
const
|
|
882
|
-
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 });
|
|
883
903
|
};
|
|
884
904
|
// AdaptationField
|
|
885
905
|
parseAdaptationField = (t, s) => {
|
|
886
|
-
let e = s, i, n,
|
|
887
|
-
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);
|
|
888
908
|
e += 1;
|
|
889
909
|
const b = (k, w) => {
|
|
890
910
|
let U = BigInt(0);
|
|
891
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);
|
|
892
|
-
const
|
|
893
|
-
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;
|
|
894
914
|
};
|
|
895
|
-
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) {
|
|
896
916
|
const k = t.getUint8(e);
|
|
897
917
|
e += 1, a = new Uint8Array(t.buffer, e, k), e += k;
|
|
898
918
|
}
|
|
899
|
-
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 };
|
|
900
920
|
};
|
|
901
921
|
parseAudio = async (t) => {
|
|
902
922
|
const s = new DataView(t.buffer);
|
|
903
923
|
let e = 0, i, n;
|
|
904
924
|
{
|
|
905
|
-
const
|
|
906
|
-
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)
|
|
907
927
|
throw new Error("invalid ts audio payload.");
|
|
908
928
|
const a = s.getUint8(e);
|
|
909
929
|
e += 1;
|
|
910
|
-
const
|
|
930
|
+
const r = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
911
931
|
e += 2;
|
|
912
|
-
let d, c,
|
|
932
|
+
let d, c, h, l, u;
|
|
913
933
|
{
|
|
914
|
-
const
|
|
915
|
-
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;
|
|
916
936
|
}
|
|
917
937
|
let g, f;
|
|
918
938
|
{
|
|
919
|
-
const
|
|
939
|
+
const y = s.getUint8(e);
|
|
920
940
|
e += 1;
|
|
921
|
-
const b =
|
|
941
|
+
const b = y >> 6, k = s.getUint8(e);
|
|
922
942
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
923
943
|
}
|
|
924
|
-
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 };
|
|
925
945
|
}
|
|
926
946
|
n = t.slice(e);
|
|
927
947
|
{
|
|
928
948
|
if (!this.audioConfig && s.getUint8(e) === 255) {
|
|
929
|
-
const
|
|
930
|
-
let
|
|
931
|
-
g =
|
|
932
|
-
const f = `mp4a.40.${
|
|
933
|
-
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);
|
|
934
954
|
}
|
|
935
|
-
const { dts:
|
|
936
|
-
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 };
|
|
937
957
|
}
|
|
938
958
|
};
|
|
939
959
|
parseVideo = async (t) => {
|
|
940
960
|
const s = new DataView(t.buffer);
|
|
941
961
|
let e = 0, i, n;
|
|
942
962
|
{
|
|
943
|
-
const
|
|
944
|
-
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)
|
|
945
965
|
throw new Error("invalid ts video payload.");
|
|
946
966
|
const a = s.getUint8(e);
|
|
947
967
|
e += 1;
|
|
948
|
-
const
|
|
968
|
+
const r = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
949
969
|
e += 2;
|
|
950
|
-
let d, c,
|
|
970
|
+
let d, c, h, l, u;
|
|
951
971
|
{
|
|
952
|
-
const
|
|
953
|
-
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;
|
|
954
974
|
}
|
|
955
975
|
let g, f;
|
|
956
976
|
{
|
|
957
|
-
const
|
|
977
|
+
const y = s.getUint8(e);
|
|
958
978
|
e += 1;
|
|
959
|
-
const b =
|
|
979
|
+
const b = y >> 6, k = s.getUint8(e);
|
|
960
980
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
961
981
|
}
|
|
962
|
-
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 };
|
|
963
983
|
}
|
|
964
984
|
n = t.slice(e);
|
|
965
985
|
{
|
|
966
|
-
const
|
|
986
|
+
const o = this.getNalus(n);
|
|
967
987
|
if (!this.videoConfig) {
|
|
968
|
-
let
|
|
969
|
-
if (
|
|
970
|
-
const f =
|
|
971
|
-
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);
|
|
972
992
|
}
|
|
973
993
|
}
|
|
974
994
|
const a = [];
|
|
975
|
-
let
|
|
976
|
-
for (const
|
|
977
|
-
const { type: g, nalu: f } =
|
|
995
|
+
let r = "delta";
|
|
996
|
+
for (const u of o) {
|
|
997
|
+
const { type: g, nalu: f } = u;
|
|
978
998
|
switch (g) {
|
|
979
999
|
case 6:
|
|
980
1000
|
// sei
|
|
@@ -982,23 +1002,23 @@ class Z {
|
|
|
982
1002
|
a.push(f);
|
|
983
1003
|
break;
|
|
984
1004
|
case 1:
|
|
985
|
-
|
|
1005
|
+
r = "delta", a.push(f);
|
|
986
1006
|
break;
|
|
987
1007
|
case 5:
|
|
988
|
-
|
|
1008
|
+
r = "key", a.push(f);
|
|
989
1009
|
break;
|
|
990
1010
|
}
|
|
991
1011
|
}
|
|
992
|
-
const d =
|
|
993
|
-
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 };
|
|
994
1014
|
}
|
|
995
1015
|
};
|
|
996
1016
|
/**
|
|
997
1017
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
998
1018
|
*/
|
|
999
1019
|
parsePtsDts(t, s) {
|
|
1000
|
-
const e = t.getUint8(s), i = t.getUint8(s + 1), n = t.getUint8(s + 2),
|
|
1001
|
-
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;
|
|
1002
1022
|
}
|
|
1003
1023
|
getNalus = (t) => {
|
|
1004
1024
|
const s = [];
|
|
@@ -1018,17 +1038,17 @@ class Z {
|
|
|
1018
1038
|
}
|
|
1019
1039
|
break;
|
|
1020
1040
|
}
|
|
1021
|
-
let
|
|
1022
|
-
if (t[e - 1] === 0 && (
|
|
1023
|
-
const a = t.slice(i, i +
|
|
1024
|
-
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 });
|
|
1025
1045
|
}
|
|
1026
1046
|
}
|
|
1027
1047
|
return s;
|
|
1028
1048
|
};
|
|
1029
1049
|
}
|
|
1030
|
-
const T = (
|
|
1031
|
-
class
|
|
1050
|
+
const T = (p, t) => p.getUint8(t) << 16 | p.getUint8(t + 1) << 8 | p.getUint8(t + 2);
|
|
1051
|
+
class Z {
|
|
1032
1052
|
audioConfig;
|
|
1033
1053
|
videoConfig;
|
|
1034
1054
|
header;
|
|
@@ -1040,53 +1060,53 @@ class tt {
|
|
|
1040
1060
|
parse = async (t) => {
|
|
1041
1061
|
let s = 0;
|
|
1042
1062
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
1043
|
-
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;
|
|
1044
1064
|
if (n) {
|
|
1045
|
-
const
|
|
1065
|
+
const r = this.parseTagBody(n, t, s + 4 + 11, o);
|
|
1046
1066
|
switch (n) {
|
|
1047
1067
|
case "script":
|
|
1048
|
-
this.on.info && this.on.info(
|
|
1068
|
+
this.on.info && this.on.info(r);
|
|
1049
1069
|
break;
|
|
1050
1070
|
case "audio":
|
|
1051
1071
|
{
|
|
1052
|
-
const { accPacketType: d } =
|
|
1072
|
+
const { accPacketType: d } = r;
|
|
1053
1073
|
if (d === 0) {
|
|
1054
|
-
const { codec: c, sampleRate:
|
|
1055
|
-
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);
|
|
1056
1076
|
} else {
|
|
1057
|
-
const { cts: c, data:
|
|
1058
|
-
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 });
|
|
1059
1079
|
}
|
|
1060
1080
|
}
|
|
1061
1081
|
break;
|
|
1062
1082
|
case "video":
|
|
1063
1083
|
{
|
|
1064
|
-
const { avcPacketType: d } =
|
|
1084
|
+
const { avcPacketType: d } = r;
|
|
1065
1085
|
if (d === 0) {
|
|
1066
|
-
const { codec: c, sps:
|
|
1067
|
-
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);
|
|
1068
1088
|
} else {
|
|
1069
|
-
const { frameType: c, cts:
|
|
1070
|
-
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 });
|
|
1071
1091
|
}
|
|
1072
1092
|
}
|
|
1073
1093
|
break;
|
|
1074
1094
|
}
|
|
1075
|
-
s = s + 4 + 11 +
|
|
1095
|
+
s = s + 4 + 11 + o;
|
|
1076
1096
|
}
|
|
1077
|
-
await new Promise((
|
|
1097
|
+
await new Promise((r) => setTimeout(() => r(!0), 8));
|
|
1078
1098
|
}
|
|
1079
1099
|
return s;
|
|
1080
1100
|
};
|
|
1081
1101
|
// Header
|
|
1082
1102
|
parseHeader = (t, s) => {
|
|
1083
|
-
let e, i, n,
|
|
1103
|
+
let e, i, n, o;
|
|
1084
1104
|
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2), i = t.getUint8(3);
|
|
1085
1105
|
{
|
|
1086
|
-
const
|
|
1106
|
+
const r = t.getUint8(0).toString(2).padStart(5, "0").split(""), [, , d, , c] = r;
|
|
1087
1107
|
n = { audio: c === "1", video: d === "1" };
|
|
1088
1108
|
}
|
|
1089
|
-
|
|
1109
|
+
o = t.getUint32(5), this.header = { signature: e, version: i, flags: n, dataOffset: o };
|
|
1090
1110
|
};
|
|
1091
1111
|
// 是否是完整tag
|
|
1092
1112
|
isSurplusTag = (t, s) => {
|
|
@@ -1103,11 +1123,11 @@ class tt {
|
|
|
1103
1123
|
return e;
|
|
1104
1124
|
};
|
|
1105
1125
|
parseTagHeader = (t, s) => {
|
|
1106
|
-
let e, i, n,
|
|
1126
|
+
let e, i, n, o, a;
|
|
1107
1127
|
{
|
|
1108
|
-
const
|
|
1128
|
+
const r = t.getUint8(s);
|
|
1109
1129
|
let d;
|
|
1110
|
-
switch (
|
|
1130
|
+
switch (r) {
|
|
1111
1131
|
case 18:
|
|
1112
1132
|
d = "script";
|
|
1113
1133
|
break;
|
|
@@ -1120,7 +1140,7 @@ class tt {
|
|
|
1120
1140
|
}
|
|
1121
1141
|
e = d;
|
|
1122
1142
|
}
|
|
1123
|
-
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 };
|
|
1124
1144
|
};
|
|
1125
1145
|
parseTagBody = (t, s, e, i) => {
|
|
1126
1146
|
let n;
|
|
@@ -1155,44 +1175,44 @@ class tt {
|
|
|
1155
1175
|
};
|
|
1156
1176
|
parseAudio = (t, s, e) => {
|
|
1157
1177
|
let i = s;
|
|
1158
|
-
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;
|
|
1159
1179
|
i = i + 1;
|
|
1160
1180
|
const c = t.getUint8(i);
|
|
1161
1181
|
i = i + 1;
|
|
1162
|
-
const
|
|
1163
|
-
if (
|
|
1164
|
-
const
|
|
1165
|
-
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 };
|
|
1166
1186
|
}
|
|
1167
|
-
return { soundFormat:
|
|
1187
|
+
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l };
|
|
1168
1188
|
};
|
|
1169
1189
|
parseVideo = (t, s, e) => {
|
|
1170
1190
|
let i = s;
|
|
1171
|
-
const n = t.getUint8(i),
|
|
1191
|
+
const n = t.getUint8(i), o = n >> 4 & 15, a = n & 15;
|
|
1172
1192
|
i = i + 1;
|
|
1173
|
-
const
|
|
1193
|
+
const r = t.getUint8(i);
|
|
1174
1194
|
i = i + 1;
|
|
1175
1195
|
const d = T(t, i);
|
|
1176
1196
|
i = i + 3;
|
|
1177
|
-
const c = e - 5,
|
|
1197
|
+
const c = e - 5, h = new Uint8Array(t.buffer.slice(i, i + c));
|
|
1178
1198
|
switch (a) {
|
|
1179
1199
|
case 7:
|
|
1180
|
-
if (
|
|
1181
|
-
const
|
|
1182
|
-
return { frameType:
|
|
1183
|
-
} else if (
|
|
1184
|
-
const
|
|
1185
|
-
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); ) {
|
|
1186
1206
|
const g = t.getUint32(i, !1), f = new Uint8Array(t.buffer.slice(i, i + 4 + g));
|
|
1187
|
-
i += 4 + g,
|
|
1207
|
+
i += 4 + g, l.push(f);
|
|
1188
1208
|
}
|
|
1189
|
-
return { frameType:
|
|
1209
|
+
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, nalus: l };
|
|
1190
1210
|
}
|
|
1191
1211
|
break;
|
|
1192
1212
|
default:
|
|
1193
1213
|
throw new Error("Unsupported codecID");
|
|
1194
1214
|
}
|
|
1195
|
-
return { frameType:
|
|
1215
|
+
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h };
|
|
1196
1216
|
};
|
|
1197
1217
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1198
1218
|
getAMFName = (t, s, e) => {
|
|
@@ -1200,74 +1220,74 @@ class tt {
|
|
|
1200
1220
|
return this.textDecoder?.decode(i) || "";
|
|
1201
1221
|
};
|
|
1202
1222
|
getAMFValue = (t, s, e) => {
|
|
1203
|
-
let i = s, n,
|
|
1223
|
+
let i = s, n, o = 0;
|
|
1204
1224
|
switch (e) {
|
|
1205
1225
|
case 0:
|
|
1206
|
-
n = t.getFloat64(i, !1),
|
|
1226
|
+
n = t.getFloat64(i, !1), o = 8;
|
|
1207
1227
|
break;
|
|
1208
1228
|
case 1:
|
|
1209
|
-
n = !!t.getUint8(i),
|
|
1229
|
+
n = !!t.getUint8(i), o = 1;
|
|
1210
1230
|
break;
|
|
1211
1231
|
case 2:
|
|
1212
1232
|
{
|
|
1213
1233
|
n = "";
|
|
1214
|
-
const
|
|
1234
|
+
const r = t.getUint16(i, !1);
|
|
1215
1235
|
i = i + 2;
|
|
1216
|
-
const d = new Int8Array(t.buffer, i,
|
|
1217
|
-
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;
|
|
1218
1238
|
}
|
|
1219
1239
|
break;
|
|
1220
1240
|
case 3:
|
|
1221
1241
|
for (n = {}; i < t.byteLength; ) {
|
|
1222
|
-
const
|
|
1223
|
-
if (
|
|
1242
|
+
const r = t.getUint16(i, !1);
|
|
1243
|
+
if (r === 0) break;
|
|
1224
1244
|
i = i + 2;
|
|
1225
|
-
const d = this.getAMFName(t, i,
|
|
1226
|
-
i = i +
|
|
1245
|
+
const d = this.getAMFName(t, i, r);
|
|
1246
|
+
i = i + r;
|
|
1227
1247
|
const c = this.getAmfType(t, i);
|
|
1228
1248
|
if (c === 6) break;
|
|
1229
1249
|
i = i + 1;
|
|
1230
|
-
const
|
|
1231
|
-
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;
|
|
1232
1252
|
}
|
|
1233
1253
|
break;
|
|
1234
1254
|
case 8:
|
|
1235
1255
|
{
|
|
1236
1256
|
n = {};
|
|
1237
|
-
const
|
|
1257
|
+
const r = t.getUint32(i, !1);
|
|
1238
1258
|
i = i + 4;
|
|
1239
|
-
for (let d = 0; d <
|
|
1259
|
+
for (let d = 0; d < r; d++) {
|
|
1240
1260
|
const c = t.getUint16(i, !1);
|
|
1241
1261
|
i = i + 2;
|
|
1242
|
-
const
|
|
1262
|
+
const h = this.getAMFName(t, i, c);
|
|
1243
1263
|
i = i + c;
|
|
1244
|
-
const
|
|
1264
|
+
const l = this.getAmfType(t, i);
|
|
1245
1265
|
i = i + 1;
|
|
1246
|
-
const
|
|
1247
|
-
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;
|
|
1248
1268
|
}
|
|
1249
1269
|
}
|
|
1250
1270
|
break;
|
|
1251
1271
|
case 10:
|
|
1252
1272
|
{
|
|
1253
1273
|
n = [];
|
|
1254
|
-
const
|
|
1274
|
+
const r = t.getUint32(i, !1);
|
|
1255
1275
|
i = i + 4;
|
|
1256
|
-
for (let d = 0; d <
|
|
1276
|
+
for (let d = 0; d < r; d++) {
|
|
1257
1277
|
const c = this.getAmfType(t, i);
|
|
1258
1278
|
i = i + 1;
|
|
1259
|
-
const
|
|
1260
|
-
i = i +
|
|
1279
|
+
const h = this.getAMFValue(t, i, c);
|
|
1280
|
+
i = i + h.length, n.push(h.value), o = 1 + h.length;
|
|
1261
1281
|
}
|
|
1262
1282
|
}
|
|
1263
1283
|
break;
|
|
1264
1284
|
}
|
|
1265
|
-
return { amfType: e, length:
|
|
1285
|
+
return { amfType: e, length: o, value: n };
|
|
1266
1286
|
};
|
|
1267
1287
|
}
|
|
1268
|
-
class
|
|
1288
|
+
class et {
|
|
1269
1289
|
pattern;
|
|
1270
|
-
cacher = new
|
|
1290
|
+
cacher = new Y();
|
|
1271
1291
|
isParseing = !1;
|
|
1272
1292
|
offset = 0;
|
|
1273
1293
|
parser;
|
|
@@ -1277,10 +1297,10 @@ class st {
|
|
|
1277
1297
|
init = (t) => {
|
|
1278
1298
|
switch (this.destroy(), this.pattern = t, this.pattern) {
|
|
1279
1299
|
case "flv":
|
|
1280
|
-
this.parser = new
|
|
1300
|
+
this.parser = new Z();
|
|
1281
1301
|
break;
|
|
1282
1302
|
case "hls":
|
|
1283
|
-
this.parser = new
|
|
1303
|
+
this.parser = new J();
|
|
1284
1304
|
break;
|
|
1285
1305
|
default:
|
|
1286
1306
|
throw new Error("is error pattern.");
|
|
@@ -1312,7 +1332,7 @@ class st {
|
|
|
1312
1332
|
}
|
|
1313
1333
|
};
|
|
1314
1334
|
}
|
|
1315
|
-
class
|
|
1335
|
+
class st {
|
|
1316
1336
|
pattern = "flv";
|
|
1317
1337
|
audioDecoderConfig;
|
|
1318
1338
|
audioDecoder;
|
|
@@ -1406,22 +1426,20 @@ class it {
|
|
|
1406
1426
|
};
|
|
1407
1427
|
decode = () => {
|
|
1408
1428
|
if (this.isProcessing !== !0) {
|
|
1409
|
-
for (this.isProcessing = !0; ; ) {
|
|
1410
|
-
this.currentChunk = this.pendingChunks.shift();
|
|
1429
|
+
for (this.isProcessing = !0; this.currentChunk = this.pendingChunks.shift(), !!this.currentChunk; ) {
|
|
1411
1430
|
const t = this.pendingChunks.length;
|
|
1412
1431
|
if (this.frameTrack) {
|
|
1413
1432
|
const [i, n] = this.fameTrackOption[this.pattern];
|
|
1414
1433
|
if (t <= i && (this.isFrameTrack = !1), t >= n && (this.isFrameTrack = !0), this.isFrameTrack) {
|
|
1415
|
-
const
|
|
1416
|
-
this.decodingSpeedRatio = Number(
|
|
1434
|
+
const o = Math.min(1 + (t - i) / 100, this.maxDecodingSpeedRatio);
|
|
1435
|
+
this.decodingSpeedRatio = Number(o.toFixed(1));
|
|
1417
1436
|
} else
|
|
1418
1437
|
this.decodingSpeedRatio = 1;
|
|
1419
1438
|
}
|
|
1420
1439
|
if (this.on.analysis) {
|
|
1421
|
-
const { decodingSpeed: i, decodingSpeedRatio: n, fps:
|
|
1422
|
-
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 });
|
|
1423
1442
|
}
|
|
1424
|
-
if (!this.currentChunk) break;
|
|
1425
1443
|
const { kind: s, init: e } = this.currentChunk;
|
|
1426
1444
|
switch (s) {
|
|
1427
1445
|
case "audio":
|
|
@@ -1464,49 +1482,67 @@ class it {
|
|
|
1464
1482
|
}
|
|
1465
1483
|
};
|
|
1466
1484
|
}
|
|
1467
|
-
class
|
|
1468
|
-
|
|
1469
|
-
writer;
|
|
1470
|
-
cutOption;
|
|
1471
|
-
pause = !1;
|
|
1485
|
+
class it {
|
|
1486
|
+
renderMap = /* @__PURE__ */ new Map();
|
|
1472
1487
|
constructor() {
|
|
1473
1488
|
}
|
|
1474
|
-
init = ({ writable: t }) => {
|
|
1475
|
-
this.destroy(), this.writable = t, this.writer = this.writable.getWriter();
|
|
1476
|
-
};
|
|
1477
1489
|
push = async (t) => {
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
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
|
+
}
|
|
1484
1506
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
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);
|
|
1487
1521
|
};
|
|
1488
1522
|
/**
|
|
1489
1523
|
* 设置剪切
|
|
1490
1524
|
*/
|
|
1491
1525
|
setCut = (t) => {
|
|
1492
|
-
|
|
1526
|
+
const { key: s, cutOption: e } = { key: "default", ...t }, i = this.renderMap.get(s);
|
|
1527
|
+
i && this.renderMap.set(s, { ...i, option: e });
|
|
1493
1528
|
};
|
|
1494
1529
|
/**
|
|
1495
1530
|
* 设置暂停
|
|
1496
1531
|
*/
|
|
1497
1532
|
setPause = (t) => {
|
|
1498
|
-
|
|
1533
|
+
const { key: s, pause: e } = { key: "default", ...t }, i = this.renderMap.get(s);
|
|
1534
|
+
i && this.renderMap.set(s, { ...i, pause: e });
|
|
1499
1535
|
};
|
|
1500
1536
|
destroy = () => {
|
|
1501
|
-
this.
|
|
1537
|
+
this.renderMap = /* @__PURE__ */ new Map();
|
|
1502
1538
|
};
|
|
1503
1539
|
}
|
|
1504
1540
|
export {
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
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
|
|
1512
1548
|
};
|