pr-player 0.3.2 → 0.3.3
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 +1 -0
- package/dist/index.js +358 -331
- package/dist/index.umd.cjs +4 -4
- package/dist/render/Render.d.ts +1 -0
- package/dist/render/RenderWorker.d.ts +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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
|
|
1
|
+
const A = '(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);", A], { type: "text/javascript;charset=utf-8" });
|
|
2
|
+
function P(p) {
|
|
3
3
|
let t;
|
|
4
4
|
try {
|
|
5
5
|
if (t = _ && (self.URL || self.webkitURL).createObjectURL(_), !t) throw "";
|
|
@@ -11,7 +11,7 @@ function R(p) {
|
|
|
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(A),
|
|
15
15
|
{
|
|
16
16
|
name: p?.name
|
|
17
17
|
}
|
|
@@ -19,7 +19,7 @@ function R(p) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
class I {
|
|
22
|
-
worker = new
|
|
22
|
+
worker = new P();
|
|
23
23
|
on = {};
|
|
24
24
|
constructor() {
|
|
25
25
|
this.worker.onmessage = (t) => {
|
|
@@ -46,9 +46,9 @@ class I {
|
|
|
46
46
|
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
const M = `(function(){"use strict";class
|
|
49
|
+
const M = `(function(){"use strict";class a{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 o=this.decodingSpeedRatio;this.on.audio.decode&&this.on.audio.decode({audioData:i,playbackRate:o})},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);try{const o=i.timestamp-this.frameStartTime+this.baseTime*1e3,s=await createImageBitmap(i);if(i.close(),!s.width||!s.height)return s.close();this.on.video.decode&&this.on.video.decode({timestamp:o,bitmap:s}),this.currentChunk&&this.currentChunk.kind==="video"&&this.currentChunk.nalus&&this.on.nalus&&this.on.nalus(this.currentChunk.nalus)}catch{i.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 o=this.lastRenderTime-this.nextRenderTime;e-=o}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 r=Math.min(1+(e-s)/100,this.maxDecodingSpeedRatio);this.decodingSpeedRatio=Number(r.toFixed(1))}else this.decodingSpeedRatio=1}if(this.on.analysis){const{decodingSpeed:s,decodingSpeedRatio:n,fps:r}=this;this.on.analysis({decodingSpeed:s,decodingSpeedRatio:n,fps:r,cacheLength:e})}const{kind:i,init:o}=this.currentChunk;switch(i){case"audio":this.decodeAudio(o);break;case"video":this.decodeVideo(o);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 a;d.on.audio.decode=t=>postMessage({action:"on.audio.decode",data:t},[t.audioData]),d.on.audio.error=t=>postMessage({action:"on.audio.error",data:t}),d.on.video.decode=t=>postMessage({action:"on.video.decode",data:t},[t.bitmap]),d.on.video.error=t=>postMessage({action:"on.video.error",data:t}),d.on.nalus=t=>postMessage({action:"on.nalus",data:t}),d.on.analysis=t=>postMessage({action:"on.analysis",data:t}),onmessage=t=>{const{action:e,data:i}=t.data,o=d[e];o&&o(i)}})();
|
|
50
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
|
|
51
|
+
function L(p) {
|
|
52
52
|
let t;
|
|
53
53
|
try {
|
|
54
54
|
if (t = C && (self.URL || self.webkitURL).createObjectURL(C), !t) throw "";
|
|
@@ -67,8 +67,8 @@ function V(p) {
|
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
class
|
|
71
|
-
worker = new
|
|
70
|
+
class V {
|
|
71
|
+
worker = new L();
|
|
72
72
|
on = { audio: {}, video: {} };
|
|
73
73
|
constructor() {
|
|
74
74
|
this.worker.onmessage = (t) => {
|
|
@@ -104,9 +104,9 @@ class L {
|
|
|
104
104
|
this.worker.postMessage({ action: "destroy" }), this.worker.terminate();
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
const
|
|
108
|
-
`, v = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",
|
|
109
|
-
function
|
|
107
|
+
const S = `(function(){"use strict";class l{renderMap=new Map;constructor(){}push=async t=>{const{timestamp:s}=t,{bitmap:e}=t;if(e.height===0||e.width===0)return e.close();try{const n=[...this.renderMap.keys()];for(const i of n){const a=this.renderMap.get(i);if(!a)continue;const{pause:y=!1,writer:h,offscreen:c,option:u}=a;if(y===!0)continue;const f=r=>{if(h){const o=new VideoFrame(r,{timestamp:s});try{o&&h.write(o)}catch{}o.close()}else c&&(c.width=r.width,c.height=r.height,c?.getContext("2d")?.drawImage(r,0,0))};if(i==="default")f(e);else if(u){const{sx:r=0,sy:o=0,sw:p=e.width,sh:g=e.height}=u,M=await createImageBitmap(e,r,o,p,g);f(M)}}}catch{}e.close()};addCut=t=>{const{key:s,writable:e,offscreen:n,option:i}={key:"default",...t};if(e){const a=e.getWriter();this.renderMap.set(s,{writer:a,option:i,pause:!1})}else this.renderMap.set(s,{offscreen:n,option:i,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 w=new l;onmessage=d=>{const{action:t,data:s}=d.data,e=w[t];e&&e(s)}})();
|
|
108
|
+
`, v = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", S], { type: "text/javascript;charset=utf-8" });
|
|
109
|
+
function F(p) {
|
|
110
110
|
let t;
|
|
111
111
|
try {
|
|
112
112
|
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
@@ -118,19 +118,22 @@ function N(p) {
|
|
|
118
118
|
}), s;
|
|
119
119
|
} catch {
|
|
120
120
|
return new Worker(
|
|
121
|
-
"data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
121
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(S),
|
|
122
122
|
{
|
|
123
123
|
name: p?.name
|
|
124
124
|
}
|
|
125
125
|
);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
class
|
|
129
|
-
worker = new
|
|
128
|
+
class B {
|
|
129
|
+
worker = new F();
|
|
130
130
|
constructor() {
|
|
131
131
|
}
|
|
132
132
|
push = (t) => this.worker.postMessage({ action: "push", data: t }, [t.bitmap]);
|
|
133
|
-
addCut = (t) =>
|
|
133
|
+
addCut = (t) => {
|
|
134
|
+
const s = [];
|
|
135
|
+
t.writable && s.push(t.writable), t.offscreen && s.push(t.offscreen), this.worker.postMessage({ action: "addCut", data: t }, s);
|
|
136
|
+
};
|
|
134
137
|
delCut = (t) => this.worker.postMessage({ action: "delCut", data: t });
|
|
135
138
|
setCut = (t) => this.worker.postMessage({ action: "setCut", data: t });
|
|
136
139
|
setPause = (t) => this.worker.postMessage({ action: "setPause", data: t });
|
|
@@ -138,73 +141,69 @@ class F {
|
|
|
138
141
|
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
139
142
|
};
|
|
140
143
|
}
|
|
141
|
-
var
|
|
144
|
+
var N = Object.defineProperty, G = (p, t, s) => t in p ? N(p, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : p[t] = s, y = (p, t, s) => G(p, typeof t != "symbol" ? t + "" : t, s);
|
|
142
145
|
class W {
|
|
143
146
|
constructor(t, s) {
|
|
144
|
-
|
|
147
|
+
y(this, "inputStream", new MediaStream()), y(this, "outputStream", new MediaStream()), y(this, "inputGain", 1), y(this, "enhanceGain", 1), y(this, "bgsGain", 1), y(this, "bgmGain", 1), y(this, "outputGain", 1), y(this, "mixAudioMap", /* @__PURE__ */ new Map()), y(this, "audioContext", new AudioContext()), y(this, "sourceNode"), y(this, "inputGainNode"), y(this, "enhanceGainNode"), y(this, "bgsGainNode"), y(this, "bgmGainNode"), y(this, "analyserNode"), y(this, "analyserArrayData"), y(this, "outputGainNode"), y(this, "destinationNode"), y(this, "filterStream", (e) => e), y(this, "stop", () => {
|
|
145
148
|
{
|
|
146
149
|
const e = this.inputStream.getTracks();
|
|
147
|
-
for (const
|
|
148
|
-
|
|
150
|
+
for (const n of e)
|
|
151
|
+
n.stop(), this.inputStream.removeTrack(n);
|
|
149
152
|
}
|
|
150
|
-
}),
|
|
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) => {
|
|
153
|
+
}), y(this, "getStream", () => this.filterStream(this.outputStream)), y(this, "setMute", (e = !0) => {
|
|
155
154
|
e ? this.analyserNode.disconnect(this.outputGainNode) : this.analyserNode.connect(this.outputGainNode);
|
|
156
|
-
}),
|
|
155
|
+
}), y(this, "setInputGain", (e) => {
|
|
157
156
|
this.inputGain = e, this.inputGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
158
|
-
}),
|
|
157
|
+
}), y(this, "setEnhanceGain", async (e) => {
|
|
159
158
|
this.enhanceGain = e + 1, this.enhanceGainNode.gain.setValueAtTime(this.enhanceGain, this.audioContext.currentTime);
|
|
160
|
-
}),
|
|
159
|
+
}), y(this, "setBgsGain", (e) => {
|
|
161
160
|
this.bgsGain = e, this.bgsGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
162
|
-
}),
|
|
161
|
+
}), y(this, "setBgmGain", (e) => {
|
|
163
162
|
this.bgmGain = e, this.bgmGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
164
|
-
}),
|
|
163
|
+
}), y(this, "setOutputGain", (e) => {
|
|
165
164
|
this.outputGain = e, this.outputGainNode.gain.setValueAtTime(this.outputGain, this.audioContext.currentTime);
|
|
166
|
-
}),
|
|
167
|
-
const { analyserNode: e, analyserArrayData:
|
|
168
|
-
e.getByteFrequencyData(
|
|
169
|
-
let
|
|
170
|
-
for (let o = 0; o <
|
|
171
|
-
|
|
172
|
-
return Math.ceil(
|
|
173
|
-
}),
|
|
165
|
+
}), y(this, "getVolume", () => {
|
|
166
|
+
const { analyserNode: e, analyserArrayData: n } = this;
|
|
167
|
+
e.getByteFrequencyData(n);
|
|
168
|
+
let i = 0;
|
|
169
|
+
for (let o = 0; o < n.length; o++)
|
|
170
|
+
i += n[o];
|
|
171
|
+
return Math.ceil(i / n.length);
|
|
172
|
+
}), y(this, "mixAudio", (e, n = "bgm") => new Promise(async (i, o) => {
|
|
174
173
|
try {
|
|
175
174
|
{
|
|
176
|
-
const d = this.mixAudioMap.get(
|
|
175
|
+
const d = this.mixAudioMap.get(n);
|
|
177
176
|
d && d.stop();
|
|
178
177
|
}
|
|
179
|
-
const a =
|
|
180
|
-
this.mixAudioMap.set(
|
|
181
|
-
r.disconnect(a), this.mixAudioMap.delete(
|
|
178
|
+
const a = n === "bgs" ? this.bgsGainNode : this.bgmGainNode, r = this.audioContext.createBufferSource();
|
|
179
|
+
this.mixAudioMap.set(n, r), r.buffer = e, r.connect(a), r.onended = () => {
|
|
180
|
+
r.disconnect(a), this.mixAudioMap.delete(n), i(!0);
|
|
182
181
|
}, r.start(0);
|
|
183
182
|
} catch (a) {
|
|
184
183
|
o(a);
|
|
185
184
|
}
|
|
186
|
-
})),
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
}),
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
}), s && (this.audioContext = s), this.inputStream = t, this.sourceNode = this.audioContext.createMediaStreamSource(this.inputStream), this.
|
|
185
|
+
})), y(this, "mixAudioStop", (e) => {
|
|
186
|
+
const n = this.mixAudioMap.get(e);
|
|
187
|
+
n?.stop();
|
|
188
|
+
}), y(this, "changeMix", (e, n) => {
|
|
189
|
+
const i = e === "bgs" ? this.bgsGainNode : this.bgmGainNode;
|
|
190
|
+
n ? i.connect(this.destinationNode) : i.disconnect(this.destinationNode);
|
|
191
|
+
}), 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;
|
|
193
192
|
{
|
|
194
|
-
const { sourceNode: e,
|
|
195
|
-
e.connect(
|
|
193
|
+
const { sourceNode: e, inputGainNode: n, enhanceGainNode: i, bgsGainNode: o, bgmGainNode: a, analyserNode: r, outputGainNode: d, destinationNode: c } = this;
|
|
194
|
+
e.connect(n), n.connect(i), i.connect(r), o.connect(r), a.connect(r), i.connect(c), o.connect(c), a.connect(c), r.connect(d), d.connect(this.audioContext.destination);
|
|
196
195
|
}
|
|
197
196
|
this.setMute(!0), this.audioContext.resume();
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
199
|
const E = async (p, t) => {
|
|
201
200
|
try {
|
|
202
|
-
const { format: s, numberOfChannels: e, numberOfFrames:
|
|
201
|
+
const { format: s, numberOfChannels: e, numberOfFrames: n, sampleRate: i } = t, o = p.createBuffer(e, n, i);
|
|
203
202
|
for (let a = 0; a < e; a++) {
|
|
204
203
|
const r = t.allocationSize({ planeIndex: a }), d = new Uint8Array(r);
|
|
205
204
|
t.copyTo(d, { planeIndex: a });
|
|
206
205
|
const c = new DataView(d.buffer), h = o.getChannelData(a);
|
|
207
|
-
for (let l = 0; l <
|
|
206
|
+
for (let l = 0; l < n; l++) {
|
|
208
207
|
let u;
|
|
209
208
|
switch (s) {
|
|
210
209
|
case "s16":
|
|
@@ -248,15 +247,15 @@ class O {
|
|
|
248
247
|
async push(t) {
|
|
249
248
|
const { audioData: s, playbackRate: e = 1 } = t;
|
|
250
249
|
if (!this.audioContext || !this.destination) return;
|
|
251
|
-
let
|
|
252
|
-
if (s.close(), !
|
|
253
|
-
const
|
|
254
|
-
|
|
250
|
+
let n = await E(this.audioContext, s);
|
|
251
|
+
if (s.close(), !n) return;
|
|
252
|
+
const i = this.audioContext.createBufferSource();
|
|
253
|
+
i.buffer = n, i.playbackRate.value = e;
|
|
255
254
|
const o = -1200 * Math.log2(e);
|
|
256
|
-
|
|
257
|
-
const a = Math.max(this.nextStartTime, this.audioContext.currentTime), r =
|
|
258
|
-
this.nextStartTime = a + r,
|
|
259
|
-
this.pendingSources = this.pendingSources.filter((d) => d !==
|
|
255
|
+
i.detune.value = o, i.connect(this.destination);
|
|
256
|
+
const a = Math.max(this.nextStartTime, this.audioContext.currentTime), r = n.duration / e;
|
|
257
|
+
this.nextStartTime = a + r, i.start(a), this.pendingSources.push(i), i.onended = () => {
|
|
258
|
+
this.pendingSources = this.pendingSources.filter((d) => d !== i);
|
|
260
259
|
}, this.audioContext.state === "suspended" && await this.audioContext.resume();
|
|
261
260
|
}
|
|
262
261
|
getStream = () => this.prAudioStream?.getStream();
|
|
@@ -272,7 +271,7 @@ const j = (p) => {
|
|
|
272
271
|
for (const s of t)
|
|
273
272
|
s.stop();
|
|
274
273
|
};
|
|
275
|
-
class
|
|
274
|
+
class $ {
|
|
276
275
|
resolvesMap = /* @__PURE__ */ new Map();
|
|
277
276
|
index = 0;
|
|
278
277
|
constructor() {
|
|
@@ -284,44 +283,44 @@ class q {
|
|
|
284
283
|
* @param timeout 超时时间 ms
|
|
285
284
|
* @returns
|
|
286
285
|
*/
|
|
287
|
-
add = (t, s = () => !1, e = 0) => new Promise((
|
|
288
|
-
if (s()) return
|
|
286
|
+
add = (t, s = () => !1, e = 0) => new Promise((n) => {
|
|
287
|
+
if (s()) return n(!0);
|
|
289
288
|
this.resolvesMap.has(t) || this.resolvesMap.set(t, /* @__PURE__ */ new Map()), this.index++;
|
|
290
289
|
const a = `${this.index}`;
|
|
291
290
|
if (e = Math.max(0, e), e === 0) {
|
|
292
|
-
this.resolvesMap.get(t)?.set(a, { resolve:
|
|
291
|
+
this.resolvesMap.get(t)?.set(a, { resolve: n, timer: 0 });
|
|
293
292
|
return;
|
|
294
293
|
}
|
|
295
294
|
const r = window.setTimeout(() => {
|
|
296
295
|
this.emit(t);
|
|
297
296
|
}, e);
|
|
298
|
-
this.resolvesMap.get(t)?.set(a, { resolve:
|
|
297
|
+
this.resolvesMap.get(t)?.set(a, { resolve: n, timer: r });
|
|
299
298
|
});
|
|
300
299
|
emit = async (t) => {
|
|
301
300
|
const s = this.resolvesMap.get(t);
|
|
302
301
|
if (!s) return;
|
|
303
302
|
const e = [...s.keys()];
|
|
304
|
-
for (const
|
|
305
|
-
const
|
|
306
|
-
|
|
303
|
+
for (const n of e) {
|
|
304
|
+
const i = s.get(n);
|
|
305
|
+
i && (clearTimeout(i.timer), i.resolve(), s.delete(n));
|
|
307
306
|
}
|
|
308
307
|
};
|
|
309
308
|
}
|
|
310
|
-
const
|
|
311
|
-
const s = new Uint8Array(p), e = new Uint8Array(t),
|
|
312
|
-
let
|
|
313
|
-
return i
|
|
314
|
-
},
|
|
309
|
+
const q = (p, t) => {
|
|
310
|
+
const s = new Uint8Array(p), e = new Uint8Array(t), n = new Uint8Array(11 + s.length + e.length);
|
|
311
|
+
let i = 0;
|
|
312
|
+
return n[i++] = 1, n[i++] = s[1], n[i++] = s[2], n[i++] = s[3], n[i++] = 255, n[i++] = 225, n[i++] = s.length >> 8 & 255, n[i++] = s.length & 255, n.set(s, i), i += s.length, n[i++] = 1, n[i++] = e.length >> 8 & 255, n[i++] = e.length & 255, n.set(e, i), n;
|
|
313
|
+
}, D = (p) => {
|
|
315
314
|
let t = 0;
|
|
316
315
|
const s = new DataView(p.buffer), e = s.getUint8(t);
|
|
317
316
|
if (t = t + 1, e !== 1) throw new Error("Invalid AVC version");
|
|
318
|
-
const i = s.getUint8(t) & 255;
|
|
319
|
-
t = t + 1;
|
|
320
317
|
const n = s.getUint8(t) & 255;
|
|
321
318
|
t = t + 1;
|
|
319
|
+
const i = s.getUint8(t) & 255;
|
|
320
|
+
t = t + 1;
|
|
322
321
|
const o = s.getUint8(t) & 255;
|
|
323
322
|
t = t + 1;
|
|
324
|
-
const d = `avc1.${Array.from([
|
|
323
|
+
const d = `avc1.${Array.from([n, i, o], (b) => b.toString(16).padStart(2, "0")).join("")}`, c = (s.getUint8(t) & 3) - 1;
|
|
325
324
|
t = t + 1;
|
|
326
325
|
const h = s.getUint8(t) & 31;
|
|
327
326
|
t = t + 1;
|
|
@@ -333,84 +332,82 @@ const $ = (p, t) => {
|
|
|
333
332
|
t = t + 1;
|
|
334
333
|
const f = s.getUint16(t, !1);
|
|
335
334
|
t = t + 2;
|
|
336
|
-
const
|
|
337
|
-
return t = t + f, { version: e, codec: d, profile:
|
|
335
|
+
const m = new Uint8Array(s.buffer.slice(t, t + f));
|
|
336
|
+
return t = t + f, { version: e, codec: d, profile: n, compatibility: i, level: o, lengthSizeMinusOne: c, numOfSequenceParameterSets: h, sequenceParameterSetLength: l, sps: u, numOfPictureParameterSets: g, pictureParameterSetLength: f, pps: m };
|
|
338
337
|
}, H = (p) => {
|
|
339
338
|
const t = new Uint8Array(4 + p.length);
|
|
340
339
|
return new DataView(t.buffer).setUint32(0, p.length, !1), t.set(p, 4), t;
|
|
341
340
|
}, K = (p) => {
|
|
342
341
|
let t = 0;
|
|
343
|
-
for (const
|
|
344
|
-
t +=
|
|
342
|
+
for (const n of p)
|
|
343
|
+
t += n.length;
|
|
345
344
|
const s = new Uint8Array(t);
|
|
346
345
|
let e = 0;
|
|
347
|
-
for (const
|
|
348
|
-
const
|
|
349
|
-
s.set(
|
|
346
|
+
for (const n of p) {
|
|
347
|
+
const i = n;
|
|
348
|
+
s.set(i, e), e += i.length;
|
|
350
349
|
}
|
|
351
350
|
return s;
|
|
352
351
|
}, X = (p) => {
|
|
353
352
|
const t = new DataView(p.buffer);
|
|
354
|
-
let s = 0, e,
|
|
353
|
+
let s = 0, e, n, i;
|
|
355
354
|
e = t.getUint32(s, !1), s += 4;
|
|
356
355
|
{
|
|
357
356
|
const o = t.getUint8(s), a = o >> 7 & 1, r = o >> 5 & 3, d = o & 31;
|
|
358
|
-
|
|
357
|
+
n = { forbidden_zero_bit: a, nal_ref_idc: r, nal_unit_type: d }, s += 1;
|
|
359
358
|
}
|
|
360
359
|
{
|
|
361
360
|
const o = e - 1;
|
|
362
|
-
|
|
361
|
+
i = new Uint8Array(t.buffer.slice(s, s + o));
|
|
363
362
|
}
|
|
364
|
-
return { size: e, header:
|
|
363
|
+
return { size: e, header: n, data: i };
|
|
365
364
|
};
|
|
366
|
-
class
|
|
365
|
+
class x {
|
|
367
366
|
#e = {
|
|
368
367
|
timeout: 5 * 1e3,
|
|
369
368
|
check: !1
|
|
370
369
|
};
|
|
371
|
-
#t
|
|
372
|
-
// 实例变量:统一管理当前请求的中止
|
|
370
|
+
#t;
|
|
373
371
|
constructor(t = {}) {
|
|
374
372
|
this.#e = { ...this.#e, ...t };
|
|
375
373
|
}
|
|
376
374
|
/**
|
|
377
|
-
*
|
|
375
|
+
*
|
|
376
|
+
* @param input string | URL | Request
|
|
377
|
+
* @param init RequestInit
|
|
378
378
|
*/
|
|
379
|
-
|
|
380
|
-
this.#t = new AbortController();
|
|
381
|
-
const
|
|
382
|
-
this.#t?.abort(
|
|
383
|
-
},
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
reason: r
|
|
392
|
-
});
|
|
393
|
-
} else
|
|
394
|
-
e({ status: "error", reason: a.message });
|
|
395
|
-
});
|
|
379
|
+
check = (t, s) => new Promise(async (e, n) => {
|
|
380
|
+
this.stop(), this.#t = new AbortController();
|
|
381
|
+
const i = window.setTimeout(() => {
|
|
382
|
+
this.#t?.abort("Timeout."), n({ status: "timeout", reason: "" });
|
|
383
|
+
}, this.#e.timeout);
|
|
384
|
+
try {
|
|
385
|
+
const o = await fetch(t, { ...s, method: "HEAD", signal: this.#t?.signal });
|
|
386
|
+
o.status === 200 ? e({ status: "successed", reason: "" }) : n({ status: "failed", reason: `${o.status}` });
|
|
387
|
+
} catch (o) {
|
|
388
|
+
n({ status: "error", reason: o.message });
|
|
389
|
+
}
|
|
390
|
+
clearTimeout(i);
|
|
396
391
|
});
|
|
397
392
|
/**
|
|
398
|
-
*
|
|
393
|
+
*
|
|
394
|
+
* @param input string | URL | Request
|
|
395
|
+
* @param init RequestInit
|
|
399
396
|
*/
|
|
400
|
-
request = (t, s) => new Promise(async (e,
|
|
397
|
+
request = async (t, s) => new Promise(async (e, n) => {
|
|
401
398
|
try {
|
|
402
|
-
this
|
|
403
|
-
const
|
|
404
|
-
e(
|
|
405
|
-
} catch (
|
|
406
|
-
|
|
399
|
+
this.#e.check && await this.check(t, s), this.#t = new AbortController();
|
|
400
|
+
const i = await fetch(t, { ...s, signal: this.#t?.signal });
|
|
401
|
+
e(i);
|
|
402
|
+
} catch (i) {
|
|
403
|
+
this.stop(), n(i);
|
|
407
404
|
}
|
|
408
405
|
});
|
|
406
|
+
/**
|
|
407
|
+
* stop
|
|
408
|
+
*/
|
|
409
409
|
stop = () => {
|
|
410
|
-
|
|
411
|
-
const t = new Error("Actively stopped.");
|
|
412
|
-
t.name = "AbortError", this.#t.abort(t);
|
|
413
|
-
}
|
|
410
|
+
this.#t?.signal.aborted === !1 && this.#t.abort("Actively stop.");
|
|
414
411
|
};
|
|
415
412
|
}
|
|
416
413
|
class tt {
|
|
@@ -418,9 +415,11 @@ class tt {
|
|
|
418
415
|
debug: !1,
|
|
419
416
|
frameTrack: !1
|
|
420
417
|
};
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
418
|
+
converter = "MediaStreamTrackGenerator" in window ? "generator" : "canvas";
|
|
419
|
+
// 自动检测浏览器 使用哪一种模式转换生产视频流
|
|
420
|
+
prFetch = new x();
|
|
421
|
+
getSegmentsFetch = new x();
|
|
422
|
+
prResolves = new $();
|
|
424
423
|
url = "";
|
|
425
424
|
start_resolve;
|
|
426
425
|
demuxerWorker;
|
|
@@ -458,11 +457,10 @@ class tt {
|
|
|
458
457
|
*/
|
|
459
458
|
stop = async () => {
|
|
460
459
|
try {
|
|
461
|
-
this.url = "", clearInterval(this.hls.getSegmentsTimer), this.prFetch.stop(), this.getSegmentsFetch.stop();
|
|
460
|
+
this.url = "", clearInterval(this.hls.getSegmentsTimer), this.prFetch.stop(), this.getSegmentsFetch.stop(), this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy(), this.cutRenders = /* @__PURE__ */ new Map(), z(this.stream), this.audioPlayer?.destroy();
|
|
462
461
|
} catch (t) {
|
|
463
462
|
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: error", t);
|
|
464
463
|
}
|
|
465
|
-
this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy(), this.cutRenders = /* @__PURE__ */ new Map(), z(this.stream), this.audioPlayer?.destroy();
|
|
466
464
|
};
|
|
467
465
|
/**
|
|
468
466
|
* 获取媒体流
|
|
@@ -506,8 +504,12 @@ class tt {
|
|
|
506
504
|
* 创建剪切
|
|
507
505
|
*/
|
|
508
506
|
create: (t, s) => {
|
|
509
|
-
|
|
510
|
-
|
|
507
|
+
if (this.converter === "generator") {
|
|
508
|
+
const o = new MediaStreamTrackGenerator({ kind: "video" }), a = new MediaStream([o]);
|
|
509
|
+
return this.renderWorker?.addCut({ key: t, writable: o.writable, option: s }), this.cutRenders.set(t, { stream: a }), a;
|
|
510
|
+
}
|
|
511
|
+
const e = document.createElement("canvas"), n = e.captureStream(), i = e.transferControlToOffscreen();
|
|
512
|
+
return this.renderWorker?.addCut({ key: t, offscreen: i, option: s }), this.cutRenders.set(t, { stream: n }), n;
|
|
511
513
|
},
|
|
512
514
|
/**
|
|
513
515
|
* 设置剪切
|
|
@@ -553,14 +555,14 @@ class tt {
|
|
|
553
555
|
switch (e) {
|
|
554
556
|
case "audio":
|
|
555
557
|
{
|
|
556
|
-
const { codec:
|
|
557
|
-
this.decoderWorker?.initAudio({ codec:
|
|
558
|
+
const { codec: n, sampleRate: i, numberOfChannels: o } = s;
|
|
559
|
+
this.decoderWorker?.initAudio({ codec: n, sampleRate: i, numberOfChannels: o });
|
|
558
560
|
}
|
|
559
561
|
break;
|
|
560
562
|
case "video":
|
|
561
563
|
{
|
|
562
|
-
const { codec:
|
|
563
|
-
this.decoderWorker?.initVideo({ codec:
|
|
564
|
+
const { codec: n, description: i } = s;
|
|
565
|
+
this.decoderWorker?.initVideo({ codec: n, description: i });
|
|
564
566
|
}
|
|
565
567
|
break;
|
|
566
568
|
}
|
|
@@ -570,14 +572,14 @@ class tt {
|
|
|
570
572
|
switch (e) {
|
|
571
573
|
case "audio":
|
|
572
574
|
{
|
|
573
|
-
const { type:
|
|
574
|
-
this.decoderWorker.push({ kind: e, init: { type:
|
|
575
|
+
const { type: n, dts: i, data: o } = s, a = i * 1e3;
|
|
576
|
+
this.decoderWorker.push({ kind: e, init: { type: n, timestamp: a, data: o } });
|
|
575
577
|
}
|
|
576
578
|
break;
|
|
577
579
|
case "video":
|
|
578
580
|
{
|
|
579
|
-
const { type:
|
|
580
|
-
this.decoderWorker.push({ kind: e, init: { type:
|
|
581
|
+
const { type: n, dts: i, data: o, nalus: a = [] } = s, r = i * 1e3;
|
|
582
|
+
this.decoderWorker.push({ kind: e, init: { type: n, timestamp: r, data: o }, nalus: a });
|
|
581
583
|
}
|
|
582
584
|
break;
|
|
583
585
|
}
|
|
@@ -587,7 +589,7 @@ class tt {
|
|
|
587
589
|
* 初始化解码器
|
|
588
590
|
*/
|
|
589
591
|
initDecoder = (t) => {
|
|
590
|
-
this.decoderWorker = new
|
|
592
|
+
this.decoderWorker = new V(), this.decoderWorker.init(t);
|
|
591
593
|
const { frameTrack: s = !1 } = this.option;
|
|
592
594
|
this.decoderWorker.setFrameTrack(s), this.decoderWorker.on.audio.decode = (e) => {
|
|
593
595
|
this.audioPlayer?.push(e), this.on.decoder.audio && this.on.decoder.audio(e);
|
|
@@ -598,9 +600,9 @@ class tt {
|
|
|
598
600
|
}, this.decoderWorker.on.video.error = (e) => {
|
|
599
601
|
this.on.error && this.on.error(e);
|
|
600
602
|
}, this.decoderWorker.on.nalus = async (e) => {
|
|
601
|
-
for (const
|
|
602
|
-
if (
|
|
603
|
-
const { header:
|
|
603
|
+
for (const n of e) {
|
|
604
|
+
if (n.byteLength <= 4) continue;
|
|
605
|
+
const { header: i, data: o } = X(n), { nal_unit_type: a } = i;
|
|
604
606
|
a === 6 && this.on.decoder.sei && this.on.decoder.sei(o);
|
|
605
607
|
}
|
|
606
608
|
}, this.decoderWorker.on.analysis = (e) => {
|
|
@@ -611,30 +613,35 @@ class tt {
|
|
|
611
613
|
* 初始化渲染器
|
|
612
614
|
*/
|
|
613
615
|
initRender = () => {
|
|
614
|
-
this.renderWorker = new
|
|
615
|
-
|
|
616
|
-
|
|
616
|
+
if (this.renderWorker = new B(), this.converter === "generator") {
|
|
617
|
+
const t = new MediaStreamTrackGenerator({ kind: "video" }), s = new MediaStream([t]);
|
|
618
|
+
this.renderWorker?.addCut({ writable: t.writable }), this.stream = s;
|
|
619
|
+
} else {
|
|
620
|
+
const t = document.createElement("canvas"), s = t.captureStream(), e = t.transferControlToOffscreen();
|
|
621
|
+
this.renderWorker?.addCut({ offscreen: e }), this.stream = s;
|
|
622
|
+
}
|
|
623
|
+
this.renderWorker?.setPause({ pause: !1 });
|
|
617
624
|
};
|
|
618
625
|
flv = {
|
|
619
626
|
start: () => new Promise(async (t, s) => {
|
|
620
627
|
try {
|
|
621
628
|
this.start_resolve = t;
|
|
622
|
-
let e,
|
|
629
|
+
let e, n = 0;
|
|
623
630
|
for (; ; ) {
|
|
624
|
-
|
|
631
|
+
n += 1;
|
|
625
632
|
try {
|
|
626
633
|
e = await this.prFetch.request(this.url);
|
|
627
634
|
} catch (o) {
|
|
628
635
|
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error", o);
|
|
629
636
|
}
|
|
630
|
-
if (e?.status === 200 ||
|
|
637
|
+
if (e?.status === 200 || n === 3) break;
|
|
631
638
|
await new Promise((o) => setTimeout(() => o(!0), 500));
|
|
632
639
|
}
|
|
633
640
|
if (!e || e.status !== 200) return s("request is error.");
|
|
634
|
-
const
|
|
635
|
-
if (!
|
|
641
|
+
const i = e.body?.getReader();
|
|
642
|
+
if (!i) return s("reader is error.");
|
|
636
643
|
for (; ; ) {
|
|
637
|
-
const { done: o, value: a } = await
|
|
644
|
+
const { done: o, value: a } = await i.read();
|
|
638
645
|
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
639
646
|
}
|
|
640
647
|
} catch (e) {
|
|
@@ -648,17 +655,17 @@ class tt {
|
|
|
648
655
|
url: "",
|
|
649
656
|
getSegmentsTimer: 0,
|
|
650
657
|
parse: async (t) => {
|
|
651
|
-
const
|
|
652
|
-
`).map((c) => c.replace("\r", "")),
|
|
658
|
+
const n = new TextDecoder("utf-8").decode(t).split(`
|
|
659
|
+
`).map((c) => c.replace("\r", "")), i = this.url.substring(0, this.url.lastIndexOf("/") + 1);
|
|
653
660
|
let o = 4, a = 0, r = !1;
|
|
654
661
|
const d = [];
|
|
655
|
-
for (const c of
|
|
662
|
+
for (const c of n)
|
|
656
663
|
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({
|
|
657
|
-
url: c.startsWith("http") ? c :
|
|
664
|
+
url: c.startsWith("http") ? c : i + c,
|
|
658
665
|
duration: o,
|
|
659
666
|
isLive: r
|
|
660
667
|
});
|
|
661
|
-
return { baseUrl:
|
|
668
|
+
return { baseUrl: i, targetDuration: a, isLive: r, segments: d };
|
|
662
669
|
},
|
|
663
670
|
getSegments: async () => {
|
|
664
671
|
try {
|
|
@@ -667,25 +674,25 @@ class tt {
|
|
|
667
674
|
s += 1;
|
|
668
675
|
try {
|
|
669
676
|
t = await this.getSegmentsFetch.request(this.url);
|
|
670
|
-
} catch (
|
|
671
|
-
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error",
|
|
677
|
+
} catch (n) {
|
|
678
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error", n);
|
|
672
679
|
}
|
|
673
680
|
if (t?.status === 200 || s === 3) break;
|
|
674
|
-
await new Promise((
|
|
681
|
+
await new Promise((n) => setTimeout(() => n(!0), 500));
|
|
675
682
|
}
|
|
676
683
|
if (!t || t.status !== 200) throw new Error("request is error.");
|
|
677
684
|
const e = t.body?.getReader();
|
|
678
685
|
if (!e) throw new Error("reader is error.");
|
|
679
686
|
for (; ; ) {
|
|
680
|
-
const { done:
|
|
681
|
-
if (
|
|
682
|
-
const o = await this.hls.parse(
|
|
687
|
+
const { done: n, value: i } = await e.read();
|
|
688
|
+
if (i) {
|
|
689
|
+
const o = await this.hls.parse(i), { segments: a = [], isLive: r = !1 } = o;
|
|
683
690
|
this.hls.isLive = r, r === !1 && (this.option.frameTrack = !1);
|
|
684
691
|
let d = Array.from(a, (h) => h.url);
|
|
685
692
|
const c = d.findIndex((h) => h === this.hls.url);
|
|
686
693
|
c !== -1 && (d = d.slice(c + 1)), this.hls.urls = d;
|
|
687
694
|
}
|
|
688
|
-
if (
|
|
695
|
+
if (n || this.url === "") break;
|
|
689
696
|
}
|
|
690
697
|
} catch (t) {
|
|
691
698
|
t.name !== "AbortError" && this.on.error && this.on.error(t);
|
|
@@ -697,14 +704,14 @@ class tt {
|
|
|
697
704
|
const e = this.hls.urls.shift();
|
|
698
705
|
if (e) {
|
|
699
706
|
this.hls.url = e;
|
|
700
|
-
const
|
|
701
|
-
if (!
|
|
707
|
+
const i = (await this.prFetch.request(e)).body?.getReader();
|
|
708
|
+
if (!i) throw new Error("segment reader is error.");
|
|
702
709
|
for (; ; ) {
|
|
703
|
-
const { done: o, value: a } = await
|
|
710
|
+
const { done: o, value: a } = await i.read();
|
|
704
711
|
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
705
712
|
}
|
|
706
713
|
} else
|
|
707
|
-
await new Promise((
|
|
714
|
+
await new Promise((n) => setTimeout(() => n(!0), 300));
|
|
708
715
|
}
|
|
709
716
|
} catch (e) {
|
|
710
717
|
e.name !== "AbortError" && s(e);
|
|
@@ -785,10 +792,10 @@ class J {
|
|
|
785
792
|
if (t.getUint8(s) !== 71)
|
|
786
793
|
throw new Error("Invalid TS packet");
|
|
787
794
|
let e = s;
|
|
788
|
-
const
|
|
795
|
+
const n = this.parseHeader(t, e);
|
|
789
796
|
e += 4;
|
|
790
|
-
const { transport_error_indicator:
|
|
791
|
-
if (
|
|
797
|
+
const { transport_error_indicator: i, pid: o, payload_unit_start_indicator: a, adaptation_field_control: r } = n;
|
|
798
|
+
if (i === 1 || o === void 0) return;
|
|
792
799
|
let d = 184;
|
|
793
800
|
if (r === 2 || r === 3) {
|
|
794
801
|
const c = t.getUint8(e);
|
|
@@ -834,14 +841,14 @@ class J {
|
|
|
834
841
|
// Header
|
|
835
842
|
parseHeader = (t, s) => {
|
|
836
843
|
let e = s;
|
|
837
|
-
const
|
|
838
|
-
if (r === 1) return { sync_byte:
|
|
839
|
-
const d = (
|
|
840
|
-
return { sync_byte:
|
|
844
|
+
const n = t.getUint8(e), i = t.getUint8(e + 1), o = t.getUint8(e + 2), a = t.getUint8(e + 3), r = (i & 128) >> 7;
|
|
845
|
+
if (r === 1) return { sync_byte: n, transport_error_indicator: r };
|
|
846
|
+
const d = (i & 64) >> 6, c = (i & 32) >> 5, h = (i & 31) << 8 | o, l = (a & 192) >> 6, u = a >> 4 & 3, g = a & 15;
|
|
847
|
+
return { sync_byte: n, 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 };
|
|
841
848
|
};
|
|
842
849
|
// PAT表
|
|
843
850
|
parsePAT = (t, s) => {
|
|
844
|
-
let e = s,
|
|
851
|
+
let e = s, n;
|
|
845
852
|
{
|
|
846
853
|
const a = t.getUint8(e);
|
|
847
854
|
e += 1;
|
|
@@ -856,22 +863,22 @@ class J {
|
|
|
856
863
|
const u = t.getUint8(e);
|
|
857
864
|
e += 1;
|
|
858
865
|
const g = t.getUint8(e);
|
|
859
|
-
e += 1,
|
|
866
|
+
e += 1, n = { 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 };
|
|
860
867
|
}
|
|
861
|
-
const
|
|
868
|
+
const i = [];
|
|
862
869
|
{
|
|
863
|
-
const a =
|
|
870
|
+
const a = n.section_length - 5 - 4, r = e + a;
|
|
864
871
|
for (; e < r; ) {
|
|
865
872
|
const d = t.getUint16(e), c = t.getUint16(e + 2) & 8191;
|
|
866
|
-
e += 4, d !== 0 && c >= 32 && c <= 8190 &&
|
|
873
|
+
e += 4, d !== 0 && c >= 32 && c <= 8190 && i.push({ program_number: d, pmt_pid: c });
|
|
867
874
|
}
|
|
868
875
|
}
|
|
869
876
|
const o = t.getUint32(e);
|
|
870
|
-
this.pat = { header:
|
|
877
|
+
this.pat = { header: n, programs: i, crc32: o }, this.on.debug && this.on.debug({ pat: this.pat });
|
|
871
878
|
};
|
|
872
879
|
// PMT表
|
|
873
880
|
parsePMT = (t, s) => {
|
|
874
|
-
let e = s,
|
|
881
|
+
let e = s, n;
|
|
875
882
|
{
|
|
876
883
|
const a = t.getUint8(e);
|
|
877
884
|
e += 1;
|
|
@@ -889,44 +896,44 @@ class J {
|
|
|
889
896
|
e += 1;
|
|
890
897
|
const f = t.getUint16(e) & 8191;
|
|
891
898
|
e += 2;
|
|
892
|
-
const
|
|
893
|
-
e += 2,
|
|
899
|
+
const m = t.getUint16(e) & 4095;
|
|
900
|
+
e += 2, n = { 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: m };
|
|
894
901
|
}
|
|
895
|
-
const
|
|
902
|
+
const i = [];
|
|
896
903
|
{
|
|
897
|
-
const a =
|
|
904
|
+
const a = n.section_length - 9 - 4, r = e + a;
|
|
898
905
|
for (; e < r; ) {
|
|
899
906
|
const d = t.getUint8(e), c = Q(d), h = t.getUint16(e + 1) & 8191, l = t.getUint16(e + 3) & 4095;
|
|
900
907
|
if (e += 5, h < 32 || h > 8190) {
|
|
901
908
|
console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);
|
|
902
909
|
continue;
|
|
903
910
|
}
|
|
904
|
-
|
|
911
|
+
i.push({ kind: c, stream_type: d, elementary_pid: h, es_info_length: l });
|
|
905
912
|
}
|
|
906
913
|
}
|
|
907
914
|
const o = t.getUint32(e);
|
|
908
|
-
this.pmt = { header:
|
|
915
|
+
this.pmt = { header: n, streams: i, crc32: o }, this.on.debug && this.on.debug({ pmt: this.pmt });
|
|
909
916
|
};
|
|
910
917
|
// AdaptationField
|
|
911
918
|
parseAdaptationField = (t, s) => {
|
|
912
|
-
let e = s,
|
|
913
|
-
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),
|
|
919
|
+
let e = s, n, i, o, a;
|
|
920
|
+
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), m = !!(r & 1);
|
|
914
921
|
e += 1;
|
|
915
922
|
const b = (k, w) => {
|
|
916
923
|
let U = BigInt(0);
|
|
917
924
|
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);
|
|
918
|
-
const
|
|
919
|
-
return U = U * 300n + BigInt(
|
|
925
|
+
const R = (k.getUint16(w + 4) & 1) << 8 | k.getUint16(w + 5);
|
|
926
|
+
return U = U * 300n + BigInt(R), U;
|
|
920
927
|
};
|
|
921
|
-
if (l && (
|
|
928
|
+
if (l && (n = b(t, e), e += 6), u && (i = b(t, e), e += 6), g && (o = t.getInt8(e), e += 1), f) {
|
|
922
929
|
const k = t.getUint8(e);
|
|
923
930
|
e += 1, a = new Uint8Array(t.buffer, e, k), e += k;
|
|
924
931
|
}
|
|
925
|
-
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:
|
|
932
|
+
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: m, pcr: n, opcr: i, splice_countdown: o, transport_private_data: a };
|
|
926
933
|
};
|
|
927
934
|
parseAudio = async (t) => {
|
|
928
935
|
const s = new DataView(t.buffer);
|
|
929
|
-
let e = 0,
|
|
936
|
+
let e = 0, n, i;
|
|
930
937
|
{
|
|
931
938
|
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
932
939
|
if (e += 3, !o)
|
|
@@ -937,19 +944,19 @@ class J {
|
|
|
937
944
|
e += 2;
|
|
938
945
|
let d, c, h, l, u;
|
|
939
946
|
{
|
|
940
|
-
const
|
|
941
|
-
e += 1, d =
|
|
947
|
+
const m = s.getUint8(e);
|
|
948
|
+
e += 1, d = m >> 4 & 3, c = (m >> 3 & 1) === 1, h = (m >> 2 & 1) === 1, l = (m >> 1 & 1) === 1, u = (m & 1) === 1;
|
|
942
949
|
}
|
|
943
950
|
let g, f;
|
|
944
951
|
{
|
|
945
|
-
const
|
|
952
|
+
const m = s.getUint8(e);
|
|
946
953
|
e += 1;
|
|
947
|
-
const b =
|
|
954
|
+
const b = m >> 6, k = s.getUint8(e);
|
|
948
955
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
949
956
|
}
|
|
950
|
-
|
|
957
|
+
n = { stream_id: a, pes_packet_length: r, scrambling_control: d, priority: c, data_alignment: h, copyright: l, original_copy: u, pts: g, dts: f };
|
|
951
958
|
}
|
|
952
|
-
|
|
959
|
+
i = t.slice(e);
|
|
953
960
|
{
|
|
954
961
|
if (!this.audioConfig && s.getUint8(e) === 255) {
|
|
955
962
|
const h = s.getUint8(e + 2), l = s.getUint8(e + 3);
|
|
@@ -958,13 +965,13 @@ class J {
|
|
|
958
965
|
const f = `mp4a.40.${u}`, b = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350][g];
|
|
959
966
|
this.audioConfig = { kind: "audio", codec: f, sampleRate: b, numberOfChannels: u }, this.on.config && this.on.config(this.audioConfig);
|
|
960
967
|
}
|
|
961
|
-
const { dts: o = 0, pts: a = 0 } =
|
|
968
|
+
const { dts: o = 0, pts: a = 0 } = n, r = a - o, d = i.slice(7);
|
|
962
969
|
return { kind: "audio", type: "key", dts: o, pts: a, cts: r, data: d };
|
|
963
970
|
}
|
|
964
971
|
};
|
|
965
972
|
parseVideo = async (t) => {
|
|
966
973
|
const s = new DataView(t.buffer);
|
|
967
|
-
let e = 0,
|
|
974
|
+
let e = 0, n, i;
|
|
968
975
|
{
|
|
969
976
|
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
970
977
|
if (e += 3, !o)
|
|
@@ -975,26 +982,26 @@ class J {
|
|
|
975
982
|
e += 2;
|
|
976
983
|
let d, c, h, l, u;
|
|
977
984
|
{
|
|
978
|
-
const
|
|
979
|
-
e += 1, d =
|
|
985
|
+
const m = s.getUint8(e);
|
|
986
|
+
e += 1, d = m >> 4 & 3, c = (m >> 3 & 1) === 1, h = (m >> 2 & 1) === 1, l = (m >> 1 & 1) === 1, u = (m & 1) === 1;
|
|
980
987
|
}
|
|
981
988
|
let g, f;
|
|
982
989
|
{
|
|
983
|
-
const
|
|
990
|
+
const m = s.getUint8(e);
|
|
984
991
|
e += 1;
|
|
985
|
-
const b =
|
|
992
|
+
const b = m >> 6, k = s.getUint8(e);
|
|
986
993
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
987
994
|
}
|
|
988
|
-
|
|
995
|
+
n = { stream_id: a, pes_packet_length: r, scrambling_control: d, priority: c, data_alignment: h, copyright: l, original_copy: u, pts: g, dts: f };
|
|
989
996
|
}
|
|
990
|
-
|
|
997
|
+
i = t.slice(e);
|
|
991
998
|
{
|
|
992
|
-
const o = this.getNalus(
|
|
999
|
+
const o = this.getNalus(i);
|
|
993
1000
|
if (!this.videoConfig) {
|
|
994
1001
|
let u, g;
|
|
995
|
-
if (u = o.find((
|
|
996
|
-
const f =
|
|
997
|
-
this.videoConfig = { kind: "video", codec:
|
|
1002
|
+
if (u = o.find((m) => m.type === 7)?.nalu.slice(4), g = o.find((m) => m.type === 8)?.nalu.slice(4), u && g) {
|
|
1003
|
+
const f = q(u, g), { codec: m } = D(f);
|
|
1004
|
+
this.videoConfig = { kind: "video", codec: m, description: f, sps: u, pps: g }, this.on.config && this.on.config(this.videoConfig);
|
|
998
1005
|
}
|
|
999
1006
|
}
|
|
1000
1007
|
const a = [];
|
|
@@ -1015,7 +1022,7 @@ class J {
|
|
|
1015
1022
|
break;
|
|
1016
1023
|
}
|
|
1017
1024
|
}
|
|
1018
|
-
const d = K(a), { dts: c = 0, pts: h = 0 } =
|
|
1025
|
+
const d = K(a), { dts: c = 0, pts: h = 0 } = n, l = h - c;
|
|
1019
1026
|
return { kind: "video", type: r, dts: c, pts: h, cts: l, data: d, nalus: a };
|
|
1020
1027
|
}
|
|
1021
1028
|
};
|
|
@@ -1023,7 +1030,7 @@ class J {
|
|
|
1023
1030
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
1024
1031
|
*/
|
|
1025
1032
|
parsePtsDts(t, s) {
|
|
1026
|
-
const e = t.getUint8(s),
|
|
1033
|
+
const e = t.getUint8(s), n = t.getUint8(s + 1), i = t.getUint8(s + 2), o = t.getUint8(s + 3), a = t.getUint8(s + 4), r = (BigInt(e) & 0b00001110n) << 29n | (BigInt(n) & 0b11111111n) << 22n | (BigInt(i) & 0b11111110n) << 14n | (BigInt(o) & 0b11111111n) << 7n | (BigInt(a) & 0b11111110n) >> 1n;
|
|
1027
1034
|
return Number(r) / 90;
|
|
1028
1035
|
}
|
|
1029
1036
|
getNalus = (t) => {
|
|
@@ -1035,8 +1042,8 @@ class J {
|
|
|
1035
1042
|
continue;
|
|
1036
1043
|
}
|
|
1037
1044
|
e += 3;
|
|
1038
|
-
let
|
|
1039
|
-
const
|
|
1045
|
+
let n = e;
|
|
1046
|
+
const i = t[e] & 31;
|
|
1040
1047
|
for (e += 1; !(e + 1 > t.byteLength); ) {
|
|
1041
1048
|
if (t[e] !== 0 || t[e + 1] !== 0 || t[e + 2] !== 1) {
|
|
1042
1049
|
e += 1;
|
|
@@ -1044,10 +1051,10 @@ class J {
|
|
|
1044
1051
|
}
|
|
1045
1052
|
break;
|
|
1046
1053
|
}
|
|
1047
|
-
let o = e -
|
|
1054
|
+
let o = e - n;
|
|
1048
1055
|
if (t[e - 1] === 0 && (o -= 1), o !== 0) {
|
|
1049
|
-
const a = t.slice(
|
|
1050
|
-
s.push({ type:
|
|
1056
|
+
const a = t.slice(n, n + o), r = H(a);
|
|
1057
|
+
s.push({ type: i, nalu: r });
|
|
1051
1058
|
}
|
|
1052
1059
|
}
|
|
1053
1060
|
return s;
|
|
@@ -1066,10 +1073,10 @@ class Z {
|
|
|
1066
1073
|
parse = async (t) => {
|
|
1067
1074
|
let s = 0;
|
|
1068
1075
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
1069
|
-
const
|
|
1070
|
-
if (
|
|
1071
|
-
const r = this.parseTagBody(
|
|
1072
|
-
switch (
|
|
1076
|
+
const n = this.parseTagHeader(t, s + 4), { tagType: i, dataSize: o, timestamp: a } = n;
|
|
1077
|
+
if (i) {
|
|
1078
|
+
const r = this.parseTagBody(i, t, s + 4 + 11, o);
|
|
1079
|
+
switch (i) {
|
|
1073
1080
|
case "script":
|
|
1074
1081
|
this.on.info && this.on.info(r);
|
|
1075
1082
|
break;
|
|
@@ -1106,30 +1113,30 @@ class Z {
|
|
|
1106
1113
|
};
|
|
1107
1114
|
// Header
|
|
1108
1115
|
parseHeader = (t, s) => {
|
|
1109
|
-
let e,
|
|
1110
|
-
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2),
|
|
1116
|
+
let e, n, i, o;
|
|
1117
|
+
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2), n = t.getUint8(3);
|
|
1111
1118
|
{
|
|
1112
1119
|
const r = t.getUint8(0).toString(2).padStart(5, "0").split(""), [, , d, , c] = r;
|
|
1113
|
-
|
|
1120
|
+
i = { audio: c === "1", video: d === "1" };
|
|
1114
1121
|
}
|
|
1115
|
-
o = t.getUint32(5), this.header = { signature: e, version:
|
|
1122
|
+
o = t.getUint32(5), this.header = { signature: e, version: n, flags: i, dataOffset: o };
|
|
1116
1123
|
};
|
|
1117
1124
|
// 是否是完整tag
|
|
1118
1125
|
isSurplusTag = (t, s) => {
|
|
1119
1126
|
let e = !0;
|
|
1120
|
-
const
|
|
1121
|
-
if (s + 4 >
|
|
1127
|
+
const n = t.byteLength;
|
|
1128
|
+
if (s + 4 > n)
|
|
1122
1129
|
e = !1;
|
|
1123
|
-
else if (s + 4 + 11 >
|
|
1130
|
+
else if (s + 4 + 11 > n)
|
|
1124
1131
|
e = !1;
|
|
1125
1132
|
else {
|
|
1126
|
-
const
|
|
1127
|
-
s + 4 + 11 +
|
|
1133
|
+
const i = T(t, s + 4 + 1);
|
|
1134
|
+
s + 4 + 11 + i > n && (e = !1);
|
|
1128
1135
|
}
|
|
1129
1136
|
return e;
|
|
1130
1137
|
};
|
|
1131
1138
|
parseTagHeader = (t, s) => {
|
|
1132
|
-
let e,
|
|
1139
|
+
let e, n, i, o, a;
|
|
1133
1140
|
{
|
|
1134
1141
|
const r = t.getUint8(s);
|
|
1135
1142
|
let d;
|
|
@@ -1146,22 +1153,22 @@ class Z {
|
|
|
1146
1153
|
}
|
|
1147
1154
|
e = d;
|
|
1148
1155
|
}
|
|
1149
|
-
return
|
|
1156
|
+
return n = T(t, s + 1), i = T(t, s + 4), o = t.getUint8(s + 7), a = T(t, s + 8), { tagType: e, dataSize: n, timestamp: i, timestampExtended: o, streamID: a };
|
|
1150
1157
|
};
|
|
1151
|
-
parseTagBody = (t, s, e,
|
|
1152
|
-
let
|
|
1158
|
+
parseTagBody = (t, s, e, n) => {
|
|
1159
|
+
let i;
|
|
1153
1160
|
switch (t) {
|
|
1154
1161
|
case "script":
|
|
1155
|
-
|
|
1162
|
+
i = this.parseMetaData(s, e);
|
|
1156
1163
|
break;
|
|
1157
1164
|
case "audio":
|
|
1158
|
-
|
|
1165
|
+
i = this.parseAudio(s, e, n);
|
|
1159
1166
|
break;
|
|
1160
1167
|
case "video":
|
|
1161
|
-
|
|
1168
|
+
i = this.parseVideo(s, e, n);
|
|
1162
1169
|
break;
|
|
1163
1170
|
}
|
|
1164
|
-
return
|
|
1171
|
+
return i;
|
|
1165
1172
|
};
|
|
1166
1173
|
parseMetaData = (t, s) => {
|
|
1167
1174
|
let e = s;
|
|
@@ -1169,48 +1176,48 @@ class Z {
|
|
|
1169
1176
|
if (t.getUint8(e) !== 2) throw new Error("Invalid AMF type for onMetaData (expected 0x02)");
|
|
1170
1177
|
e = e + 1;
|
|
1171
1178
|
}
|
|
1172
|
-
const
|
|
1179
|
+
const n = t.getUint16(e, !1);
|
|
1173
1180
|
e = e + 2;
|
|
1174
1181
|
{
|
|
1175
|
-
const a = new Int8Array(t.buffer.slice(e, e +
|
|
1182
|
+
const a = new Int8Array(t.buffer.slice(e, e + n));
|
|
1176
1183
|
if ((this.textDecoder?.decode(a) || "") !== "onMetaData") throw new Error("Expected 'onMetaData' string");
|
|
1177
|
-
e = e +
|
|
1184
|
+
e = e + n;
|
|
1178
1185
|
}
|
|
1179
|
-
const
|
|
1180
|
-
return e = e + 1, this.getAMFValue(t, e,
|
|
1186
|
+
const i = this.getAmfType(t, e);
|
|
1187
|
+
return e = e + 1, this.getAMFValue(t, e, i).value;
|
|
1181
1188
|
};
|
|
1182
1189
|
parseAudio = (t, s, e) => {
|
|
1183
|
-
let
|
|
1184
|
-
const
|
|
1185
|
-
|
|
1186
|
-
const c = t.getUint8(
|
|
1187
|
-
|
|
1188
|
-
const h = e, l = new Uint8Array(t.buffer.slice(
|
|
1190
|
+
let n = s;
|
|
1191
|
+
const i = t.getUint8(n), o = i >> 4 & 15, a = i >> 2 & 3, r = i >> 1 & 1, d = i & 1;
|
|
1192
|
+
n = n + 1;
|
|
1193
|
+
const c = t.getUint8(n);
|
|
1194
|
+
n = n + 1;
|
|
1195
|
+
const h = e, l = new Uint8Array(t.buffer.slice(n, n + h));
|
|
1189
1196
|
if (o === 10 && c === 0) {
|
|
1190
|
-
const u = t.getUint8(
|
|
1191
|
-
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l, samplingFrequencyIndex:
|
|
1197
|
+
const u = t.getUint8(n), g = t.getUint8(n + 1), f = u >> 3 & 31, m = (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[m];
|
|
1198
|
+
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l, samplingFrequencyIndex: m, channelConfiguration: b, codec: w, sampleRate: U };
|
|
1192
1199
|
}
|
|
1193
1200
|
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l };
|
|
1194
1201
|
};
|
|
1195
1202
|
parseVideo = (t, s, e) => {
|
|
1196
|
-
let
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
const r = t.getUint8(
|
|
1200
|
-
|
|
1201
|
-
const d = T(t,
|
|
1202
|
-
|
|
1203
|
-
const c = e - 5, h = new Uint8Array(t.buffer.slice(
|
|
1203
|
+
let n = s;
|
|
1204
|
+
const i = t.getUint8(n), o = i >> 4 & 15, a = i & 15;
|
|
1205
|
+
n = n + 1;
|
|
1206
|
+
const r = t.getUint8(n);
|
|
1207
|
+
n = n + 1;
|
|
1208
|
+
const d = T(t, n);
|
|
1209
|
+
n = n + 3;
|
|
1210
|
+
const c = e - 5, h = new Uint8Array(t.buffer.slice(n, n + c));
|
|
1204
1211
|
switch (a) {
|
|
1205
1212
|
case 7:
|
|
1206
1213
|
if (r === 0) {
|
|
1207
|
-
const l =
|
|
1214
|
+
const l = D(h);
|
|
1208
1215
|
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, ...l };
|
|
1209
1216
|
} else if (r === 1) {
|
|
1210
|
-
const l = [], u =
|
|
1211
|
-
for (; !(
|
|
1212
|
-
const g = t.getUint32(
|
|
1213
|
-
|
|
1217
|
+
const l = [], u = n + e - 5;
|
|
1218
|
+
for (; !(n + 4 > u); ) {
|
|
1219
|
+
const g = t.getUint32(n, !1), f = new Uint8Array(t.buffer.slice(n, n + 4 + g));
|
|
1220
|
+
n += 4 + g, l.push(f);
|
|
1214
1221
|
}
|
|
1215
1222
|
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, nalus: l };
|
|
1216
1223
|
}
|
|
@@ -1222,73 +1229,73 @@ class Z {
|
|
|
1222
1229
|
};
|
|
1223
1230
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1224
1231
|
getAMFName = (t, s, e) => {
|
|
1225
|
-
const
|
|
1226
|
-
return this.textDecoder?.decode(
|
|
1232
|
+
const n = new Uint8Array(t.buffer.slice(s, s + e));
|
|
1233
|
+
return this.textDecoder?.decode(n) || "";
|
|
1227
1234
|
};
|
|
1228
1235
|
getAMFValue = (t, s, e) => {
|
|
1229
|
-
let
|
|
1236
|
+
let n = s, i, o = 0;
|
|
1230
1237
|
switch (e) {
|
|
1231
1238
|
case 0:
|
|
1232
|
-
|
|
1239
|
+
i = t.getFloat64(n, !1), o = 8;
|
|
1233
1240
|
break;
|
|
1234
1241
|
case 1:
|
|
1235
|
-
|
|
1242
|
+
i = !!t.getUint8(n), o = 1;
|
|
1236
1243
|
break;
|
|
1237
1244
|
case 2:
|
|
1238
1245
|
{
|
|
1239
|
-
|
|
1240
|
-
const r = t.getUint16(
|
|
1241
|
-
|
|
1242
|
-
const d = new Int8Array(t.buffer,
|
|
1243
|
-
|
|
1246
|
+
i = "";
|
|
1247
|
+
const r = t.getUint16(n, !1);
|
|
1248
|
+
n = n + 2;
|
|
1249
|
+
const d = new Int8Array(t.buffer, n, r).filter((h) => h !== 0);
|
|
1250
|
+
i = (this.textDecoder?.decode(d) || "").trim(), o = 2 + r;
|
|
1244
1251
|
}
|
|
1245
1252
|
break;
|
|
1246
1253
|
case 3:
|
|
1247
|
-
for (
|
|
1248
|
-
const r = t.getUint16(
|
|
1254
|
+
for (i = {}; n < t.byteLength; ) {
|
|
1255
|
+
const r = t.getUint16(n, !1);
|
|
1249
1256
|
if (r === 0) break;
|
|
1250
|
-
|
|
1251
|
-
const d = this.getAMFName(t,
|
|
1252
|
-
|
|
1253
|
-
const c = this.getAmfType(t,
|
|
1257
|
+
n = n + 2;
|
|
1258
|
+
const d = this.getAMFName(t, n, r);
|
|
1259
|
+
n = n + r;
|
|
1260
|
+
const c = this.getAmfType(t, n);
|
|
1254
1261
|
if (c === 6) break;
|
|
1255
|
-
|
|
1256
|
-
const h = this.getAMFValue(t,
|
|
1257
|
-
|
|
1262
|
+
n = n + 1;
|
|
1263
|
+
const h = this.getAMFValue(t, n, c);
|
|
1264
|
+
n = n + h.length, i[d] = h.value, o = 2 + r + 1 + h.length;
|
|
1258
1265
|
}
|
|
1259
1266
|
break;
|
|
1260
1267
|
case 8:
|
|
1261
1268
|
{
|
|
1262
|
-
|
|
1263
|
-
const r = t.getUint32(
|
|
1264
|
-
|
|
1269
|
+
i = {};
|
|
1270
|
+
const r = t.getUint32(n, !1);
|
|
1271
|
+
n = n + 4;
|
|
1265
1272
|
for (let d = 0; d < r; d++) {
|
|
1266
|
-
const c = t.getUint16(
|
|
1267
|
-
|
|
1268
|
-
const h = this.getAMFName(t,
|
|
1269
|
-
|
|
1270
|
-
const l = this.getAmfType(t,
|
|
1271
|
-
|
|
1272
|
-
const u = this.getAMFValue(t,
|
|
1273
|
-
|
|
1273
|
+
const c = t.getUint16(n, !1);
|
|
1274
|
+
n = n + 2;
|
|
1275
|
+
const h = this.getAMFName(t, n, c);
|
|
1276
|
+
n = n + c;
|
|
1277
|
+
const l = this.getAmfType(t, n);
|
|
1278
|
+
n = n + 1;
|
|
1279
|
+
const u = this.getAMFValue(t, n, l);
|
|
1280
|
+
n = n + u.length, i[h] = u.value, o = 2 + c + 1 + u.length;
|
|
1274
1281
|
}
|
|
1275
1282
|
}
|
|
1276
1283
|
break;
|
|
1277
1284
|
case 10:
|
|
1278
1285
|
{
|
|
1279
|
-
|
|
1280
|
-
const r = t.getUint32(
|
|
1281
|
-
|
|
1286
|
+
i = [];
|
|
1287
|
+
const r = t.getUint32(n, !1);
|
|
1288
|
+
n = n + 4;
|
|
1282
1289
|
for (let d = 0; d < r; d++) {
|
|
1283
|
-
const c = this.getAmfType(t,
|
|
1284
|
-
|
|
1285
|
-
const h = this.getAMFValue(t,
|
|
1286
|
-
|
|
1290
|
+
const c = this.getAmfType(t, n);
|
|
1291
|
+
n = n + 1;
|
|
1292
|
+
const h = this.getAMFValue(t, n, c);
|
|
1293
|
+
n = n + h.length, i.push(h.value), o = 1 + h.length;
|
|
1287
1294
|
}
|
|
1288
1295
|
}
|
|
1289
1296
|
break;
|
|
1290
1297
|
}
|
|
1291
|
-
return { amfType: e, length: o, value:
|
|
1298
|
+
return { amfType: e, length: o, value: i };
|
|
1292
1299
|
};
|
|
1293
1300
|
}
|
|
1294
1301
|
class et {
|
|
@@ -1402,8 +1409,13 @@ class st {
|
|
|
1402
1409
|
this.video.destroy(), this.videoDecoderConfig = { ...t }, this.videoDecoder = new VideoDecoder({
|
|
1403
1410
|
output: async (s) => {
|
|
1404
1411
|
this.frameStartTime || (this.frameStartTime = s.timestamp);
|
|
1405
|
-
|
|
1406
|
-
|
|
1412
|
+
try {
|
|
1413
|
+
const e = s.timestamp - this.frameStartTime + this.baseTime * 1e3, n = await createImageBitmap(s);
|
|
1414
|
+
if (s.close(), !n.width || !n.height) return n.close();
|
|
1415
|
+
this.on.video.decode && this.on.video.decode({ timestamp: e, bitmap: n }), this.currentChunk && this.currentChunk.kind === "video" && this.currentChunk.nalus && this.on.nalus && this.on.nalus(this.currentChunk.nalus);
|
|
1416
|
+
} catch {
|
|
1417
|
+
s.close();
|
|
1418
|
+
}
|
|
1407
1419
|
},
|
|
1408
1420
|
error: (s) => {
|
|
1409
1421
|
this.on.video.error && this.on.video.error(s);
|
|
@@ -1435,16 +1447,16 @@ class st {
|
|
|
1435
1447
|
for (this.isProcessing = !0; this.currentChunk = this.pendingChunks.shift(), !!this.currentChunk; ) {
|
|
1436
1448
|
const t = this.pendingChunks.length;
|
|
1437
1449
|
if (this.frameTrack) {
|
|
1438
|
-
const [
|
|
1439
|
-
if (t <=
|
|
1440
|
-
const o = Math.min(1 + (t -
|
|
1450
|
+
const [n, i] = this.fameTrackOption[this.pattern];
|
|
1451
|
+
if (t <= n && (this.isFrameTrack = !1), t >= i && (this.isFrameTrack = !0), this.isFrameTrack) {
|
|
1452
|
+
const o = Math.min(1 + (t - n) / 100, this.maxDecodingSpeedRatio);
|
|
1441
1453
|
this.decodingSpeedRatio = Number(o.toFixed(1));
|
|
1442
1454
|
} else
|
|
1443
1455
|
this.decodingSpeedRatio = 1;
|
|
1444
1456
|
}
|
|
1445
1457
|
if (this.on.analysis) {
|
|
1446
|
-
const { decodingSpeed:
|
|
1447
|
-
this.on.analysis({ decodingSpeed:
|
|
1458
|
+
const { decodingSpeed: n, decodingSpeedRatio: i, fps: o } = this;
|
|
1459
|
+
this.on.analysis({ decodingSpeed: n, decodingSpeedRatio: i, fps: o, cacheLength: t });
|
|
1448
1460
|
}
|
|
1449
1461
|
const { kind: s, init: e } = this.currentChunk;
|
|
1450
1462
|
switch (s) {
|
|
@@ -1488,27 +1500,38 @@ class st {
|
|
|
1488
1500
|
}
|
|
1489
1501
|
};
|
|
1490
1502
|
}
|
|
1491
|
-
class
|
|
1503
|
+
class nt {
|
|
1492
1504
|
renderMap = /* @__PURE__ */ new Map();
|
|
1493
1505
|
constructor() {
|
|
1494
1506
|
}
|
|
1495
1507
|
push = async (t) => {
|
|
1496
1508
|
const { timestamp: s } = t, { bitmap: e } = t;
|
|
1497
|
-
if (e.height === 0 || e.width === 0)
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1509
|
+
if (e.height === 0 || e.width === 0) return e.close();
|
|
1510
|
+
try {
|
|
1511
|
+
const n = [...this.renderMap.keys()];
|
|
1512
|
+
for (const i of n) {
|
|
1513
|
+
const o = this.renderMap.get(i);
|
|
1514
|
+
if (!o) continue;
|
|
1515
|
+
const { pause: a = !1, writer: r, offscreen: d, option: c } = o;
|
|
1516
|
+
if (a === !0) continue;
|
|
1517
|
+
const h = (l) => {
|
|
1518
|
+
if (r) {
|
|
1519
|
+
const u = new VideoFrame(l, { timestamp: s });
|
|
1520
|
+
try {
|
|
1521
|
+
u && r.write(u);
|
|
1522
|
+
} catch {
|
|
1523
|
+
}
|
|
1524
|
+
u.close();
|
|
1525
|
+
} else d && (d.width = l.width, d.height = l.height, d?.getContext("2d")?.drawImage(l, 0, 0));
|
|
1526
|
+
};
|
|
1527
|
+
if (i === "default")
|
|
1528
|
+
h(e);
|
|
1529
|
+
else if (c) {
|
|
1530
|
+
const { sx: l = 0, sy: u = 0, sw: g = e.width, sh: f = e.height } = c, m = await createImageBitmap(e, l, u, g, f);
|
|
1531
|
+
h(m);
|
|
1511
1532
|
}
|
|
1533
|
+
}
|
|
1534
|
+
} catch {
|
|
1512
1535
|
}
|
|
1513
1536
|
e.close();
|
|
1514
1537
|
};
|
|
@@ -1516,8 +1539,12 @@ class it {
|
|
|
1516
1539
|
* 增加剪切
|
|
1517
1540
|
*/
|
|
1518
1541
|
addCut = (t) => {
|
|
1519
|
-
const { key: s, writable: e, option: i } = { key: "default", ...t }
|
|
1520
|
-
|
|
1542
|
+
const { key: s, writable: e, offscreen: n, option: i } = { key: "default", ...t };
|
|
1543
|
+
if (e) {
|
|
1544
|
+
const o = e.getWriter();
|
|
1545
|
+
this.renderMap.set(s, { writer: o, option: i, pause: !1 });
|
|
1546
|
+
} else
|
|
1547
|
+
this.renderMap.set(s, { offscreen: n, option: i, pause: !1 });
|
|
1521
1548
|
};
|
|
1522
1549
|
/**
|
|
1523
1550
|
* 删除剪切
|
|
@@ -1529,15 +1556,15 @@ class it {
|
|
|
1529
1556
|
* 设置剪切
|
|
1530
1557
|
*/
|
|
1531
1558
|
setCut = (t) => {
|
|
1532
|
-
const { key: s, cutOption: e } = { key: "default", ...t },
|
|
1533
|
-
|
|
1559
|
+
const { key: s, cutOption: e } = { key: "default", ...t }, n = this.renderMap.get(s);
|
|
1560
|
+
n && this.renderMap.set(s, { ...n, option: e });
|
|
1534
1561
|
};
|
|
1535
1562
|
/**
|
|
1536
1563
|
* 设置暂停
|
|
1537
1564
|
*/
|
|
1538
1565
|
setPause = (t) => {
|
|
1539
|
-
const { key: s, pause: e } = { key: "default", ...t },
|
|
1540
|
-
|
|
1566
|
+
const { key: s, pause: e } = { key: "default", ...t }, n = this.renderMap.get(s);
|
|
1567
|
+
n && this.renderMap.set(s, { ...n, pause: e });
|
|
1541
1568
|
};
|
|
1542
1569
|
destroy = () => {
|
|
1543
1570
|
this.renderMap = /* @__PURE__ */ new Map();
|
|
@@ -1545,10 +1572,10 @@ class it {
|
|
|
1545
1572
|
}
|
|
1546
1573
|
export {
|
|
1547
1574
|
st as Decoder,
|
|
1548
|
-
|
|
1575
|
+
V as DecoderWorker,
|
|
1549
1576
|
et as Demuxer,
|
|
1550
1577
|
I as DemuxerWorker,
|
|
1551
1578
|
tt as PrPlayer,
|
|
1552
|
-
|
|
1553
|
-
|
|
1579
|
+
nt as Render,
|
|
1580
|
+
B as RenderWorker
|
|
1554
1581
|
};
|