pr-player 0.3.1 → 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 +10 -0
- package/dist/index.js +364 -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,18 @@ 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;
|
|
513
|
+
},
|
|
514
|
+
/**
|
|
515
|
+
* 设置剪切
|
|
516
|
+
*/
|
|
517
|
+
setCut: (t, s) => {
|
|
518
|
+
this.renderWorker?.setCut({ key: t, cutOption: s });
|
|
511
519
|
},
|
|
512
520
|
/**
|
|
513
521
|
* 获取媒体流
|
|
@@ -547,14 +555,14 @@ class tt {
|
|
|
547
555
|
switch (e) {
|
|
548
556
|
case "audio":
|
|
549
557
|
{
|
|
550
|
-
const { codec:
|
|
551
|
-
this.decoderWorker?.initAudio({ codec:
|
|
558
|
+
const { codec: n, sampleRate: i, numberOfChannels: o } = s;
|
|
559
|
+
this.decoderWorker?.initAudio({ codec: n, sampleRate: i, numberOfChannels: o });
|
|
552
560
|
}
|
|
553
561
|
break;
|
|
554
562
|
case "video":
|
|
555
563
|
{
|
|
556
|
-
const { codec:
|
|
557
|
-
this.decoderWorker?.initVideo({ codec:
|
|
564
|
+
const { codec: n, description: i } = s;
|
|
565
|
+
this.decoderWorker?.initVideo({ codec: n, description: i });
|
|
558
566
|
}
|
|
559
567
|
break;
|
|
560
568
|
}
|
|
@@ -564,14 +572,14 @@ class tt {
|
|
|
564
572
|
switch (e) {
|
|
565
573
|
case "audio":
|
|
566
574
|
{
|
|
567
|
-
const { type:
|
|
568
|
-
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 } });
|
|
569
577
|
}
|
|
570
578
|
break;
|
|
571
579
|
case "video":
|
|
572
580
|
{
|
|
573
|
-
const { type:
|
|
574
|
-
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 });
|
|
575
583
|
}
|
|
576
584
|
break;
|
|
577
585
|
}
|
|
@@ -581,7 +589,7 @@ class tt {
|
|
|
581
589
|
* 初始化解码器
|
|
582
590
|
*/
|
|
583
591
|
initDecoder = (t) => {
|
|
584
|
-
this.decoderWorker = new
|
|
592
|
+
this.decoderWorker = new V(), this.decoderWorker.init(t);
|
|
585
593
|
const { frameTrack: s = !1 } = this.option;
|
|
586
594
|
this.decoderWorker.setFrameTrack(s), this.decoderWorker.on.audio.decode = (e) => {
|
|
587
595
|
this.audioPlayer?.push(e), this.on.decoder.audio && this.on.decoder.audio(e);
|
|
@@ -592,9 +600,9 @@ class tt {
|
|
|
592
600
|
}, this.decoderWorker.on.video.error = (e) => {
|
|
593
601
|
this.on.error && this.on.error(e);
|
|
594
602
|
}, this.decoderWorker.on.nalus = async (e) => {
|
|
595
|
-
for (const
|
|
596
|
-
if (
|
|
597
|
-
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;
|
|
598
606
|
a === 6 && this.on.decoder.sei && this.on.decoder.sei(o);
|
|
599
607
|
}
|
|
600
608
|
}, this.decoderWorker.on.analysis = (e) => {
|
|
@@ -605,30 +613,35 @@ class tt {
|
|
|
605
613
|
* 初始化渲染器
|
|
606
614
|
*/
|
|
607
615
|
initRender = () => {
|
|
608
|
-
this.renderWorker = new
|
|
609
|
-
|
|
610
|
-
|
|
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 });
|
|
611
624
|
};
|
|
612
625
|
flv = {
|
|
613
626
|
start: () => new Promise(async (t, s) => {
|
|
614
627
|
try {
|
|
615
628
|
this.start_resolve = t;
|
|
616
|
-
let e,
|
|
629
|
+
let e, n = 0;
|
|
617
630
|
for (; ; ) {
|
|
618
|
-
|
|
631
|
+
n += 1;
|
|
619
632
|
try {
|
|
620
633
|
e = await this.prFetch.request(this.url);
|
|
621
634
|
} catch (o) {
|
|
622
635
|
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: error", o);
|
|
623
636
|
}
|
|
624
|
-
if (e?.status === 200 ||
|
|
637
|
+
if (e?.status === 200 || n === 3) break;
|
|
625
638
|
await new Promise((o) => setTimeout(() => o(!0), 500));
|
|
626
639
|
}
|
|
627
640
|
if (!e || e.status !== 200) return s("request is error.");
|
|
628
|
-
const
|
|
629
|
-
if (!
|
|
641
|
+
const i = e.body?.getReader();
|
|
642
|
+
if (!i) return s("reader is error.");
|
|
630
643
|
for (; ; ) {
|
|
631
|
-
const { done: o, value: a } = await
|
|
644
|
+
const { done: o, value: a } = await i.read();
|
|
632
645
|
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
633
646
|
}
|
|
634
647
|
} catch (e) {
|
|
@@ -642,17 +655,17 @@ class tt {
|
|
|
642
655
|
url: "",
|
|
643
656
|
getSegmentsTimer: 0,
|
|
644
657
|
parse: async (t) => {
|
|
645
|
-
const
|
|
646
|
-
`).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);
|
|
647
660
|
let o = 4, a = 0, r = !1;
|
|
648
661
|
const d = [];
|
|
649
|
-
for (const c of
|
|
662
|
+
for (const c of n)
|
|
650
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({
|
|
651
|
-
url: c.startsWith("http") ? c :
|
|
664
|
+
url: c.startsWith("http") ? c : i + c,
|
|
652
665
|
duration: o,
|
|
653
666
|
isLive: r
|
|
654
667
|
});
|
|
655
|
-
return { baseUrl:
|
|
668
|
+
return { baseUrl: i, targetDuration: a, isLive: r, segments: d };
|
|
656
669
|
},
|
|
657
670
|
getSegments: async () => {
|
|
658
671
|
try {
|
|
@@ -661,25 +674,25 @@ class tt {
|
|
|
661
674
|
s += 1;
|
|
662
675
|
try {
|
|
663
676
|
t = await this.getSegmentsFetch.request(this.url);
|
|
664
|
-
} catch (
|
|
665
|
-
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);
|
|
666
679
|
}
|
|
667
680
|
if (t?.status === 200 || s === 3) break;
|
|
668
|
-
await new Promise((
|
|
681
|
+
await new Promise((n) => setTimeout(() => n(!0), 500));
|
|
669
682
|
}
|
|
670
683
|
if (!t || t.status !== 200) throw new Error("request is error.");
|
|
671
684
|
const e = t.body?.getReader();
|
|
672
685
|
if (!e) throw new Error("reader is error.");
|
|
673
686
|
for (; ; ) {
|
|
674
|
-
const { done:
|
|
675
|
-
if (
|
|
676
|
-
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;
|
|
677
690
|
this.hls.isLive = r, r === !1 && (this.option.frameTrack = !1);
|
|
678
691
|
let d = Array.from(a, (h) => h.url);
|
|
679
692
|
const c = d.findIndex((h) => h === this.hls.url);
|
|
680
693
|
c !== -1 && (d = d.slice(c + 1)), this.hls.urls = d;
|
|
681
694
|
}
|
|
682
|
-
if (
|
|
695
|
+
if (n || this.url === "") break;
|
|
683
696
|
}
|
|
684
697
|
} catch (t) {
|
|
685
698
|
t.name !== "AbortError" && this.on.error && this.on.error(t);
|
|
@@ -691,14 +704,14 @@ class tt {
|
|
|
691
704
|
const e = this.hls.urls.shift();
|
|
692
705
|
if (e) {
|
|
693
706
|
this.hls.url = e;
|
|
694
|
-
const
|
|
695
|
-
if (!
|
|
707
|
+
const i = (await this.prFetch.request(e)).body?.getReader();
|
|
708
|
+
if (!i) throw new Error("segment reader is error.");
|
|
696
709
|
for (; ; ) {
|
|
697
|
-
const { done: o, value: a } = await
|
|
710
|
+
const { done: o, value: a } = await i.read();
|
|
698
711
|
if (a && this.demuxerWorker?.push(a), o || this.url === "") break;
|
|
699
712
|
}
|
|
700
713
|
} else
|
|
701
|
-
await new Promise((
|
|
714
|
+
await new Promise((n) => setTimeout(() => n(!0), 300));
|
|
702
715
|
}
|
|
703
716
|
} catch (e) {
|
|
704
717
|
e.name !== "AbortError" && s(e);
|
|
@@ -779,10 +792,10 @@ class J {
|
|
|
779
792
|
if (t.getUint8(s) !== 71)
|
|
780
793
|
throw new Error("Invalid TS packet");
|
|
781
794
|
let e = s;
|
|
782
|
-
const
|
|
795
|
+
const n = this.parseHeader(t, e);
|
|
783
796
|
e += 4;
|
|
784
|
-
const { transport_error_indicator:
|
|
785
|
-
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;
|
|
786
799
|
let d = 184;
|
|
787
800
|
if (r === 2 || r === 3) {
|
|
788
801
|
const c = t.getUint8(e);
|
|
@@ -828,14 +841,14 @@ class J {
|
|
|
828
841
|
// Header
|
|
829
842
|
parseHeader = (t, s) => {
|
|
830
843
|
let e = s;
|
|
831
|
-
const
|
|
832
|
-
if (r === 1) return { sync_byte:
|
|
833
|
-
const d = (
|
|
834
|
-
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 };
|
|
835
848
|
};
|
|
836
849
|
// PAT表
|
|
837
850
|
parsePAT = (t, s) => {
|
|
838
|
-
let e = s,
|
|
851
|
+
let e = s, n;
|
|
839
852
|
{
|
|
840
853
|
const a = t.getUint8(e);
|
|
841
854
|
e += 1;
|
|
@@ -850,22 +863,22 @@ class J {
|
|
|
850
863
|
const u = t.getUint8(e);
|
|
851
864
|
e += 1;
|
|
852
865
|
const g = t.getUint8(e);
|
|
853
|
-
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 };
|
|
854
867
|
}
|
|
855
|
-
const
|
|
868
|
+
const i = [];
|
|
856
869
|
{
|
|
857
|
-
const a =
|
|
870
|
+
const a = n.section_length - 5 - 4, r = e + a;
|
|
858
871
|
for (; e < r; ) {
|
|
859
872
|
const d = t.getUint16(e), c = t.getUint16(e + 2) & 8191;
|
|
860
|
-
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 });
|
|
861
874
|
}
|
|
862
875
|
}
|
|
863
876
|
const o = t.getUint32(e);
|
|
864
|
-
this.pat = { header:
|
|
877
|
+
this.pat = { header: n, programs: i, crc32: o }, this.on.debug && this.on.debug({ pat: this.pat });
|
|
865
878
|
};
|
|
866
879
|
// PMT表
|
|
867
880
|
parsePMT = (t, s) => {
|
|
868
|
-
let e = s,
|
|
881
|
+
let e = s, n;
|
|
869
882
|
{
|
|
870
883
|
const a = t.getUint8(e);
|
|
871
884
|
e += 1;
|
|
@@ -883,44 +896,44 @@ class J {
|
|
|
883
896
|
e += 1;
|
|
884
897
|
const f = t.getUint16(e) & 8191;
|
|
885
898
|
e += 2;
|
|
886
|
-
const
|
|
887
|
-
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 };
|
|
888
901
|
}
|
|
889
|
-
const
|
|
902
|
+
const i = [];
|
|
890
903
|
{
|
|
891
|
-
const a =
|
|
904
|
+
const a = n.section_length - 9 - 4, r = e + a;
|
|
892
905
|
for (; e < r; ) {
|
|
893
906
|
const d = t.getUint8(e), c = Q(d), h = t.getUint16(e + 1) & 8191, l = t.getUint16(e + 3) & 4095;
|
|
894
907
|
if (e += 5, h < 32 || h > 8190) {
|
|
895
908
|
console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);
|
|
896
909
|
continue;
|
|
897
910
|
}
|
|
898
|
-
|
|
911
|
+
i.push({ kind: c, stream_type: d, elementary_pid: h, es_info_length: l });
|
|
899
912
|
}
|
|
900
913
|
}
|
|
901
914
|
const o = t.getUint32(e);
|
|
902
|
-
this.pmt = { header:
|
|
915
|
+
this.pmt = { header: n, streams: i, crc32: o }, this.on.debug && this.on.debug({ pmt: this.pmt });
|
|
903
916
|
};
|
|
904
917
|
// AdaptationField
|
|
905
918
|
parseAdaptationField = (t, s) => {
|
|
906
|
-
let e = s,
|
|
907
|
-
const r = t.getUint8(e), d = !!(r & 128), c = !!(r & 64), h = !!(r & 32), l = !!(r & 16), u = !!(r & 8), g = !!(r & 4), f = !!(r & 2),
|
|
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);
|
|
908
921
|
e += 1;
|
|
909
922
|
const b = (k, w) => {
|
|
910
923
|
let U = BigInt(0);
|
|
911
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);
|
|
912
|
-
const
|
|
913
|
-
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;
|
|
914
927
|
};
|
|
915
|
-
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) {
|
|
916
929
|
const k = t.getUint8(e);
|
|
917
930
|
e += 1, a = new Uint8Array(t.buffer, e, k), e += k;
|
|
918
931
|
}
|
|
919
|
-
return { discontinuity_indicator: d, random_access_indicator: c, elementary_stream_priority_indicator: h, pcr_flag: l, opcr_flag: u, splicing_point_flag: g, transport_private_data_flag: f, adaptation_field_extension_flag:
|
|
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 };
|
|
920
933
|
};
|
|
921
934
|
parseAudio = async (t) => {
|
|
922
935
|
const s = new DataView(t.buffer);
|
|
923
|
-
let e = 0,
|
|
936
|
+
let e = 0, n, i;
|
|
924
937
|
{
|
|
925
938
|
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
926
939
|
if (e += 3, !o)
|
|
@@ -931,19 +944,19 @@ class J {
|
|
|
931
944
|
e += 2;
|
|
932
945
|
let d, c, h, l, u;
|
|
933
946
|
{
|
|
934
|
-
const
|
|
935
|
-
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;
|
|
936
949
|
}
|
|
937
950
|
let g, f;
|
|
938
951
|
{
|
|
939
|
-
const
|
|
952
|
+
const m = s.getUint8(e);
|
|
940
953
|
e += 1;
|
|
941
|
-
const b =
|
|
954
|
+
const b = m >> 6, k = s.getUint8(e);
|
|
942
955
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
943
956
|
}
|
|
944
|
-
|
|
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 };
|
|
945
958
|
}
|
|
946
|
-
|
|
959
|
+
i = t.slice(e);
|
|
947
960
|
{
|
|
948
961
|
if (!this.audioConfig && s.getUint8(e) === 255) {
|
|
949
962
|
const h = s.getUint8(e + 2), l = s.getUint8(e + 3);
|
|
@@ -952,13 +965,13 @@ class J {
|
|
|
952
965
|
const f = `mp4a.40.${u}`, b = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350][g];
|
|
953
966
|
this.audioConfig = { kind: "audio", codec: f, sampleRate: b, numberOfChannels: u }, this.on.config && this.on.config(this.audioConfig);
|
|
954
967
|
}
|
|
955
|
-
const { dts: o = 0, pts: a = 0 } =
|
|
968
|
+
const { dts: o = 0, pts: a = 0 } = n, r = a - o, d = i.slice(7);
|
|
956
969
|
return { kind: "audio", type: "key", dts: o, pts: a, cts: r, data: d };
|
|
957
970
|
}
|
|
958
971
|
};
|
|
959
972
|
parseVideo = async (t) => {
|
|
960
973
|
const s = new DataView(t.buffer);
|
|
961
|
-
let e = 0,
|
|
974
|
+
let e = 0, n, i;
|
|
962
975
|
{
|
|
963
976
|
const o = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
964
977
|
if (e += 3, !o)
|
|
@@ -969,26 +982,26 @@ class J {
|
|
|
969
982
|
e += 2;
|
|
970
983
|
let d, c, h, l, u;
|
|
971
984
|
{
|
|
972
|
-
const
|
|
973
|
-
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;
|
|
974
987
|
}
|
|
975
988
|
let g, f;
|
|
976
989
|
{
|
|
977
|
-
const
|
|
990
|
+
const m = s.getUint8(e);
|
|
978
991
|
e += 1;
|
|
979
|
-
const b =
|
|
992
|
+
const b = m >> 6, k = s.getUint8(e);
|
|
980
993
|
e += 1, (b & 2) === 2 && (g = this.parsePtsDts(s, e)), (b & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += k;
|
|
981
994
|
}
|
|
982
|
-
|
|
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 };
|
|
983
996
|
}
|
|
984
|
-
|
|
997
|
+
i = t.slice(e);
|
|
985
998
|
{
|
|
986
|
-
const o = this.getNalus(
|
|
999
|
+
const o = this.getNalus(i);
|
|
987
1000
|
if (!this.videoConfig) {
|
|
988
1001
|
let u, g;
|
|
989
|
-
if (u = o.find((
|
|
990
|
-
const f =
|
|
991
|
-
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);
|
|
992
1005
|
}
|
|
993
1006
|
}
|
|
994
1007
|
const a = [];
|
|
@@ -1009,7 +1022,7 @@ class J {
|
|
|
1009
1022
|
break;
|
|
1010
1023
|
}
|
|
1011
1024
|
}
|
|
1012
|
-
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;
|
|
1013
1026
|
return { kind: "video", type: r, dts: c, pts: h, cts: l, data: d, nalus: a };
|
|
1014
1027
|
}
|
|
1015
1028
|
};
|
|
@@ -1017,7 +1030,7 @@ class J {
|
|
|
1017
1030
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
1018
1031
|
*/
|
|
1019
1032
|
parsePtsDts(t, s) {
|
|
1020
|
-
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;
|
|
1021
1034
|
return Number(r) / 90;
|
|
1022
1035
|
}
|
|
1023
1036
|
getNalus = (t) => {
|
|
@@ -1029,8 +1042,8 @@ class J {
|
|
|
1029
1042
|
continue;
|
|
1030
1043
|
}
|
|
1031
1044
|
e += 3;
|
|
1032
|
-
let
|
|
1033
|
-
const
|
|
1045
|
+
let n = e;
|
|
1046
|
+
const i = t[e] & 31;
|
|
1034
1047
|
for (e += 1; !(e + 1 > t.byteLength); ) {
|
|
1035
1048
|
if (t[e] !== 0 || t[e + 1] !== 0 || t[e + 2] !== 1) {
|
|
1036
1049
|
e += 1;
|
|
@@ -1038,10 +1051,10 @@ class J {
|
|
|
1038
1051
|
}
|
|
1039
1052
|
break;
|
|
1040
1053
|
}
|
|
1041
|
-
let o = e -
|
|
1054
|
+
let o = e - n;
|
|
1042
1055
|
if (t[e - 1] === 0 && (o -= 1), o !== 0) {
|
|
1043
|
-
const a = t.slice(
|
|
1044
|
-
s.push({ type:
|
|
1056
|
+
const a = t.slice(n, n + o), r = H(a);
|
|
1057
|
+
s.push({ type: i, nalu: r });
|
|
1045
1058
|
}
|
|
1046
1059
|
}
|
|
1047
1060
|
return s;
|
|
@@ -1060,10 +1073,10 @@ class Z {
|
|
|
1060
1073
|
parse = async (t) => {
|
|
1061
1074
|
let s = 0;
|
|
1062
1075
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
1063
|
-
const
|
|
1064
|
-
if (
|
|
1065
|
-
const r = this.parseTagBody(
|
|
1066
|
-
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) {
|
|
1067
1080
|
case "script":
|
|
1068
1081
|
this.on.info && this.on.info(r);
|
|
1069
1082
|
break;
|
|
@@ -1100,30 +1113,30 @@ class Z {
|
|
|
1100
1113
|
};
|
|
1101
1114
|
// Header
|
|
1102
1115
|
parseHeader = (t, s) => {
|
|
1103
|
-
let e,
|
|
1104
|
-
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);
|
|
1105
1118
|
{
|
|
1106
1119
|
const r = t.getUint8(0).toString(2).padStart(5, "0").split(""), [, , d, , c] = r;
|
|
1107
|
-
|
|
1120
|
+
i = { audio: c === "1", video: d === "1" };
|
|
1108
1121
|
}
|
|
1109
|
-
o = t.getUint32(5), this.header = { signature: e, version:
|
|
1122
|
+
o = t.getUint32(5), this.header = { signature: e, version: n, flags: i, dataOffset: o };
|
|
1110
1123
|
};
|
|
1111
1124
|
// 是否是完整tag
|
|
1112
1125
|
isSurplusTag = (t, s) => {
|
|
1113
1126
|
let e = !0;
|
|
1114
|
-
const
|
|
1115
|
-
if (s + 4 >
|
|
1127
|
+
const n = t.byteLength;
|
|
1128
|
+
if (s + 4 > n)
|
|
1116
1129
|
e = !1;
|
|
1117
|
-
else if (s + 4 + 11 >
|
|
1130
|
+
else if (s + 4 + 11 > n)
|
|
1118
1131
|
e = !1;
|
|
1119
1132
|
else {
|
|
1120
|
-
const
|
|
1121
|
-
s + 4 + 11 +
|
|
1133
|
+
const i = T(t, s + 4 + 1);
|
|
1134
|
+
s + 4 + 11 + i > n && (e = !1);
|
|
1122
1135
|
}
|
|
1123
1136
|
return e;
|
|
1124
1137
|
};
|
|
1125
1138
|
parseTagHeader = (t, s) => {
|
|
1126
|
-
let e,
|
|
1139
|
+
let e, n, i, o, a;
|
|
1127
1140
|
{
|
|
1128
1141
|
const r = t.getUint8(s);
|
|
1129
1142
|
let d;
|
|
@@ -1140,22 +1153,22 @@ class Z {
|
|
|
1140
1153
|
}
|
|
1141
1154
|
e = d;
|
|
1142
1155
|
}
|
|
1143
|
-
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 };
|
|
1144
1157
|
};
|
|
1145
|
-
parseTagBody = (t, s, e,
|
|
1146
|
-
let
|
|
1158
|
+
parseTagBody = (t, s, e, n) => {
|
|
1159
|
+
let i;
|
|
1147
1160
|
switch (t) {
|
|
1148
1161
|
case "script":
|
|
1149
|
-
|
|
1162
|
+
i = this.parseMetaData(s, e);
|
|
1150
1163
|
break;
|
|
1151
1164
|
case "audio":
|
|
1152
|
-
|
|
1165
|
+
i = this.parseAudio(s, e, n);
|
|
1153
1166
|
break;
|
|
1154
1167
|
case "video":
|
|
1155
|
-
|
|
1168
|
+
i = this.parseVideo(s, e, n);
|
|
1156
1169
|
break;
|
|
1157
1170
|
}
|
|
1158
|
-
return
|
|
1171
|
+
return i;
|
|
1159
1172
|
};
|
|
1160
1173
|
parseMetaData = (t, s) => {
|
|
1161
1174
|
let e = s;
|
|
@@ -1163,48 +1176,48 @@ class Z {
|
|
|
1163
1176
|
if (t.getUint8(e) !== 2) throw new Error("Invalid AMF type for onMetaData (expected 0x02)");
|
|
1164
1177
|
e = e + 1;
|
|
1165
1178
|
}
|
|
1166
|
-
const
|
|
1179
|
+
const n = t.getUint16(e, !1);
|
|
1167
1180
|
e = e + 2;
|
|
1168
1181
|
{
|
|
1169
|
-
const a = new Int8Array(t.buffer.slice(e, e +
|
|
1182
|
+
const a = new Int8Array(t.buffer.slice(e, e + n));
|
|
1170
1183
|
if ((this.textDecoder?.decode(a) || "") !== "onMetaData") throw new Error("Expected 'onMetaData' string");
|
|
1171
|
-
e = e +
|
|
1184
|
+
e = e + n;
|
|
1172
1185
|
}
|
|
1173
|
-
const
|
|
1174
|
-
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;
|
|
1175
1188
|
};
|
|
1176
1189
|
parseAudio = (t, s, e) => {
|
|
1177
|
-
let
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
const c = t.getUint8(
|
|
1181
|
-
|
|
1182
|
-
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));
|
|
1183
1196
|
if (o === 10 && c === 0) {
|
|
1184
|
-
const u = t.getUint8(
|
|
1185
|
-
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 };
|
|
1186
1199
|
}
|
|
1187
1200
|
return { soundFormat: o, soundRate: a, soundSize: r, soundType: d, accPacketType: c, data: l };
|
|
1188
1201
|
};
|
|
1189
1202
|
parseVideo = (t, s, e) => {
|
|
1190
|
-
let
|
|
1191
|
-
const
|
|
1192
|
-
|
|
1193
|
-
const r = t.getUint8(
|
|
1194
|
-
|
|
1195
|
-
const d = T(t,
|
|
1196
|
-
|
|
1197
|
-
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));
|
|
1198
1211
|
switch (a) {
|
|
1199
1212
|
case 7:
|
|
1200
1213
|
if (r === 0) {
|
|
1201
|
-
const l =
|
|
1214
|
+
const l = D(h);
|
|
1202
1215
|
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, ...l };
|
|
1203
1216
|
} else if (r === 1) {
|
|
1204
|
-
const l = [], u =
|
|
1205
|
-
for (; !(
|
|
1206
|
-
const g = t.getUint32(
|
|
1207
|
-
|
|
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);
|
|
1208
1221
|
}
|
|
1209
1222
|
return { frameType: o, codecID: a, avcPacketType: r, cts: d, data: h, nalus: l };
|
|
1210
1223
|
}
|
|
@@ -1216,73 +1229,73 @@ class Z {
|
|
|
1216
1229
|
};
|
|
1217
1230
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1218
1231
|
getAMFName = (t, s, e) => {
|
|
1219
|
-
const
|
|
1220
|
-
return this.textDecoder?.decode(
|
|
1232
|
+
const n = new Uint8Array(t.buffer.slice(s, s + e));
|
|
1233
|
+
return this.textDecoder?.decode(n) || "";
|
|
1221
1234
|
};
|
|
1222
1235
|
getAMFValue = (t, s, e) => {
|
|
1223
|
-
let
|
|
1236
|
+
let n = s, i, o = 0;
|
|
1224
1237
|
switch (e) {
|
|
1225
1238
|
case 0:
|
|
1226
|
-
|
|
1239
|
+
i = t.getFloat64(n, !1), o = 8;
|
|
1227
1240
|
break;
|
|
1228
1241
|
case 1:
|
|
1229
|
-
|
|
1242
|
+
i = !!t.getUint8(n), o = 1;
|
|
1230
1243
|
break;
|
|
1231
1244
|
case 2:
|
|
1232
1245
|
{
|
|
1233
|
-
|
|
1234
|
-
const r = t.getUint16(
|
|
1235
|
-
|
|
1236
|
-
const d = new Int8Array(t.buffer,
|
|
1237
|
-
|
|
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;
|
|
1238
1251
|
}
|
|
1239
1252
|
break;
|
|
1240
1253
|
case 3:
|
|
1241
|
-
for (
|
|
1242
|
-
const r = t.getUint16(
|
|
1254
|
+
for (i = {}; n < t.byteLength; ) {
|
|
1255
|
+
const r = t.getUint16(n, !1);
|
|
1243
1256
|
if (r === 0) break;
|
|
1244
|
-
|
|
1245
|
-
const d = this.getAMFName(t,
|
|
1246
|
-
|
|
1247
|
-
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);
|
|
1248
1261
|
if (c === 6) break;
|
|
1249
|
-
|
|
1250
|
-
const h = this.getAMFValue(t,
|
|
1251
|
-
|
|
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;
|
|
1252
1265
|
}
|
|
1253
1266
|
break;
|
|
1254
1267
|
case 8:
|
|
1255
1268
|
{
|
|
1256
|
-
|
|
1257
|
-
const r = t.getUint32(
|
|
1258
|
-
|
|
1269
|
+
i = {};
|
|
1270
|
+
const r = t.getUint32(n, !1);
|
|
1271
|
+
n = n + 4;
|
|
1259
1272
|
for (let d = 0; d < r; d++) {
|
|
1260
|
-
const c = t.getUint16(
|
|
1261
|
-
|
|
1262
|
-
const h = this.getAMFName(t,
|
|
1263
|
-
|
|
1264
|
-
const l = this.getAmfType(t,
|
|
1265
|
-
|
|
1266
|
-
const u = this.getAMFValue(t,
|
|
1267
|
-
|
|
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;
|
|
1268
1281
|
}
|
|
1269
1282
|
}
|
|
1270
1283
|
break;
|
|
1271
1284
|
case 10:
|
|
1272
1285
|
{
|
|
1273
|
-
|
|
1274
|
-
const r = t.getUint32(
|
|
1275
|
-
|
|
1286
|
+
i = [];
|
|
1287
|
+
const r = t.getUint32(n, !1);
|
|
1288
|
+
n = n + 4;
|
|
1276
1289
|
for (let d = 0; d < r; d++) {
|
|
1277
|
-
const c = this.getAmfType(t,
|
|
1278
|
-
|
|
1279
|
-
const h = this.getAMFValue(t,
|
|
1280
|
-
|
|
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;
|
|
1281
1294
|
}
|
|
1282
1295
|
}
|
|
1283
1296
|
break;
|
|
1284
1297
|
}
|
|
1285
|
-
return { amfType: e, length: o, value:
|
|
1298
|
+
return { amfType: e, length: o, value: i };
|
|
1286
1299
|
};
|
|
1287
1300
|
}
|
|
1288
1301
|
class et {
|
|
@@ -1396,8 +1409,13 @@ class st {
|
|
|
1396
1409
|
this.video.destroy(), this.videoDecoderConfig = { ...t }, this.videoDecoder = new VideoDecoder({
|
|
1397
1410
|
output: async (s) => {
|
|
1398
1411
|
this.frameStartTime || (this.frameStartTime = s.timestamp);
|
|
1399
|
-
|
|
1400
|
-
|
|
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
|
+
}
|
|
1401
1419
|
},
|
|
1402
1420
|
error: (s) => {
|
|
1403
1421
|
this.on.video.error && this.on.video.error(s);
|
|
@@ -1429,16 +1447,16 @@ class st {
|
|
|
1429
1447
|
for (this.isProcessing = !0; this.currentChunk = this.pendingChunks.shift(), !!this.currentChunk; ) {
|
|
1430
1448
|
const t = this.pendingChunks.length;
|
|
1431
1449
|
if (this.frameTrack) {
|
|
1432
|
-
const [
|
|
1433
|
-
if (t <=
|
|
1434
|
-
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);
|
|
1435
1453
|
this.decodingSpeedRatio = Number(o.toFixed(1));
|
|
1436
1454
|
} else
|
|
1437
1455
|
this.decodingSpeedRatio = 1;
|
|
1438
1456
|
}
|
|
1439
1457
|
if (this.on.analysis) {
|
|
1440
|
-
const { decodingSpeed:
|
|
1441
|
-
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 });
|
|
1442
1460
|
}
|
|
1443
1461
|
const { kind: s, init: e } = this.currentChunk;
|
|
1444
1462
|
switch (s) {
|
|
@@ -1482,27 +1500,38 @@ class st {
|
|
|
1482
1500
|
}
|
|
1483
1501
|
};
|
|
1484
1502
|
}
|
|
1485
|
-
class
|
|
1503
|
+
class nt {
|
|
1486
1504
|
renderMap = /* @__PURE__ */ new Map();
|
|
1487
1505
|
constructor() {
|
|
1488
1506
|
}
|
|
1489
1507
|
push = async (t) => {
|
|
1490
1508
|
const { timestamp: s } = t, { bitmap: e } = t;
|
|
1491
|
-
if (e.height === 0 || e.width === 0)
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
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);
|
|
1505
1532
|
}
|
|
1533
|
+
}
|
|
1534
|
+
} catch {
|
|
1506
1535
|
}
|
|
1507
1536
|
e.close();
|
|
1508
1537
|
};
|
|
@@ -1510,8 +1539,12 @@ class it {
|
|
|
1510
1539
|
* 增加剪切
|
|
1511
1540
|
*/
|
|
1512
1541
|
addCut = (t) => {
|
|
1513
|
-
const { key: s, writable: e, option: i } = { key: "default", ...t }
|
|
1514
|
-
|
|
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 });
|
|
1515
1548
|
};
|
|
1516
1549
|
/**
|
|
1517
1550
|
* 删除剪切
|
|
@@ -1523,15 +1556,15 @@ class it {
|
|
|
1523
1556
|
* 设置剪切
|
|
1524
1557
|
*/
|
|
1525
1558
|
setCut = (t) => {
|
|
1526
|
-
const { key: s, cutOption: e } = { key: "default", ...t },
|
|
1527
|
-
|
|
1559
|
+
const { key: s, cutOption: e } = { key: "default", ...t }, n = this.renderMap.get(s);
|
|
1560
|
+
n && this.renderMap.set(s, { ...n, option: e });
|
|
1528
1561
|
};
|
|
1529
1562
|
/**
|
|
1530
1563
|
* 设置暂停
|
|
1531
1564
|
*/
|
|
1532
1565
|
setPause = (t) => {
|
|
1533
|
-
const { key: s, pause: e } = { key: "default", ...t },
|
|
1534
|
-
|
|
1566
|
+
const { key: s, pause: e } = { key: "default", ...t }, n = this.renderMap.get(s);
|
|
1567
|
+
n && this.renderMap.set(s, { ...n, pause: e });
|
|
1535
1568
|
};
|
|
1536
1569
|
destroy = () => {
|
|
1537
1570
|
this.renderMap = /* @__PURE__ */ new Map();
|
|
@@ -1539,10 +1572,10 @@ class it {
|
|
|
1539
1572
|
}
|
|
1540
1573
|
export {
|
|
1541
1574
|
st as Decoder,
|
|
1542
|
-
|
|
1575
|
+
V as DecoderWorker,
|
|
1543
1576
|
et as Demuxer,
|
|
1544
1577
|
I as DemuxerWorker,
|
|
1545
1578
|
tt as PrPlayer,
|
|
1546
|
-
|
|
1547
|
-
|
|
1579
|
+
nt as Render,
|
|
1580
|
+
B as RenderWorker
|
|
1548
1581
|
};
|