pr-player 0.1.4 → 0.1.6
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 +5 -1
- package/dist/demuxer/ts264Parser.d.ts +1 -0
- package/dist/index.js +338 -291
- package/dist/index.umd.cjs +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const D = '(function(){"use strict";class P{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const I=(u,t)=>{const s=new Uint8Array(u),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=u=>{let t=0;const s=new DataView(u.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 i=s.getUint8(t)&255;t=t+1;const h=`avc1.${Array.from([n,a,i],b=>b.toString(16).padStart(2,"0")).join("")}`,c=(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 l=new Uint8Array(s.buffer.slice(t,t+p));t=t+p;const d=s.getUint8(t)&31;t=t+1;const f=s.getUint16(t,!1);t=t+2;const y=new Uint8Array(s.buffer.slice(t,t+f));return t=t+f,{version:e,codec:h,profile:n,compatibility:a,level:i,lengthSizeMinusOne:c,numOfSequenceParameterSets:g,sequenceParameterSetLength:p,sps:l,numOfPictureParameterSets:d,pictureParameterSetLength:f,pps:y}},M=u=>{const t=new Uint8Array(4+u.length);return new DataView(t.buffer).setUint32(0,u.length,!1),t.set(u,4),t},C=u=>{let t=0;for(const n of u)t+=n.length;const s=new Uint8Array(t);let e=0;for(const n of u){const a=n;s.set(a,e),e+=a.length}return s},x=u=>{let t="unknown";switch(u){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 D{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:i,payload_unit_start_indicator:o,adaptation_field_control:r}=n;if(a===1||i===void 0)return;let h=184;if(r===2||r===3){const c=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=c,h-=c}if(r===3&&(h-=1),r===1||r===3){const c=new Uint8Array(t.buffer.slice(e,e+h));if(i===0)return this.parsePAT(t,e);{const{programs:l=[]}=this.pat||{};if(l.find(f=>f.pmt_pid===i))return this.parsePMT(t,e)}const{streams:g=[]}=this.pmt||{},p=g.find(l=>l.elementary_pid===i);if(p){if(o===1){const l=this.payloadMap.get(i);if(l){switch(p.kind){case"audio":break;case"video":{const d=await this.parseVideo(l);this.on.chunk&&this.on.chunk(d),await new Promise(f=>setTimeout(()=>f(!0),8))}break}this.payloadMap.delete(i)}}{this.payloadMap.has(i)||this.payloadMap.set(i,new Uint8Array);const l=this.payloadMap.get(i),d=new Uint8Array(l.byteLength+c.byteLength);d.set(l,0),d.set(c,l.byteLength),this.payloadMap.set(i,d)}}}};parseHeader=(t,s)=>{let e=s;const n=t.getUint8(e),a=t.getUint8(e+1),i=t.getUint8(e+2),o=t.getUint8(e+3),r=(a&128)>>7;if(r===1)return{sync_byte:n,transport_error_indicator:r};const h=(a&64)>>6,c=(a&32)>>5,g=(a&31)<<8|i,p=(o&192)>>6,l=o>>4&3,d=o&15;return{sync_byte:n,transport_error_indicator:r,payload_unit_start_indicator:h,transport_priority:c,pid:g,transport_scrambling_control:p,adaptation_field_control:l,continuity_counter:d}};parsePAT=(t,s)=>{let e=s,n;{const o=t.getUint8(e);e+=1;const r=t.getUint8(e);if(e+=1,r!==0)throw new Error("Invalid PAT table_id");const h=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const l=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1,n={pointer_field:o,table_id:r,section_length:h,transport_stream_id:c,version_number:g,current_next_indicator:p,section_number:l,last_section_number:d}}const a=[];{const o=n.section_length-5-4,r=e+o;for(;e<r;){const h=t.getUint16(e),c=t.getUint16(e+2)&8191;e+=4,h!==0&&c>=32&&c<=8190&&a.push({program_number:h,pmt_pid:c})}}const i=t.getUint32(e);this.pat={header:n,programs:a,crc32:i},this.on.debug&&this.on.debug({pat:this.pat})};parsePMT=(t,s)=>{let e=s,n;{const o=t.getUint8(e);e+=1;const r=t.getUint8(e);if(e+=1,r!==2)throw new Error("Invalid PMT table_id");const h=t.getUint16(e)&4095;e+=2;const c=t.getUint16(e);e+=2;const g=(t.getUint8(e)&62)>>1,p=t.getUint8(e)&1;e+=1;const l=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1;const f=t.getUint16(e)&8191;e+=2;const y=t.getUint16(e)&4095;e+=2,n={pointer_field:o,table_id:r,section_length:h,transport_stream_id:c,version_number:g,current_next_indicator:p,section_number:l,last_section_number:d,pcr_pid:f,program_info_length:y}}const a=[];{const o=n.section_length-9-4,r=e+o;for(;e<r;){const h=t.getUint8(e),c=x(h),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:c,stream_type:h,elementary_pid:g,es_info_length:p})}}const i=t.getUint32(e);this.pmt={header:n,streams:a,crc32:i},this.on.debug&&this.on.debug({pmt:this.pmt})};parseAdaptationField=(t,s)=>{let e=s,n,a,i,o;const r=t.getUint8(e),h=!!(r&128),c=!!(r&64),g=!!(r&32),p=!!(r&16),l=!!(r&8),d=!!(r&4),f=!!(r&2),y=!!(r&1);e+=1;const b=(U,m)=>{let _=BigInt(0);_|=BigInt(U.getUint16(m))<<25n,_|=BigInt(U.getUint16(m+1))<<17n,_|=BigInt(U.getUint16(m+2))<<9n,_|=BigInt(U.getUint16(m+3))<<1n,_|=BigInt(U.getUint16(m+4)>>7);const B=(U.getUint16(m+4)&1)<<8|U.getUint16(m+5);return _=_*300n+BigInt(B),_};if(p&&(n=b(t,e),e+=6),l&&(a=b(t,e),e+=6),d&&(i=t.getInt8(e),e+=1),f){const U=t.getUint8(e);e+=1,o=new Uint8Array(t.buffer,e,U),e+=U}return{discontinuity_indicator:h,random_access_indicator:c,elementary_stream_priority_indicator:g,pcr_flag:p,opcr_flag:l,splicing_point_flag:d,transport_private_data_flag:f,adaptation_field_extension_flag:y,pcr:n,opcr:a,splice_countdown:i,transport_private_data:o}};parseVideo=async t=>{const s=new DataView(t.buffer);let e=0,n,a;{const i=s.getUint8(e)===0&&s.getUint8(e+1)===0&&s.getUint8(e+2)===1;if(e+=3,!i)throw new Error("invalid ts video payload.");const o=s.getUint8(e);e+=1;const r=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let h,c;const g=o!==188&&o!==190&&o!==191&&o!==240&&o!==241&&o!==255&&o!==242;if(g){e+=1;const p=s.getUint8(e);e+=1;const l=p>>6,d=s.getUint8(e);e+=1,(l&2)===2&&(h=this.parsePtsDts(s,e),e+=5),(l&1)===1?(c=this.parsePtsDts(s,e),e+=5):c=h,e+=d-(e-9)}n={stream_id:o,pes_packet_length:r,pts:h,dts:c,optional_header_exist:g}}a=t.slice(e);{const i=this.getNalus(a);if(!this.videoConfig){let l,d;if(l=i.find(y=>y.type===7)?.nalu.slice(4),d=i.find(y=>y.type===8)?.nalu.slice(4),l&&d){const f=I(l,d),{codec:y}=T(f);this.videoConfig={kind:"video",codec:y,description:f,sps:l,pps:d},this.on.config&&this.on.config(this.videoConfig)}}const o=[];let r="delta";for(const l of i){const{type:d,nalu:f}=l;switch(d){case 9:o.push(f);break;case 1:r="delta",o.push(f);break;case 5:r="key",o.push(f);break}}const h=C(o),{dts:c=0,pts:g=0}=n,p=g-c;return{kind:"video",type:r,dts:c,pts:g,cts:p,data:h,nalus:o}}};parsePtsDts(t,s){const e=t.getUint8(s),n=t.getUint8(s+1),a=t.getUint8(s+2),i=t.getUint8(s+3),o=t.getUint8(s+4),r=(BigInt(e)&0b00001110n)<<29n|(BigInt(n)&0b11111111n)<<22n|(BigInt(a)&0b11111110n)<<14n|(BigInt(i)&0b11111111n)<<7n|(BigInt(o)&0b11111110n)>>1n;return Number(r)/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 i=e-n;if(t[e-1]===0&&(i-=1),i!==0){const o=t.slice(n,n+i),r=M(o);s.push({type:a,nalu:r})}}return s}}const k=(u,t)=>u.getUint8(t)<<16|u.getUint8(t+1)<<8|u.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:i,timestamp:o}=n;if(a){const r=this.parseTagBody(a,t,s+4+11,i);switch(a){case"script":this.on.info&&this.on.info(r);break;case"audio":{const{accPacketType:h}=r;if(h===0){const{codec:c,sampleRate:g,channelConfiguration:p}=r;this.audioConfig={kind:"audio",codec:c,sampleRate:g,numberOfChannels:p},this.on.config&&this.on.config(this.audioConfig)}else{const{cts:c,data:g}=r,p="key",l=c===void 0?void 0:c+o;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:o,pts:l,cts:c,data:g})}}break;case"video":{const{avcPacketType:h}=r;if(h===0){const{codec:c,sps:g,pps:p,data:l}=r;this.videoConfig={kind:"video",codec:c,description:l,sps:g,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:c,cts:g,data:p,nalus:l}=r,d=c===1?"key":"delta",f=g===void 0?void 0:g+o;this.on.chunk&&this.on.chunk({kind:"video",type:d,dts:o,pts:f,cts:g,data:p,nalus:l})}}break}s=s+4+11+i}await new Promise(r=>setTimeout(()=>r(!0),8))}return s};parseHeader=(t,s)=>{let e,n,a,i;e=t.getUint8(s)<<16|t.getUint8(s+1)<<8|t.getUint8(s+2),n=t.getUint8(3);{const r=t.getUint8(0).toString(2).padStart(5,"0").split(""),[,,h,,c]=r;a={audio:c==="1",video:h==="1"}}i=t.getUint32(5),this.header={signature:e,version:n,flags:a,dataOffset:i}};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,i,o;{const r=t.getUint8(s);let h;switch(r){case 18:h="script";break;case 8:h="audio";break;case 9:h="video";break}e=h}return n=k(t,s+1),a=k(t,s+4),i=t.getUint8(s+7),o=k(t,s+8),{tagType:e,dataSize:n,timestamp:a,timestampExtended:i,streamID:o}};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 o=new Int8Array(t.buffer.slice(e,e+n));if((this.textDecoder?.decode(o)||"")!=="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),i=a>>4&15,o=a>>2&3,r=a>>1&1,h=a&1;n=n+1;const c=t.getUint8(n);n=n+1;const g=e-2,p=new Uint8Array(t.buffer.slice(n,n+g));if(i===10&&c===0){const l=t.getUint8(n),d=t.getUint8(n+1),f=(l&248)>>3,y=(l&7)<<1|d>>7,b=(d&120)>>3,U=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],m=`mp4a.40.${f}`,_=U[y];return{soundFormat:i,soundRate:o,soundSize:r,soundType:h,accPacketType:c,data:p,audioObjectType:f,samplingFrequencyIndex:y,channelConfiguration:b,codec:m,sampleRate:_}}return{soundFormat:i,soundRate:o,soundSize:r,soundType:h,accPacketType:c,data:p}};parseVideo=(t,s,e)=>{let n=s;const a=t.getUint8(n),i=a>>4&15,o=a&15;n=n+1;const r=t.getUint8(n);n=n+1;const h=k(t,n);n=n+3;const c=e-5,g=new Uint8Array(t.buffer.slice(n,n+c));switch(o){case 7:if(r===0){const p=T(g);return{frameType:i,codecID:o,avcPacketType:r,cts:h,data:g,...p}}else if(r===1){const p=[],l=n+e-5;for(;!(n+4>l);){const d=t.getUint32(n,!1),f=new Uint8Array(t.buffer.slice(n,n+4+d));n+=4+d,p.push(f)}return{frameType:i,codecID:o,avcPacketType:r,cts:h,data:g,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:i,codecID:o,avcPacketType:r,cts:h,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,i=0;switch(e){case 0:a=t.getFloat64(n,!1),i=8;break;case 1:a=!!t.getUint8(n),i=1;break;case 2:{a="";const r=t.getUint16(n,!1);n=n+2;const h=new Int8Array(t.buffer,n,r).filter(g=>g!==0);a=(this.textDecoder?.decode(h)||"").trim(),i=2+r}break;case 3:for(a={};n<t.byteLength;){const r=t.getUint16(n,!1);if(r===0)break;n=n+2;const h=this.getAMFName(t,n,r);n=n+r;const c=this.getAmfType(t,n);if(c===6)break;n=n+1;const g=this.getAMFValue(t,n,c);n=n+g.length,a[h]=g.value,i=2+r+1+g.length}break;case 8:{a={};const r=t.getUint32(n,!1);n=n+4;for(let h=0;h<r;h++){const c=t.getUint16(n,!1);n=n+2;const g=this.getAMFName(t,n,c);n=n+c;const p=this.getAmfType(t,n);n=n+1;const l=this.getAMFValue(t,n,p);n=n+l.length,a[g]=l.value,i=2+c+1+l.length}}break;case 10:{a=[];const r=t.getUint32(n,!1);n=n+4;for(let h=0;h<r;h++){const c=this.getAmfType(t,n);n=n+1;const g=this.getAMFValue(t,n,c);n=n+g.length,a.push(g.value),i=1+g.length}}break}return{amfType:e,length:i,value:a}}}class S{pattern;cacher=new P;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new L;break;case"hls":this.parser=new D;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 S;A.on.debug=u=>postMessage({action:"onDebug",data:u}),A.on.info=u=>postMessage({action:"onInfo",data:u}),A.on.config=u=>postMessage({action:"onConfig",data:u}),A.on.chunk=u=>postMessage({action:"onChunk",data:u}),onmessage=u=>{const{action:t,data:s}=u.data,e=A[t];e&&e(s)}})();\n', T = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", D], { type: "text/javascript;charset=utf-8" });
|
|
2
|
-
function
|
|
1
|
+
const D = '(function(){"use strict";class P{pendingPayloads=[];payload=new Uint8Array(0);chunks=[];push=t=>{this.pendingPayloads.push(t)};next=(t=0)=>{this.payload=this.payload.slice(t);const s=this.pendingPayloads.shift();if(!s)return!1;const e=new Uint8Array(this.payload.byteLength+s.byteLength);return e.set(this.payload,0),e.set(s,this.payload.byteLength),this.payload=e,new DataView(this.payload.buffer)};pushChunk=t=>{this.chunks.push(t),this.chunks.length>1e3&&this.chunks.shift()};destroy=()=>{this.pendingPayloads=[],this.payload=new Uint8Array(0),this.chunks=[]}}const I=(y,t)=>{const s=new Uint8Array(y),e=new Uint8Array(t),n=new Uint8Array(11+s.length+e.length);let a=0;return n[a++]=1,n[a++]=s[1],n[a++]=s[2],n[a++]=s[3],n[a++]=255,n[a++]=225,n[a++]=s.length>>8&255,n[a++]=s.length&255,n.set(s,a),a+=s.length,n[a++]=1,n[a++]=e.length>>8&255,n[a++]=e.length&255,n.set(e,a),n},T=y=>{let t=0;const s=new DataView(y.buffer),e=s.getUint8(t);if(t=t+1,e!==1)throw new Error("Invalid AVC version");const n=s.getUint8(t)&255;t=t+1;const a=s.getUint8(t)&255;t=t+1;const o=s.getUint8(t)&255;t=t+1;const c=`avc1.${Array.from([n,a,o],U=>U.toString(16).padStart(2,"0")).join("")}`,r=(s.getUint8(t)&3)-1;t=t+1;const g=s.getUint8(t)&31;t=t+1;const p=s.getUint16(t,!1);t=t+2;const h=new Uint8Array(s.buffer.slice(t,t+p));t=t+p;const d=s.getUint8(t)&31;t=t+1;const u=s.getUint16(t,!1);t=t+2;const f=new Uint8Array(s.buffer.slice(t,t+u));return t=t+u,{version:e,codec:c,profile:n,compatibility:a,level:o,lengthSizeMinusOne:r,numOfSequenceParameterSets:g,sequenceParameterSetLength:p,sps:h,numOfPictureParameterSets:d,pictureParameterSetLength:u,pps:f}},M=y=>{const t=new Uint8Array(4+y.length);return new DataView(t.buffer).setUint32(0,y.length,!1),t.set(y,4),t},C=y=>{let t=0;for(const n of y)t+=n.length;const s=new Uint8Array(t);let e=0;for(const n of y){const a=n;s.set(a,e),e+=a.length}return s},D=y=>{let t="unknown";switch(y){case 1:case 2:case 27:case 36:t="video";break;case 3:case 4:case 15:t="audio";break;case 6:t="subtitle";break;case 134:t="ad";break}return t};class x{pat;pmt;audioConfig;videoConfig;payloadMap=new Map;on={};constructor(){}parse=async t=>{let s=0;for(;!(s+188>t.byteLength);){if(t.getInt8(s)!=71){s++;continue}await this.parsePacket(t,s),s+=188}return s};parsePacket=async(t,s)=>{if(s+188>t.byteLength)throw new Error("Invalid TS packet");if(t.getUint8(s)!==71)throw new Error("Invalid TS packet");let e=s;const n=this.parseHeader(t,e);e+=4;const{transport_error_indicator:a,pid:o,payload_unit_start_indicator:l,adaptation_field_control:i}=n;if(a===1||o===void 0)return;let c=184;if(i===2||i===3){const r=t.getUint8(e);e+=1,this.parseAdaptationField(t,e),e+=r,c-=r}if(i===3&&(c-=1),i===1||i===3){const r=new Uint8Array(t.buffer.slice(e,e+c));if(o===0)return this.parsePAT(t,e);{const{programs:h=[]}=this.pat||{};if(h.find(u=>u.pmt_pid===o))return this.parsePMT(t,e)}const{streams:g=[]}=this.pmt||{},p=g.find(h=>h.elementary_pid===o);if(p){if(l===1){const h=this.payloadMap.get(o);if(h){switch(p.kind){case"audio":{const d=await this.parseAudio(h);this.on.chunk&&this.on.chunk(d)}break;case"video":{const d=await this.parseVideo(h);this.on.chunk&&this.on.chunk(d),await new Promise(u=>setTimeout(()=>u(!0),8))}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=(_,m)=>{let b=BigInt(0);b|=BigInt(_.getUint16(m))<<25n,b|=BigInt(_.getUint16(m+1))<<17n,b|=BigInt(_.getUint16(m+2))<<9n,b|=BigInt(_.getUint16(m+3))<<1n,b|=BigInt(_.getUint16(m+4)>>7);const S=(_.getUint16(m+4)&1)<<8|_.getUint16(m+5);return b=b*300n+BigInt(S),b};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){const r=s.getUint8(e);if(e+=1,r===255){const g=s.getUint8(e),p=s.getUint8(e+1),h=p>>2&3,d=(g&248)>>3&3,u=p>>6&3,U=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350][h],_=`mp4a.40.${d}`,m=u===3?1:2;this.audioConfig={kind:"audio",codec:_,sampleRate:U,numberOfChannels:m},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,pes_payload:a}}};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 O{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-2,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&248)>>3,f=(h&7)<<1|d>>7,U=(d&120)>>3,_=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],m=`mp4a.40.${u}`,b=_[f];return{soundFormat:o,soundRate:l,soundSize:i,soundType:c,accPacketType:r,data:p,audioObjectType:u,samplingFrequencyIndex:f,channelConfiguration:U,codec:m,sampleRate:b}}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 L{pattern;cacher=new P;isParseing=!1;offset=0;on={};parser;constructor(){}init=t=>{switch(this.destroy(),this.pattern=t,this.pattern){case"flv":this.parser=new O;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 L;A.on.debug=y=>postMessage({action:"onDebug",data:y}),A.on.info=y=>postMessage({action:"onInfo",data:y}),A.on.config=y=>postMessage({action:"onConfig",data:y}),A.on.chunk=y=>postMessage({action:"onChunk",data:y}),onmessage=y=>{const{action:t,data:s}=y.data,e=A[t];e&&e(s)}})();\n', v = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", D], { type: "text/javascript;charset=utf-8" });
|
|
2
|
+
function B(l) {
|
|
3
3
|
let t;
|
|
4
4
|
try {
|
|
5
|
-
if (t =
|
|
5
|
+
if (t = v && (self.URL || self.webkitURL).createObjectURL(v), !t) throw "";
|
|
6
6
|
const s = new Worker(t, {
|
|
7
|
-
name:
|
|
7
|
+
name: l?.name
|
|
8
8
|
});
|
|
9
9
|
return s.addEventListener("error", () => {
|
|
10
10
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
@@ -13,13 +13,13 @@ function L(u) {
|
|
|
13
13
|
return new Worker(
|
|
14
14
|
"data:text/javascript;charset=utf-8," + encodeURIComponent(D),
|
|
15
15
|
{
|
|
16
|
-
name:
|
|
16
|
+
name: l?.name
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
class
|
|
22
|
-
worker = new
|
|
21
|
+
class L {
|
|
22
|
+
worker = new B();
|
|
23
23
|
on = {};
|
|
24
24
|
constructor() {
|
|
25
25
|
this.worker.onmessage = (t) => {
|
|
@@ -47,13 +47,13 @@ class B {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
const M = `(function(){"use strict";class r{audioDecoderConfig;audioDecoder;videoDecoderConfig;videoDecoder;hasKeyFrame=!1;on={audio:{},video:{}};constructor(){}audio={init:i=>{this.audio.destroy(),this.audioDecoderConfig={...i},this.audioDecoder=new AudioDecoder({output:e=>{this.on.audio.decode&&this.on.audio.decode(e)},error:e=>{this.on.audio.error&&this.on.audio.error(e)}}),this.audioDecoder.configure(this.audioDecoderConfig)},decode:i=>{if(!this.audioDecoder)return;const e=new EncodedAudioChunk(i);this.audioDecoder.decode(e)},flush:()=>{this.audioDecoder?.flush()},destroy:()=>{this.audioDecoderConfig=void 0,this.audioDecoder?.close(),this.audioDecoder=void 0}};video={init:i=>{this.video.destroy(),this.videoDecoderConfig={...i},this.videoDecoder=new VideoDecoder({output:async e=>{const d=await createImageBitmap(e),s=e.timestamp;e.close(),d.width>0&&d.height>0?this.on.video.decode&&this.on.video.decode({timestamp:s,bitmap:d}):d.close()},error:e=>{console.log("\\x1B[38;2;0;151;255m%c%s\\x1B[0m","color:#0097ff;","------->Breathe: e",e),this.on.video.error&&this.on.video.error(e)}}),this.videoDecoder.configure(this.videoDecoderConfig)},decode:i=>{if(this.videoDecoder&&(i.type==="key"&&(this.hasKeyFrame=!0),this.hasKeyFrame&&this.videoDecoder.decodeQueueSize<2)){const e=new EncodedVideoChunk(i);this.videoDecoder.decode(e)}},flush:()=>{this.videoDecoder?.flush()},destroy:()=>{this.videoDecoderConfig=void 0,this.videoDecoder?.close(),this.videoDecoder=void 0,this.hasKeyFrame=!1}}}const t=new r;t.on.audio.decode=o=>postMessage({type:"audio",action:"onDecode",data:o}),t.on.audio.error=o=>postMessage({type:"audio",action:"onError",data:o}),t.on.video.decode=o=>postMessage({type:"video",action:"onDecode",data:o}),t.on.video.error=o=>postMessage({type:"video",action:"onError",data:o}),onmessage=o=>{const{type:i,action:e,data:d}=o.data,s=t[i][e];s&&s(d)}})();
|
|
50
|
-
`,
|
|
51
|
-
function F(
|
|
50
|
+
`, T = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", M], { type: "text/javascript;charset=utf-8" });
|
|
51
|
+
function F(l) {
|
|
52
52
|
let t;
|
|
53
53
|
try {
|
|
54
|
-
if (t =
|
|
54
|
+
if (t = T && (self.URL || self.webkitURL).createObjectURL(T), !t) throw "";
|
|
55
55
|
const s = new Worker(t, {
|
|
56
|
-
name:
|
|
56
|
+
name: l?.name
|
|
57
57
|
});
|
|
58
58
|
return s.addEventListener("error", () => {
|
|
59
59
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
@@ -62,7 +62,7 @@ function F(u) {
|
|
|
62
62
|
return new Worker(
|
|
63
63
|
"data:text/javascript;charset=utf-8," + encodeURIComponent(M),
|
|
64
64
|
{
|
|
65
|
-
name:
|
|
65
|
+
name: l?.name
|
|
66
66
|
}
|
|
67
67
|
);
|
|
68
68
|
}
|
|
@@ -103,93 +103,93 @@ class N {
|
|
|
103
103
|
this.worker.postMessage({ type: "audio", action: "destroy" }), this.worker.postMessage({ type: "video", action: "destroy", data: {} }), this.worker.terminate();
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
var E = Object.defineProperty, G = (
|
|
106
|
+
var E = Object.defineProperty, G = (l, t, s) => t in l ? E(l, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : l[t] = s, y = (l, t, s) => G(l, typeof t != "symbol" ? t + "" : t, s);
|
|
107
107
|
class O {
|
|
108
108
|
constructor(t, s) {
|
|
109
|
-
|
|
109
|
+
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", () => {
|
|
110
110
|
{
|
|
111
111
|
const e = this.inputStream.getTracks();
|
|
112
112
|
for (const n of e)
|
|
113
113
|
n.stop(), this.inputStream.removeTrack(n);
|
|
114
114
|
}
|
|
115
|
-
}),
|
|
115
|
+
}), y(this, "getStream", () => this.filterStream(this.outputStream)), y(this, "setMute", (e = !0) => {
|
|
116
116
|
e ? this.analyserNode.disconnect(this.outputGainNode) : this.analyserNode.connect(this.outputGainNode);
|
|
117
|
-
}),
|
|
117
|
+
}), y(this, "setInputGain", (e) => {
|
|
118
118
|
this.inputGain = e, this.inputGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
119
|
-
}),
|
|
119
|
+
}), y(this, "setEnhanceGain", async (e) => {
|
|
120
120
|
this.enhanceGain = e + 1, this.enhanceGainNode.gain.setValueAtTime(this.enhanceGain, this.audioContext.currentTime);
|
|
121
|
-
}),
|
|
121
|
+
}), y(this, "setBgsGain", (e) => {
|
|
122
122
|
this.bgsGain = e, this.bgsGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
123
|
-
}),
|
|
123
|
+
}), y(this, "setBgmGain", (e) => {
|
|
124
124
|
this.bgmGain = e, this.bgmGainNode.gain.setValueAtTime(e, this.audioContext.currentTime);
|
|
125
|
-
}),
|
|
125
|
+
}), y(this, "setOutputGain", (e) => {
|
|
126
126
|
this.outputGain = e, this.outputGainNode.gain.setValueAtTime(this.outputGain, this.audioContext.currentTime);
|
|
127
|
-
}),
|
|
127
|
+
}), y(this, "getVolume", () => {
|
|
128
128
|
const { analyserNode: e, analyserArrayData: n } = this;
|
|
129
129
|
e.getByteFrequencyData(n);
|
|
130
130
|
let i = 0;
|
|
131
|
-
for (let
|
|
132
|
-
i += n[
|
|
131
|
+
for (let r = 0; r < n.length; r++)
|
|
132
|
+
i += n[r];
|
|
133
133
|
return Math.ceil(i / n.length);
|
|
134
|
-
}),
|
|
134
|
+
}), y(this, "mixAudio", (e, n = "bgm") => new Promise(async (i, r) => {
|
|
135
135
|
try {
|
|
136
136
|
{
|
|
137
137
|
const d = this.mixAudioMap.get(n);
|
|
138
138
|
d && d.stop();
|
|
139
139
|
}
|
|
140
|
-
const
|
|
141
|
-
this.mixAudioMap.set(n,
|
|
142
|
-
|
|
143
|
-
},
|
|
144
|
-
} catch (
|
|
145
|
-
|
|
140
|
+
const c = n === "bgs" ? this.bgsGainNode : this.bgmGainNode, o = this.audioContext.createBufferSource();
|
|
141
|
+
this.mixAudioMap.set(n, o), o.buffer = e, o.connect(c), o.onended = () => {
|
|
142
|
+
o.disconnect(c), this.mixAudioMap.delete(n), i(!0);
|
|
143
|
+
}, o.start(0);
|
|
144
|
+
} catch (c) {
|
|
145
|
+
r(c);
|
|
146
146
|
}
|
|
147
|
-
})),
|
|
147
|
+
})), y(this, "mixAudioStop", (e) => {
|
|
148
148
|
const n = this.mixAudioMap.get(e);
|
|
149
149
|
n?.stop();
|
|
150
|
-
}),
|
|
150
|
+
}), y(this, "changeMix", (e, n) => {
|
|
151
151
|
const i = e === "bgs" ? this.bgsGainNode : this.bgmGainNode;
|
|
152
152
|
n ? i.connect(this.destinationNode) : i.disconnect(this.destinationNode);
|
|
153
153
|
}), 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;
|
|
154
154
|
{
|
|
155
|
-
const { sourceNode: e, inputGainNode: n, enhanceGainNode: i, bgsGainNode:
|
|
156
|
-
e.connect(n), n.connect(i), i.connect(
|
|
155
|
+
const { sourceNode: e, inputGainNode: n, enhanceGainNode: i, bgsGainNode: r, bgmGainNode: c, analyserNode: o, outputGainNode: d, destinationNode: a } = this;
|
|
156
|
+
e.connect(n), n.connect(i), i.connect(o), r.connect(o), c.connect(o), i.connect(a), r.connect(a), c.connect(a), o.connect(d), d.connect(this.audioContext.destination);
|
|
157
157
|
}
|
|
158
158
|
this.setMute(!0), this.audioContext.resume();
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
const W = async (
|
|
161
|
+
const W = async (l, t) => {
|
|
162
162
|
try {
|
|
163
|
-
const { format: s, numberOfChannels: e, numberOfFrames: n, sampleRate: i } = t,
|
|
164
|
-
for (let
|
|
165
|
-
const
|
|
166
|
-
t.copyTo(d, { planeIndex:
|
|
167
|
-
const
|
|
163
|
+
const { format: s, numberOfChannels: e, numberOfFrames: n, sampleRate: i } = t, r = l.createBuffer(e, n, i);
|
|
164
|
+
for (let c = 0; c < e; c++) {
|
|
165
|
+
const o = t.allocationSize({ planeIndex: c }), d = new Uint8Array(o);
|
|
166
|
+
t.copyTo(d, { planeIndex: c });
|
|
167
|
+
const a = new DataView(d.buffer), h = r.getChannelData(c);
|
|
168
168
|
for (let p = 0; p < n; p++) {
|
|
169
|
-
let
|
|
169
|
+
let u;
|
|
170
170
|
switch (s) {
|
|
171
171
|
case "s16":
|
|
172
172
|
// 16-bit signed PCM (范围: -32768 ~ 32767)
|
|
173
173
|
case "s16-planar":
|
|
174
|
-
|
|
174
|
+
u = a.getInt16(p * 2, !0) / 32768;
|
|
175
175
|
break;
|
|
176
176
|
case "f32":
|
|
177
177
|
// 32-bit float (范围: -1.0 ~ 1.0)
|
|
178
178
|
case "f32-planar":
|
|
179
|
-
|
|
179
|
+
u = a.getFloat32(p * 4, !0);
|
|
180
180
|
break;
|
|
181
181
|
case "u8":
|
|
182
182
|
// 8-bit unsigned (范围: 0 ~ 255)
|
|
183
183
|
case "u8-planar":
|
|
184
|
-
|
|
184
|
+
u = (a.getUint8(p) - 128) / 128;
|
|
185
185
|
break;
|
|
186
186
|
default:
|
|
187
187
|
throw new Error(`Unsupported audio format: ${s}`);
|
|
188
188
|
}
|
|
189
|
-
h[p] = Math.max(-1, Math.min(1,
|
|
189
|
+
h[p] = Math.max(-1, Math.min(1, u));
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
return
|
|
192
|
+
return r;
|
|
193
193
|
} catch (s) {
|
|
194
194
|
throw console.error("Failed to convert AudioData to AudioBuffer:", s), s;
|
|
195
195
|
}
|
|
@@ -228,12 +228,12 @@ class V {
|
|
|
228
228
|
}
|
|
229
229
|
const S = `(function(){"use strict";class r{isRendering=!1;pendingFrames=[];offscreenCanvas;writable;writer;ctx;cutOption;baseTime=0;pause=!1;shader=["stream"];constructor(){}init=({offscreenCanvas:e,writable:t})=>{this.destroy(),this.offscreenCanvas=e,this.writable=t,this.writer=this.writable.getWriter(),this.ctx=this.offscreenCanvas.getContext("2d")};setBaseTime=e=>{this.baseTime=e};setShader=e=>{this.shader=e};setSize=({width:e,height:t})=>{this.offscreenCanvas&&(this.offscreenCanvas.width=e,this.offscreenCanvas.height=t)};destroy=()=>{this.isRendering=!1,this.pendingFrames=[],this.offscreenCanvas=void 0,this.ctx=void 0,this.baseTime=0};push=e=>{this.pendingFrames.push(e),this.isRendering===!1&&setTimeout(this.renderFrame,0)};setCut=e=>{this.cutOption=e};setPause=e=>{this.pause=e,this.isRendering===!1&&setTimeout(this.renderFrame,0)};calculateTimeUntilNextFrame=e=>{const t=performance.timeOrigin+performance.now(),i=this.baseTime+e/1e3-t;return Math.max(0,i)};renderFrame=async()=>{for(this.isRendering=!0;;){const e=this.pendingFrames.shift();if(!e)break;let{timestamp:t,bitmap:s}=e;if(this.cutOption){const{sx:a=0,sy:c=0,sw:m=s.width,sh:o=s.height}=this.cutOption;s=await createImageBitmap(s,a,c,m,o)}const i=this.calculateTimeUntilNextFrame(t);await new Promise(a=>setTimeout(()=>a(!0),i)),this.drawImage({timestamp:t,bitmap:s}),this.cutOption&&s.close()}this.isRendering=!1};drawImage=e=>{if(this.pause!==!0){if(this.shader.includes("stream")){const t=new VideoFrame(e.bitmap,{timestamp:e.timestamp});this.writer.write(t),t.close()}this.shader.includes("canvas")&&this.ctx&&this.offscreenCanvas&&this.ctx.drawImage(e.bitmap,0,0,this.offscreenCanvas.width,this.offscreenCanvas.height)}}}const h=new r;onmessage=n=>{const{action:e,data:t}=n.data,s=h[e];s&&s(t)}})();
|
|
230
230
|
`, x = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", S], { type: "text/javascript;charset=utf-8" });
|
|
231
|
-
function
|
|
231
|
+
function j(l) {
|
|
232
232
|
let t;
|
|
233
233
|
try {
|
|
234
234
|
if (t = x && (self.URL || self.webkitURL).createObjectURL(x), !t) throw "";
|
|
235
235
|
const s = new Worker(t, {
|
|
236
|
-
name:
|
|
236
|
+
name: l?.name
|
|
237
237
|
});
|
|
238
238
|
return s.addEventListener("error", () => {
|
|
239
239
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
@@ -242,13 +242,13 @@ function z(u) {
|
|
|
242
242
|
return new Worker(
|
|
243
243
|
"data:text/javascript;charset=utf-8," + encodeURIComponent(S),
|
|
244
244
|
{
|
|
245
|
-
name:
|
|
245
|
+
name: l?.name
|
|
246
246
|
}
|
|
247
247
|
);
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
|
-
class
|
|
251
|
-
worker = new
|
|
250
|
+
class z {
|
|
251
|
+
worker = new j();
|
|
252
252
|
constructor() {
|
|
253
253
|
}
|
|
254
254
|
init = ({ offscreenCanvas: t, writable: s }) => this.worker.postMessage({ action: "init", data: { offscreenCanvas: t, writable: s } }, [t, s]);
|
|
@@ -262,18 +262,18 @@ class j {
|
|
|
262
262
|
this.worker.postMessage({ action: "destroy", data: {} }), this.worker.terminate();
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
|
-
const $ = (
|
|
266
|
-
const t =
|
|
265
|
+
const $ = (l) => {
|
|
266
|
+
const t = l.toLowerCase();
|
|
267
267
|
return t.includes(".m3u8") || t.includes("hls") || t.includes("master.m3u8") || t.match(/index\d*\.m3u8/) ? "hls" : t.includes(".mpd") || t.includes("dash") ? "dash" : t.startsWith("rtmp://") || t.startsWith("rtmps://") ? "rtmp" : t.includes(".flv") || t.includes("flv") && !t.includes("flash") ? "flv" : "unknown";
|
|
268
|
-
}, P = (
|
|
269
|
-
const t =
|
|
268
|
+
}, P = (l) => {
|
|
269
|
+
const t = l?.getTracks() || [];
|
|
270
270
|
for (const s of t)
|
|
271
271
|
s.stop();
|
|
272
272
|
}, A = () => {
|
|
273
|
-
const
|
|
274
|
-
|
|
273
|
+
const l = new z(), t = document.createElement("canvas"), s = t.transferControlToOffscreen(), e = new MediaStreamTrackGenerator({ kind: "video" }), n = new MediaStream([e]), i = () => {
|
|
274
|
+
l.destroy(), P(n);
|
|
275
275
|
};
|
|
276
|
-
return
|
|
276
|
+
return l.init({ offscreenCanvas: s, writable: e.writable }), { worker: l, canvas: t, stream: n, destroy: i };
|
|
277
277
|
};
|
|
278
278
|
class H {
|
|
279
279
|
resolvesMap = /* @__PURE__ */ new Map();
|
|
@@ -290,15 +290,15 @@ class H {
|
|
|
290
290
|
add = (t, s = () => !1, e = 0) => new Promise((n) => {
|
|
291
291
|
if (s()) return n(!0);
|
|
292
292
|
this.resolvesMap.has(t) || this.resolvesMap.set(t, /* @__PURE__ */ new Map()), this.index++;
|
|
293
|
-
const
|
|
293
|
+
const c = `${this.index}`;
|
|
294
294
|
if (e = Math.max(0, e), e === 0) {
|
|
295
|
-
this.resolvesMap.get(t)?.set(
|
|
295
|
+
this.resolvesMap.get(t)?.set(c, { resolve: n, timer: 0 });
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
|
-
const
|
|
298
|
+
const o = window.setTimeout(() => {
|
|
299
299
|
this.emit(t);
|
|
300
300
|
}, e);
|
|
301
|
-
this.resolvesMap.get(t)?.set(
|
|
301
|
+
this.resolvesMap.get(t)?.set(c, { resolve: n, timer: o });
|
|
302
302
|
});
|
|
303
303
|
emit = async (t) => {
|
|
304
304
|
const s = this.resolvesMap.get(t);
|
|
@@ -310,59 +310,59 @@ class H {
|
|
|
310
310
|
}
|
|
311
311
|
};
|
|
312
312
|
}
|
|
313
|
-
const q = (
|
|
314
|
-
const s = new Uint8Array(
|
|
313
|
+
const q = (l, t) => {
|
|
314
|
+
const s = new Uint8Array(l), e = new Uint8Array(t), n = new Uint8Array(11 + s.length + e.length);
|
|
315
315
|
let i = 0;
|
|
316
316
|
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;
|
|
317
|
-
}, I = (
|
|
317
|
+
}, I = (l) => {
|
|
318
318
|
let t = 0;
|
|
319
|
-
const s = new DataView(
|
|
319
|
+
const s = new DataView(l.buffer), e = s.getUint8(t);
|
|
320
320
|
if (t = t + 1, e !== 1) throw new Error("Invalid AVC version");
|
|
321
321
|
const n = s.getUint8(t) & 255;
|
|
322
322
|
t = t + 1;
|
|
323
323
|
const i = s.getUint8(t) & 255;
|
|
324
324
|
t = t + 1;
|
|
325
|
-
const
|
|
325
|
+
const r = s.getUint8(t) & 255;
|
|
326
326
|
t = t + 1;
|
|
327
|
-
const d = `avc1.${Array.from([n, i,
|
|
327
|
+
const d = `avc1.${Array.from([n, i, r], (k) => k.toString(16).padStart(2, "0")).join("")}`, a = (s.getUint8(t) & 3) - 1;
|
|
328
328
|
t = t + 1;
|
|
329
329
|
const h = s.getUint8(t) & 31;
|
|
330
330
|
t = t + 1;
|
|
331
331
|
const p = s.getUint16(t, !1);
|
|
332
332
|
t = t + 2;
|
|
333
|
-
const
|
|
333
|
+
const u = new Uint8Array(s.buffer.slice(t, t + p));
|
|
334
334
|
t = t + p;
|
|
335
335
|
const g = s.getUint8(t) & 31;
|
|
336
336
|
t = t + 1;
|
|
337
|
-
const
|
|
337
|
+
const f = s.getUint16(t, !1);
|
|
338
338
|
t = t + 2;
|
|
339
|
-
const
|
|
340
|
-
return t = t +
|
|
341
|
-
}, K = (
|
|
342
|
-
const t = new Uint8Array(4 +
|
|
343
|
-
return new DataView(t.buffer).setUint32(0,
|
|
344
|
-
}, X = (
|
|
339
|
+
const m = new Uint8Array(s.buffer.slice(t, t + f));
|
|
340
|
+
return t = t + f, { version: e, codec: d, profile: n, compatibility: i, level: r, lengthSizeMinusOne: a, numOfSequenceParameterSets: h, sequenceParameterSetLength: p, sps: u, numOfPictureParameterSets: g, pictureParameterSetLength: f, pps: m };
|
|
341
|
+
}, K = (l) => {
|
|
342
|
+
const t = new Uint8Array(4 + l.length);
|
|
343
|
+
return new DataView(t.buffer).setUint32(0, l.length, !1), t.set(l, 4), t;
|
|
344
|
+
}, X = (l) => {
|
|
345
345
|
let t = 0;
|
|
346
|
-
for (const n of
|
|
346
|
+
for (const n of l)
|
|
347
347
|
t += n.length;
|
|
348
348
|
const s = new Uint8Array(t);
|
|
349
349
|
let e = 0;
|
|
350
|
-
for (const n of
|
|
350
|
+
for (const n of l) {
|
|
351
351
|
const i = n;
|
|
352
352
|
s.set(i, e), e += i.length;
|
|
353
353
|
}
|
|
354
354
|
return s;
|
|
355
|
-
}, Y = (
|
|
356
|
-
const t = new DataView(
|
|
355
|
+
}, Y = (l) => {
|
|
356
|
+
const t = new DataView(l.buffer);
|
|
357
357
|
let s = 0, e, n, i;
|
|
358
358
|
e = t.getUint32(s, !1), s += 4;
|
|
359
359
|
{
|
|
360
|
-
const
|
|
361
|
-
n = { forbidden_zero_bit:
|
|
360
|
+
const r = t.getUint8(s), c = r >> 7 & 1, o = r >> 5 & 3, d = r & 31;
|
|
361
|
+
n = { forbidden_zero_bit: c, nal_ref_idc: o, nal_unit_type: d }, s += 1;
|
|
362
362
|
}
|
|
363
363
|
{
|
|
364
|
-
const
|
|
365
|
-
i = new Uint8Array(t.buffer.slice(s, s +
|
|
364
|
+
const r = e - 1;
|
|
365
|
+
i = new Uint8Array(t.buffer.slice(s, s + r));
|
|
366
366
|
}
|
|
367
367
|
return { size: e, header: n, data: i };
|
|
368
368
|
};
|
|
@@ -386,10 +386,10 @@ class C {
|
|
|
386
386
|
this.#t?.abort("Timeout."), n({ status: "timeout", reason: "" });
|
|
387
387
|
}, this.#e.timeout);
|
|
388
388
|
try {
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
} catch (
|
|
392
|
-
n({ status: "error", reason:
|
|
389
|
+
const r = await fetch(t, { ...s, method: "HEAD", signal: this.#t?.signal });
|
|
390
|
+
r.status === 200 ? e({ status: "successed", reason: "" }) : n({ status: "failed", reason: `${r.status}` });
|
|
391
|
+
} catch (r) {
|
|
392
|
+
n({ status: "error", reason: r.message });
|
|
393
393
|
}
|
|
394
394
|
clearTimeout(i);
|
|
395
395
|
});
|
|
@@ -415,6 +415,9 @@ class C {
|
|
|
415
415
|
};
|
|
416
416
|
}
|
|
417
417
|
class et {
|
|
418
|
+
option = {
|
|
419
|
+
debug: !1
|
|
420
|
+
};
|
|
418
421
|
prFetch = new C();
|
|
419
422
|
prResolves = new H();
|
|
420
423
|
url = "";
|
|
@@ -429,7 +432,9 @@ class et {
|
|
|
429
432
|
cutRenders = /* @__PURE__ */ new Map();
|
|
430
433
|
// @ts-ignore
|
|
431
434
|
trackGenerator;
|
|
432
|
-
constructor() {
|
|
435
|
+
constructor(t = {}) {
|
|
436
|
+
const { debug: s = !1 } = t;
|
|
437
|
+
this.option.debug = s;
|
|
433
438
|
}
|
|
434
439
|
/**
|
|
435
440
|
* 初始化
|
|
@@ -461,7 +466,7 @@ class et {
|
|
|
461
466
|
try {
|
|
462
467
|
clearInterval(this.hls.getSegmentsTimer), this.prFetch.stop();
|
|
463
468
|
} catch (s) {
|
|
464
|
-
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->
|
|
469
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: error", s);
|
|
465
470
|
}
|
|
466
471
|
this.demuxerWorker?.destroy(), this.decoderWorker?.destroy(), this.renderWorker?.destroy(), P(this.stream);
|
|
467
472
|
const t = [...this.cutRenders.keys()];
|
|
@@ -522,17 +527,18 @@ class et {
|
|
|
522
527
|
* 初始化解复器
|
|
523
528
|
*/
|
|
524
529
|
initDemuxer = (t) => {
|
|
525
|
-
this.demuxerWorker = new
|
|
530
|
+
this.demuxerWorker = new L(), this.demuxerWorker.init(t), this.demuxerWorker.on.debug = (s) => {
|
|
531
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: debug", s);
|
|
526
532
|
}, this.demuxerWorker.on.info = (s) => {
|
|
527
|
-
this.on.demuxer.info && this.on.demuxer.info(s);
|
|
533
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: info", s), this.on.demuxer.info && this.on.demuxer.info(s);
|
|
528
534
|
}, this.demuxerWorker.on.config = (s) => {
|
|
529
|
-
this.on.demuxer.config && this.on.demuxer.config(s);
|
|
535
|
+
this.option.debug && console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: config", s), this.on.demuxer.config && this.on.demuxer.config(s);
|
|
530
536
|
const { kind: e } = s;
|
|
531
537
|
switch (e) {
|
|
532
538
|
case "audio":
|
|
533
539
|
{
|
|
534
|
-
const { codec: n, sampleRate: i, numberOfChannels:
|
|
535
|
-
this.decoderWorker?.audio.init({ codec: n, sampleRate: i, numberOfChannels:
|
|
540
|
+
const { codec: n, sampleRate: i, numberOfChannels: r } = s;
|
|
541
|
+
this.decoderWorker?.audio.init({ codec: n, sampleRate: i, numberOfChannels: r });
|
|
536
542
|
}
|
|
537
543
|
break;
|
|
538
544
|
case "video":
|
|
@@ -548,22 +554,22 @@ class et {
|
|
|
548
554
|
switch (e) {
|
|
549
555
|
case "audio":
|
|
550
556
|
{
|
|
551
|
-
const { type: n, dts: i, data:
|
|
552
|
-
this.decoderWorker.audio.decode({ type: n, timestamp:
|
|
557
|
+
const { type: n, dts: i, data: r } = s, c = i * 1;
|
|
558
|
+
this.decoderWorker.audio.decode({ type: n, timestamp: c, data: r });
|
|
553
559
|
}
|
|
554
560
|
break;
|
|
555
561
|
case "video":
|
|
556
562
|
{
|
|
557
|
-
const { type: n, dts: i, data:
|
|
563
|
+
const { type: n, dts: i, data: r, nalus: c = [] } = s;
|
|
558
564
|
if (this.renderBaseTime === void 0) {
|
|
559
565
|
const d = (/* @__PURE__ */ new Date()).getTime();
|
|
560
566
|
this.renderBaseTime = d - i, this.renderWorker?.setBaseTime(this.renderBaseTime);
|
|
561
567
|
}
|
|
562
|
-
const
|
|
563
|
-
this.decoderWorker.video.decode({ type: n, timestamp:
|
|
564
|
-
for (const d of
|
|
568
|
+
const o = i * 1e3;
|
|
569
|
+
this.decoderWorker.video.decode({ type: n, timestamp: o, data: r });
|
|
570
|
+
for (const d of c) {
|
|
565
571
|
if (d.byteLength <= 4) continue;
|
|
566
|
-
const { header:
|
|
572
|
+
const { header: a, data: h } = Y(d), { nal_unit_type: p } = a;
|
|
567
573
|
p === 6 && this.on.demuxer.sei && this.on.demuxer.sei(h);
|
|
568
574
|
}
|
|
569
575
|
}
|
|
@@ -617,16 +623,16 @@ class et {
|
|
|
617
623
|
getSegmentsTimer: 0,
|
|
618
624
|
parse: async (t) => {
|
|
619
625
|
const n = new TextDecoder("utf-8").decode(t).split(`
|
|
620
|
-
`).map((
|
|
621
|
-
let
|
|
626
|
+
`).map((a) => a.replace("\r", "")), i = this.url.substring(0, this.url.lastIndexOf("/") + 1);
|
|
627
|
+
let r = 4, c = 0, o = !1;
|
|
622
628
|
const d = [];
|
|
623
|
-
for (const
|
|
624
|
-
|
|
625
|
-
url:
|
|
626
|
-
duration:
|
|
627
|
-
isLive:
|
|
629
|
+
for (const a of n)
|
|
630
|
+
a.startsWith("#EXTINF:") ? r = parseFloat(a.split(":")[1].split(",")[0]) : a.startsWith("#EXT-X-TARGETDURATION:") ? c = parseInt(a.split(":")[1]) : a.startsWith("#EXT-X-ENDLIST") ? o = !1 : a.startsWith("#EXT-X-MEDIA-SEQUENCE:") ? o = !0 : a.includes(".ts") && !a.startsWith("#") && d.push({
|
|
631
|
+
url: a.startsWith("http") ? a : i + a,
|
|
632
|
+
duration: r,
|
|
633
|
+
isLive: o
|
|
628
634
|
});
|
|
629
|
-
return { baseUrl: i, targetDuration:
|
|
635
|
+
return { baseUrl: i, targetDuration: c, isLive: o, segments: d };
|
|
630
636
|
},
|
|
631
637
|
getSegments: async () => {
|
|
632
638
|
const e = (await new C().request(this.url)).body?.getReader();
|
|
@@ -634,11 +640,11 @@ class et {
|
|
|
634
640
|
for (; ; ) {
|
|
635
641
|
const { done: n, value: i } = await e.read();
|
|
636
642
|
if (i) {
|
|
637
|
-
const
|
|
638
|
-
this.hls.isLive =
|
|
639
|
-
let d = Array.from(
|
|
640
|
-
const
|
|
641
|
-
|
|
643
|
+
const r = await this.hls.parse(i), { segments: c = [], isLive: o = !1 } = r;
|
|
644
|
+
this.hls.isLive = o;
|
|
645
|
+
let d = Array.from(c, (h) => h.url);
|
|
646
|
+
const a = d.findIndex((h) => h === this.hls.url);
|
|
647
|
+
a !== -1 && (d = d.slice(a + 1)), this.hls.urls = d;
|
|
642
648
|
}
|
|
643
649
|
if (n) break;
|
|
644
650
|
}
|
|
@@ -690,9 +696,9 @@ class Q {
|
|
|
690
696
|
this.pendingPayloads = [], this.payload = new Uint8Array(0), this.chunks = [];
|
|
691
697
|
};
|
|
692
698
|
}
|
|
693
|
-
const J = (
|
|
699
|
+
const J = (l) => {
|
|
694
700
|
let t = "unknown";
|
|
695
|
-
switch (
|
|
701
|
+
switch (l) {
|
|
696
702
|
case 1:
|
|
697
703
|
case 2:
|
|
698
704
|
case 27:
|
|
@@ -741,42 +747,46 @@ class Z {
|
|
|
741
747
|
let e = s;
|
|
742
748
|
const n = this.parseHeader(t, e);
|
|
743
749
|
e += 4;
|
|
744
|
-
const { transport_error_indicator: i, pid:
|
|
745
|
-
if (i === 1 ||
|
|
750
|
+
const { transport_error_indicator: i, pid: r, payload_unit_start_indicator: c, adaptation_field_control: o } = n;
|
|
751
|
+
if (i === 1 || r === void 0) return;
|
|
746
752
|
let d = 184;
|
|
747
|
-
if (
|
|
748
|
-
const
|
|
749
|
-
e += 1, this.parseAdaptationField(t, e), e +=
|
|
753
|
+
if (o === 2 || o === 3) {
|
|
754
|
+
const a = t.getUint8(e);
|
|
755
|
+
e += 1, this.parseAdaptationField(t, e), e += a, d -= a;
|
|
750
756
|
}
|
|
751
|
-
if (
|
|
752
|
-
const
|
|
753
|
-
if (
|
|
757
|
+
if (o === 3 && (d -= 1), o === 1 || o === 3) {
|
|
758
|
+
const a = new Uint8Array(t.buffer.slice(e, e + d));
|
|
759
|
+
if (r === 0) return this.parsePAT(t, e);
|
|
754
760
|
{
|
|
755
|
-
const { programs:
|
|
756
|
-
if (
|
|
761
|
+
const { programs: u = [] } = this.pat || {};
|
|
762
|
+
if (u.find((f) => f.pmt_pid === r)) return this.parsePMT(t, e);
|
|
757
763
|
}
|
|
758
|
-
const { streams: h = [] } = this.pmt || {}, p = h.find((
|
|
764
|
+
const { streams: h = [] } = this.pmt || {}, p = h.find((u) => u.elementary_pid === r);
|
|
759
765
|
if (p) {
|
|
760
|
-
if (
|
|
761
|
-
const
|
|
762
|
-
if (
|
|
766
|
+
if (c === 1) {
|
|
767
|
+
const u = this.payloadMap.get(r);
|
|
768
|
+
if (u) {
|
|
763
769
|
switch (p.kind) {
|
|
764
770
|
case "audio":
|
|
771
|
+
{
|
|
772
|
+
const g = await this.parseAudio(u);
|
|
773
|
+
this.on.chunk && this.on.chunk(g);
|
|
774
|
+
}
|
|
765
775
|
break;
|
|
766
776
|
case "video":
|
|
767
777
|
{
|
|
768
|
-
const g = await this.parseVideo(
|
|
769
|
-
this.on.chunk && this.on.chunk(g), await new Promise((
|
|
778
|
+
const g = await this.parseVideo(u);
|
|
779
|
+
this.on.chunk && this.on.chunk(g), await new Promise((f) => setTimeout(() => f(!0), 8));
|
|
770
780
|
}
|
|
771
781
|
break;
|
|
772
782
|
}
|
|
773
|
-
this.payloadMap.delete(
|
|
783
|
+
this.payloadMap.delete(r);
|
|
774
784
|
}
|
|
775
785
|
}
|
|
776
786
|
{
|
|
777
|
-
this.payloadMap.has(
|
|
778
|
-
const
|
|
779
|
-
g.set(
|
|
787
|
+
this.payloadMap.has(r) || this.payloadMap.set(r, new Uint8Array());
|
|
788
|
+
const u = this.payloadMap.get(r), g = new Uint8Array(u.byteLength + a.byteLength);
|
|
789
|
+
g.set(u, 0), g.set(a, u.byteLength), this.payloadMap.set(r, g);
|
|
780
790
|
}
|
|
781
791
|
}
|
|
782
792
|
}
|
|
@@ -784,160 +794,197 @@ class Z {
|
|
|
784
794
|
// Header
|
|
785
795
|
parseHeader = (t, s) => {
|
|
786
796
|
let e = s;
|
|
787
|
-
const n = t.getUint8(e), i = t.getUint8(e + 1),
|
|
788
|
-
if (
|
|
789
|
-
const d = (i & 64) >> 6,
|
|
790
|
-
return { sync_byte: n, transport_error_indicator:
|
|
797
|
+
const n = t.getUint8(e), i = t.getUint8(e + 1), r = t.getUint8(e + 2), c = t.getUint8(e + 3), o = (i & 128) >> 7;
|
|
798
|
+
if (o === 1) return { sync_byte: n, transport_error_indicator: o };
|
|
799
|
+
const d = (i & 64) >> 6, a = (i & 32) >> 5, h = (i & 31) << 8 | r, p = (c & 192) >> 6, u = c >> 4 & 3, g = c & 15;
|
|
800
|
+
return { sync_byte: n, transport_error_indicator: o, payload_unit_start_indicator: d, transport_priority: a, pid: h, transport_scrambling_control: p, adaptation_field_control: u, continuity_counter: g };
|
|
791
801
|
};
|
|
792
802
|
// PAT表
|
|
793
803
|
parsePAT = (t, s) => {
|
|
794
804
|
let e = s, n;
|
|
795
805
|
{
|
|
796
|
-
const
|
|
806
|
+
const c = t.getUint8(e);
|
|
797
807
|
e += 1;
|
|
798
|
-
const
|
|
799
|
-
if (e += 1,
|
|
808
|
+
const o = t.getUint8(e);
|
|
809
|
+
if (e += 1, o !== 0) throw new Error("Invalid PAT table_id");
|
|
800
810
|
const d = t.getUint16(e) & 4095;
|
|
801
811
|
e += 2;
|
|
802
|
-
const
|
|
812
|
+
const a = t.getUint16(e);
|
|
803
813
|
e += 2;
|
|
804
814
|
const h = (t.getUint8(e) & 62) >> 1, p = t.getUint8(e) & 1;
|
|
805
815
|
e += 1;
|
|
806
|
-
const
|
|
816
|
+
const u = t.getUint8(e);
|
|
807
817
|
e += 1;
|
|
808
818
|
const g = t.getUint8(e);
|
|
809
|
-
e += 1, n = { pointer_field:
|
|
819
|
+
e += 1, n = { pointer_field: c, table_id: o, section_length: d, transport_stream_id: a, version_number: h, current_next_indicator: p, section_number: u, last_section_number: g };
|
|
810
820
|
}
|
|
811
821
|
const i = [];
|
|
812
822
|
{
|
|
813
|
-
const
|
|
814
|
-
for (; e <
|
|
815
|
-
const d = t.getUint16(e),
|
|
816
|
-
e += 4, d !== 0 &&
|
|
823
|
+
const c = n.section_length - 5 - 4, o = e + c;
|
|
824
|
+
for (; e < o; ) {
|
|
825
|
+
const d = t.getUint16(e), a = t.getUint16(e + 2) & 8191;
|
|
826
|
+
e += 4, d !== 0 && a >= 32 && a <= 8190 && i.push({ program_number: d, pmt_pid: a });
|
|
817
827
|
}
|
|
818
828
|
}
|
|
819
|
-
const
|
|
820
|
-
this.pat = { header: n, programs: i, crc32:
|
|
829
|
+
const r = t.getUint32(e);
|
|
830
|
+
this.pat = { header: n, programs: i, crc32: r }, this.on.debug && this.on.debug({ pat: this.pat });
|
|
821
831
|
};
|
|
822
832
|
// PMT表
|
|
823
833
|
parsePMT = (t, s) => {
|
|
824
834
|
let e = s, n;
|
|
825
835
|
{
|
|
826
|
-
const
|
|
836
|
+
const c = t.getUint8(e);
|
|
827
837
|
e += 1;
|
|
828
|
-
const
|
|
829
|
-
if (e += 1,
|
|
838
|
+
const o = t.getUint8(e);
|
|
839
|
+
if (e += 1, o !== 2) throw new Error("Invalid PMT table_id");
|
|
830
840
|
const d = t.getUint16(e) & 4095;
|
|
831
841
|
e += 2;
|
|
832
|
-
const
|
|
842
|
+
const a = t.getUint16(e);
|
|
833
843
|
e += 2;
|
|
834
844
|
const h = (t.getUint8(e) & 62) >> 1, p = t.getUint8(e) & 1;
|
|
835
845
|
e += 1;
|
|
836
|
-
const
|
|
846
|
+
const u = t.getUint8(e);
|
|
837
847
|
e += 1;
|
|
838
848
|
const g = t.getUint8(e);
|
|
839
849
|
e += 1;
|
|
840
|
-
const
|
|
850
|
+
const f = t.getUint16(e) & 8191;
|
|
841
851
|
e += 2;
|
|
842
|
-
const
|
|
843
|
-
e += 2, n = { pointer_field:
|
|
852
|
+
const m = t.getUint16(e) & 4095;
|
|
853
|
+
e += 2, n = { pointer_field: c, table_id: o, section_length: d, transport_stream_id: a, version_number: h, current_next_indicator: p, section_number: u, last_section_number: g, pcr_pid: f, program_info_length: m };
|
|
844
854
|
}
|
|
845
855
|
const i = [];
|
|
846
856
|
{
|
|
847
|
-
const
|
|
848
|
-
for (; e <
|
|
849
|
-
const d = t.getUint8(e),
|
|
857
|
+
const c = n.section_length - 9 - 4, o = e + c;
|
|
858
|
+
for (; e < o; ) {
|
|
859
|
+
const d = t.getUint8(e), a = J(d), h = t.getUint16(e + 1) & 8191, p = t.getUint16(e + 3) & 4095;
|
|
850
860
|
if (e += 5, h < 32 || h > 8190) {
|
|
851
861
|
console.warn(`Invalid elementary_pid: 0x${h.toString(16)}`);
|
|
852
862
|
continue;
|
|
853
863
|
}
|
|
854
|
-
i.push({ kind:
|
|
864
|
+
i.push({ kind: a, stream_type: d, elementary_pid: h, es_info_length: p });
|
|
855
865
|
}
|
|
856
866
|
}
|
|
857
|
-
const
|
|
858
|
-
this.pmt = { header: n, streams: i, crc32:
|
|
867
|
+
const r = t.getUint32(e);
|
|
868
|
+
this.pmt = { header: n, streams: i, crc32: r }, this.on.debug && this.on.debug({ pmt: this.pmt });
|
|
859
869
|
};
|
|
860
870
|
// AdaptationField
|
|
861
871
|
parseAdaptationField = (t, s) => {
|
|
862
|
-
let e = s, n, i,
|
|
863
|
-
const
|
|
872
|
+
let e = s, n, i, r, c;
|
|
873
|
+
const o = t.getUint8(e), d = !!(o & 128), a = !!(o & 64), h = !!(o & 32), p = !!(o & 16), u = !!(o & 8), g = !!(o & 4), f = !!(o & 2), m = !!(o & 1);
|
|
864
874
|
e += 1;
|
|
865
|
-
const
|
|
866
|
-
let
|
|
867
|
-
|
|
868
|
-
const R = (b.getUint16(
|
|
869
|
-
return
|
|
875
|
+
const k = (b, U) => {
|
|
876
|
+
let w = BigInt(0);
|
|
877
|
+
w |= BigInt(b.getUint16(U)) << 25n, w |= BigInt(b.getUint16(U + 1)) << 17n, w |= BigInt(b.getUint16(U + 2)) << 9n, w |= BigInt(b.getUint16(U + 3)) << 1n, w |= BigInt(b.getUint16(U + 4) >> 7);
|
|
878
|
+
const R = (b.getUint16(U + 4) & 1) << 8 | b.getUint16(U + 5);
|
|
879
|
+
return w = w * 300n + BigInt(R), w;
|
|
870
880
|
};
|
|
871
|
-
if (p && (n =
|
|
881
|
+
if (p && (n = k(t, e), e += 6), u && (i = k(t, e), e += 6), g && (r = t.getInt8(e), e += 1), f) {
|
|
872
882
|
const b = t.getUint8(e);
|
|
873
|
-
e += 1,
|
|
883
|
+
e += 1, c = new Uint8Array(t.buffer, e, b), e += b;
|
|
884
|
+
}
|
|
885
|
+
return { discontinuity_indicator: d, random_access_indicator: a, elementary_stream_priority_indicator: h, pcr_flag: p, opcr_flag: u, splicing_point_flag: g, transport_private_data_flag: f, adaptation_field_extension_flag: m, pcr: n, opcr: i, splice_countdown: r, transport_private_data: c };
|
|
886
|
+
};
|
|
887
|
+
parseAudio = async (t) => {
|
|
888
|
+
const s = new DataView(t.buffer);
|
|
889
|
+
let e = 0, n, i;
|
|
890
|
+
{
|
|
891
|
+
const r = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
892
|
+
if (e += 3, !r)
|
|
893
|
+
throw new Error("invalid ts audio payload.");
|
|
894
|
+
const c = s.getUint8(e);
|
|
895
|
+
e += 1;
|
|
896
|
+
const o = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
897
|
+
e += 2;
|
|
898
|
+
let d, a, h, p, u;
|
|
899
|
+
{
|
|
900
|
+
const m = s.getUint8(e);
|
|
901
|
+
e += 1, d = m >> 4 & 3, a = (m >> 3 & 1) === 1, h = (m >> 2 & 1) === 1, p = (m >> 1 & 1) === 1, u = (m & 1) === 1;
|
|
902
|
+
}
|
|
903
|
+
let g, f;
|
|
904
|
+
{
|
|
905
|
+
const m = s.getUint8(e);
|
|
906
|
+
e += 1;
|
|
907
|
+
const k = m >> 6, b = s.getUint8(e);
|
|
908
|
+
e += 1, (k & 2) === 2 && (g = this.parsePtsDts(s, e)), (k & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += b;
|
|
909
|
+
}
|
|
910
|
+
n = { stream_id: c, pes_packet_length: o, scrambling_control: d, priority: a, data_alignment: h, copyright: p, original_copy: u, pts: g, dts: f };
|
|
911
|
+
}
|
|
912
|
+
i = t.slice(e);
|
|
913
|
+
{
|
|
914
|
+
if (!this.audioConfig) {
|
|
915
|
+
const a = s.getUint8(e);
|
|
916
|
+
if (e += 1, a === 255) {
|
|
917
|
+
const h = s.getUint8(e), p = s.getUint8(e + 1), u = p >> 2 & 3, g = (h & 248) >> 3 & 3, f = p >> 6 & 3, k = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350][u], b = `mp4a.40.${g}`, U = f === 3 ? 1 : 2;
|
|
918
|
+
this.audioConfig = { kind: "audio", codec: b, sampleRate: k, numberOfChannels: U }, this.on.config && this.on.config(this.audioConfig);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
const { dts: r = 0, pts: c = 0 } = n, o = c - r, d = i.slice(7);
|
|
922
|
+
return { kind: "audio", type: "key", dts: r, pts: c, cts: o, data: d, pes_payload: i };
|
|
874
923
|
}
|
|
875
|
-
return { discontinuity_indicator: d, random_access_indicator: c, elementary_stream_priority_indicator: h, pcr_flag: p, opcr_flag: l, splicing_point_flag: g, transport_private_data_flag: m, adaptation_field_extension_flag: y, pcr: n, opcr: i, splice_countdown: o, transport_private_data: a };
|
|
876
924
|
};
|
|
877
925
|
parseVideo = async (t) => {
|
|
878
926
|
const s = new DataView(t.buffer);
|
|
879
927
|
let e = 0, n, i;
|
|
880
928
|
{
|
|
881
|
-
const
|
|
882
|
-
if (e += 3, !
|
|
929
|
+
const r = s.getUint8(e) === 0 && s.getUint8(e + 1) === 0 && s.getUint8(e + 2) === 1;
|
|
930
|
+
if (e += 3, !r)
|
|
883
931
|
throw new Error("invalid ts video payload.");
|
|
884
|
-
const
|
|
932
|
+
const c = s.getUint8(e);
|
|
885
933
|
e += 1;
|
|
886
|
-
const
|
|
934
|
+
const o = s.getUint8(e) << 8 | s.getUint8(e + 1);
|
|
887
935
|
e += 2;
|
|
888
|
-
let d,
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
if (h) {
|
|
897
|
-
e += 1;
|
|
898
|
-
const p = s.getUint8(e);
|
|
936
|
+
let d, a, h, p, u;
|
|
937
|
+
{
|
|
938
|
+
const m = s.getUint8(e);
|
|
939
|
+
e += 1, d = m >> 4 & 3, a = (m >> 3 & 1) === 1, h = (m >> 2 & 1) === 1, p = (m >> 1 & 1) === 1, u = (m & 1) === 1;
|
|
940
|
+
}
|
|
941
|
+
let g, f;
|
|
942
|
+
{
|
|
943
|
+
const m = s.getUint8(e);
|
|
899
944
|
e += 1;
|
|
900
|
-
const
|
|
901
|
-
e += 1, (
|
|
945
|
+
const k = m >> 6, b = s.getUint8(e);
|
|
946
|
+
e += 1, (k & 2) === 2 && (g = this.parsePtsDts(s, e)), (k & 1) === 1 ? f = this.parsePtsDts(s, e + 5) : f = g, e += b;
|
|
902
947
|
}
|
|
903
|
-
n = { stream_id:
|
|
948
|
+
n = { stream_id: c, pes_packet_length: o, scrambling_control: d, priority: a, data_alignment: h, copyright: p, original_copy: u, pts: g, dts: f };
|
|
904
949
|
}
|
|
905
950
|
i = t.slice(e);
|
|
906
951
|
{
|
|
907
|
-
const
|
|
952
|
+
const r = this.getNalus(i);
|
|
908
953
|
if (!this.videoConfig) {
|
|
909
|
-
let
|
|
910
|
-
if (
|
|
911
|
-
const
|
|
912
|
-
this.videoConfig = { kind: "video", codec:
|
|
954
|
+
let u, g;
|
|
955
|
+
if (u = r.find((m) => m.type === 7)?.nalu.slice(4), g = r.find((m) => m.type === 8)?.nalu.slice(4), u && g) {
|
|
956
|
+
const f = q(u, g), { codec: m } = I(f);
|
|
957
|
+
this.videoConfig = { kind: "video", codec: m, description: f, sps: u, pps: g }, this.on.config && this.on.config(this.videoConfig);
|
|
913
958
|
}
|
|
914
959
|
}
|
|
915
|
-
const
|
|
916
|
-
let
|
|
917
|
-
for (const
|
|
918
|
-
const { type: g, nalu:
|
|
960
|
+
const c = [];
|
|
961
|
+
let o = "delta";
|
|
962
|
+
for (const u of r) {
|
|
963
|
+
const { type: g, nalu: f } = u;
|
|
919
964
|
switch (g) {
|
|
965
|
+
case 6:
|
|
966
|
+
// sei
|
|
920
967
|
case 9:
|
|
921
|
-
|
|
968
|
+
c.push(f);
|
|
922
969
|
break;
|
|
923
970
|
case 1:
|
|
924
|
-
|
|
971
|
+
o = "delta", c.push(f);
|
|
925
972
|
break;
|
|
926
973
|
case 5:
|
|
927
|
-
|
|
974
|
+
o = "key", c.push(f);
|
|
928
975
|
break;
|
|
929
976
|
}
|
|
930
977
|
}
|
|
931
|
-
const d = X(
|
|
932
|
-
return { kind: "video", type:
|
|
978
|
+
const d = X(c), { dts: a = 0, pts: h = 0 } = n, p = h - a;
|
|
979
|
+
return { kind: "video", type: o, dts: a, pts: h, cts: p, data: d, nalus: c };
|
|
933
980
|
}
|
|
934
981
|
};
|
|
935
982
|
/**
|
|
936
983
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
937
984
|
*/
|
|
938
985
|
parsePtsDts(t, s) {
|
|
939
|
-
const e = t.getUint8(s), n = t.getUint8(s + 1), i = t.getUint8(s + 2),
|
|
940
|
-
return Number(
|
|
986
|
+
const e = t.getUint8(s), n = t.getUint8(s + 1), i = t.getUint8(s + 2), r = t.getUint8(s + 3), c = t.getUint8(s + 4), o = (BigInt(e) & 0b00001110n) << 29n | (BigInt(n) & 0b11111111n) << 22n | (BigInt(i) & 0b11111110n) << 14n | (BigInt(r) & 0b11111111n) << 7n | (BigInt(c) & 0b11111110n) >> 1n;
|
|
987
|
+
return Number(o) / 90;
|
|
941
988
|
}
|
|
942
989
|
getNalus = (t) => {
|
|
943
990
|
const s = [];
|
|
@@ -957,16 +1004,16 @@ class Z {
|
|
|
957
1004
|
}
|
|
958
1005
|
break;
|
|
959
1006
|
}
|
|
960
|
-
let
|
|
961
|
-
if (t[e - 1] === 0 && (
|
|
962
|
-
const
|
|
963
|
-
s.push({ type: i, nalu:
|
|
1007
|
+
let r = e - n;
|
|
1008
|
+
if (t[e - 1] === 0 && (r -= 1), r !== 0) {
|
|
1009
|
+
const c = t.slice(n, n + r), o = K(c);
|
|
1010
|
+
s.push({ type: i, nalu: o });
|
|
964
1011
|
}
|
|
965
1012
|
}
|
|
966
1013
|
return s;
|
|
967
1014
|
};
|
|
968
1015
|
}
|
|
969
|
-
const _ = (
|
|
1016
|
+
const _ = (l, t) => l.getUint8(t) << 16 | l.getUint8(t + 1) << 8 | l.getUint8(t + 2);
|
|
970
1017
|
class tt {
|
|
971
1018
|
audioConfig;
|
|
972
1019
|
videoConfig;
|
|
@@ -979,53 +1026,53 @@ class tt {
|
|
|
979
1026
|
parse = async (t) => {
|
|
980
1027
|
let s = 0;
|
|
981
1028
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
982
|
-
const n = this.parseTagHeader(t, s + 4), { tagType: i, dataSize:
|
|
1029
|
+
const n = this.parseTagHeader(t, s + 4), { tagType: i, dataSize: r, timestamp: c } = n;
|
|
983
1030
|
if (i) {
|
|
984
|
-
const
|
|
1031
|
+
const o = this.parseTagBody(i, t, s + 4 + 11, r);
|
|
985
1032
|
switch (i) {
|
|
986
1033
|
case "script":
|
|
987
|
-
this.on.info && this.on.info(
|
|
1034
|
+
this.on.info && this.on.info(o);
|
|
988
1035
|
break;
|
|
989
1036
|
case "audio":
|
|
990
1037
|
{
|
|
991
|
-
const { accPacketType: d } =
|
|
1038
|
+
const { accPacketType: d } = o;
|
|
992
1039
|
if (d === 0) {
|
|
993
|
-
const { codec:
|
|
994
|
-
this.audioConfig = { kind: "audio", codec:
|
|
1040
|
+
const { codec: a, sampleRate: h, channelConfiguration: p } = o;
|
|
1041
|
+
this.audioConfig = { kind: "audio", codec: a, sampleRate: h, numberOfChannels: p }, this.on.config && this.on.config(this.audioConfig);
|
|
995
1042
|
} else {
|
|
996
|
-
const { cts:
|
|
997
|
-
this.on.chunk && this.on.chunk({ kind: "audio", type: p, dts:
|
|
1043
|
+
const { cts: a, data: h } = o, p = "key", u = a === void 0 ? void 0 : a + c;
|
|
1044
|
+
this.on.chunk && this.on.chunk({ kind: "audio", type: p, dts: c, pts: u, cts: a, data: h });
|
|
998
1045
|
}
|
|
999
1046
|
}
|
|
1000
1047
|
break;
|
|
1001
1048
|
case "video":
|
|
1002
1049
|
{
|
|
1003
|
-
const { avcPacketType: d } =
|
|
1050
|
+
const { avcPacketType: d } = o;
|
|
1004
1051
|
if (d === 0) {
|
|
1005
|
-
const { codec:
|
|
1006
|
-
this.videoConfig = { kind: "video", codec:
|
|
1052
|
+
const { codec: a, sps: h, pps: p, data: u } = o;
|
|
1053
|
+
this.videoConfig = { kind: "video", codec: a, description: u, sps: h, pps: p }, this.on.config && this.on.config(this.videoConfig);
|
|
1007
1054
|
} else {
|
|
1008
|
-
const { frameType:
|
|
1009
|
-
this.on.chunk && this.on.chunk({ kind: "video", type: g, dts:
|
|
1055
|
+
const { frameType: a, cts: h, data: p, nalus: u } = o, g = a === 1 ? "key" : "delta", f = h === void 0 ? void 0 : h + c;
|
|
1056
|
+
this.on.chunk && this.on.chunk({ kind: "video", type: g, dts: c, pts: f, cts: h, data: p, nalus: u });
|
|
1010
1057
|
}
|
|
1011
1058
|
}
|
|
1012
1059
|
break;
|
|
1013
1060
|
}
|
|
1014
|
-
s = s + 4 + 11 +
|
|
1061
|
+
s = s + 4 + 11 + r;
|
|
1015
1062
|
}
|
|
1016
|
-
await new Promise((
|
|
1063
|
+
await new Promise((o) => setTimeout(() => o(!0), 8));
|
|
1017
1064
|
}
|
|
1018
1065
|
return s;
|
|
1019
1066
|
};
|
|
1020
1067
|
// Header
|
|
1021
1068
|
parseHeader = (t, s) => {
|
|
1022
|
-
let e, n, i,
|
|
1069
|
+
let e, n, i, r;
|
|
1023
1070
|
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2), n = t.getUint8(3);
|
|
1024
1071
|
{
|
|
1025
|
-
const
|
|
1026
|
-
i = { audio:
|
|
1072
|
+
const o = t.getUint8(0).toString(2).padStart(5, "0").split(""), [, , d, , a] = o;
|
|
1073
|
+
i = { audio: a === "1", video: d === "1" };
|
|
1027
1074
|
}
|
|
1028
|
-
|
|
1075
|
+
r = t.getUint32(5), this.header = { signature: e, version: n, flags: i, dataOffset: r };
|
|
1029
1076
|
};
|
|
1030
1077
|
// 是否是完整tag
|
|
1031
1078
|
isSurplusTag = (t, s) => {
|
|
@@ -1042,11 +1089,11 @@ class tt {
|
|
|
1042
1089
|
return e;
|
|
1043
1090
|
};
|
|
1044
1091
|
parseTagHeader = (t, s) => {
|
|
1045
|
-
let e, n, i,
|
|
1092
|
+
let e, n, i, r, c;
|
|
1046
1093
|
{
|
|
1047
|
-
const
|
|
1094
|
+
const o = t.getUint8(s);
|
|
1048
1095
|
let d;
|
|
1049
|
-
switch (
|
|
1096
|
+
switch (o) {
|
|
1050
1097
|
case 18:
|
|
1051
1098
|
d = "script";
|
|
1052
1099
|
break;
|
|
@@ -1059,7 +1106,7 @@ class tt {
|
|
|
1059
1106
|
}
|
|
1060
1107
|
e = d;
|
|
1061
1108
|
}
|
|
1062
|
-
return n = _(t, s + 1), i = _(t, s + 4),
|
|
1109
|
+
return n = _(t, s + 1), i = _(t, s + 4), r = t.getUint8(s + 7), c = _(t, s + 8), { tagType: e, dataSize: n, timestamp: i, timestampExtended: r, streamID: c };
|
|
1063
1110
|
};
|
|
1064
1111
|
parseTagBody = (t, s, e, n) => {
|
|
1065
1112
|
let i;
|
|
@@ -1085,8 +1132,8 @@ class tt {
|
|
|
1085
1132
|
const n = t.getUint16(e, !1);
|
|
1086
1133
|
e = e + 2;
|
|
1087
1134
|
{
|
|
1088
|
-
const
|
|
1089
|
-
if ((this.textDecoder?.decode(
|
|
1135
|
+
const c = new Int8Array(t.buffer.slice(e, e + n));
|
|
1136
|
+
if ((this.textDecoder?.decode(c) || "") !== "onMetaData") throw new Error("Expected 'onMetaData' string");
|
|
1090
1137
|
e = e + n;
|
|
1091
1138
|
}
|
|
1092
1139
|
const i = this.getAmfType(t, e);
|
|
@@ -1094,44 +1141,44 @@ class tt {
|
|
|
1094
1141
|
};
|
|
1095
1142
|
parseAudio = (t, s, e) => {
|
|
1096
1143
|
let n = s;
|
|
1097
|
-
const i = t.getUint8(n),
|
|
1144
|
+
const i = t.getUint8(n), r = i >> 4 & 15, c = i >> 2 & 3, o = i >> 1 & 1, d = i & 1;
|
|
1098
1145
|
n = n + 1;
|
|
1099
|
-
const
|
|
1146
|
+
const a = t.getUint8(n);
|
|
1100
1147
|
n = n + 1;
|
|
1101
1148
|
const h = e - 2, p = new Uint8Array(t.buffer.slice(n, n + h));
|
|
1102
|
-
if (
|
|
1103
|
-
const
|
|
1104
|
-
return { soundFormat:
|
|
1149
|
+
if (r === 10 && a === 0) {
|
|
1150
|
+
const u = t.getUint8(n), g = t.getUint8(n + 1), f = (u & 248) >> 3, m = (u & 7) << 1 | g >> 7, k = (g & 120) >> 3, b = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350], U = `mp4a.40.${f}`, w = b[m];
|
|
1151
|
+
return { soundFormat: r, soundRate: c, soundSize: o, soundType: d, accPacketType: a, data: p, audioObjectType: f, samplingFrequencyIndex: m, channelConfiguration: k, codec: U, sampleRate: w };
|
|
1105
1152
|
}
|
|
1106
|
-
return { soundFormat:
|
|
1153
|
+
return { soundFormat: r, soundRate: c, soundSize: o, soundType: d, accPacketType: a, data: p };
|
|
1107
1154
|
};
|
|
1108
1155
|
parseVideo = (t, s, e) => {
|
|
1109
1156
|
let n = s;
|
|
1110
|
-
const i = t.getUint8(n),
|
|
1157
|
+
const i = t.getUint8(n), r = i >> 4 & 15, c = i & 15;
|
|
1111
1158
|
n = n + 1;
|
|
1112
|
-
const
|
|
1159
|
+
const o = t.getUint8(n);
|
|
1113
1160
|
n = n + 1;
|
|
1114
1161
|
const d = _(t, n);
|
|
1115
1162
|
n = n + 3;
|
|
1116
|
-
const
|
|
1117
|
-
switch (
|
|
1163
|
+
const a = e - 5, h = new Uint8Array(t.buffer.slice(n, n + a));
|
|
1164
|
+
switch (c) {
|
|
1118
1165
|
case 7:
|
|
1119
|
-
if (
|
|
1166
|
+
if (o === 0) {
|
|
1120
1167
|
const p = I(h);
|
|
1121
|
-
return { frameType:
|
|
1122
|
-
} else if (
|
|
1123
|
-
const p = [],
|
|
1124
|
-
for (; !(n + 4 >
|
|
1125
|
-
const g = t.getUint32(n, !1),
|
|
1126
|
-
n += 4 + g, p.push(
|
|
1168
|
+
return { frameType: r, codecID: c, avcPacketType: o, cts: d, data: h, ...p };
|
|
1169
|
+
} else if (o === 1) {
|
|
1170
|
+
const p = [], u = n + e - 5;
|
|
1171
|
+
for (; !(n + 4 > u); ) {
|
|
1172
|
+
const g = t.getUint32(n, !1), f = new Uint8Array(t.buffer.slice(n, n + 4 + g));
|
|
1173
|
+
n += 4 + g, p.push(f);
|
|
1127
1174
|
}
|
|
1128
|
-
return { frameType:
|
|
1175
|
+
return { frameType: r, codecID: c, avcPacketType: o, cts: d, data: h, nalus: p };
|
|
1129
1176
|
}
|
|
1130
1177
|
break;
|
|
1131
1178
|
default:
|
|
1132
1179
|
throw new Error("Unsupported codecID");
|
|
1133
1180
|
}
|
|
1134
|
-
return { frameType:
|
|
1181
|
+
return { frameType: r, codecID: c, avcPacketType: o, cts: d, data: h };
|
|
1135
1182
|
};
|
|
1136
1183
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1137
1184
|
getAMFName = (t, s, e) => {
|
|
@@ -1139,69 +1186,69 @@ class tt {
|
|
|
1139
1186
|
return this.textDecoder?.decode(n) || "";
|
|
1140
1187
|
};
|
|
1141
1188
|
getAMFValue = (t, s, e) => {
|
|
1142
|
-
let n = s, i,
|
|
1189
|
+
let n = s, i, r = 0;
|
|
1143
1190
|
switch (e) {
|
|
1144
1191
|
case 0:
|
|
1145
|
-
i = t.getFloat64(n, !1),
|
|
1192
|
+
i = t.getFloat64(n, !1), r = 8;
|
|
1146
1193
|
break;
|
|
1147
1194
|
case 1:
|
|
1148
|
-
i = !!t.getUint8(n),
|
|
1195
|
+
i = !!t.getUint8(n), r = 1;
|
|
1149
1196
|
break;
|
|
1150
1197
|
case 2:
|
|
1151
1198
|
{
|
|
1152
1199
|
i = "";
|
|
1153
|
-
const
|
|
1200
|
+
const o = t.getUint16(n, !1);
|
|
1154
1201
|
n = n + 2;
|
|
1155
|
-
const d = new Int8Array(t.buffer, n,
|
|
1156
|
-
i = (this.textDecoder?.decode(d) || "").trim(),
|
|
1202
|
+
const d = new Int8Array(t.buffer, n, o).filter((h) => h !== 0);
|
|
1203
|
+
i = (this.textDecoder?.decode(d) || "").trim(), r = 2 + o;
|
|
1157
1204
|
}
|
|
1158
1205
|
break;
|
|
1159
1206
|
case 3:
|
|
1160
1207
|
for (i = {}; n < t.byteLength; ) {
|
|
1161
|
-
const
|
|
1162
|
-
if (
|
|
1208
|
+
const o = t.getUint16(n, !1);
|
|
1209
|
+
if (o === 0) break;
|
|
1163
1210
|
n = n + 2;
|
|
1164
|
-
const d = this.getAMFName(t, n,
|
|
1165
|
-
n = n +
|
|
1166
|
-
const
|
|
1167
|
-
if (
|
|
1211
|
+
const d = this.getAMFName(t, n, o);
|
|
1212
|
+
n = n + o;
|
|
1213
|
+
const a = this.getAmfType(t, n);
|
|
1214
|
+
if (a === 6) break;
|
|
1168
1215
|
n = n + 1;
|
|
1169
|
-
const h = this.getAMFValue(t, n,
|
|
1170
|
-
n = n + h.length, i[d] = h.value,
|
|
1216
|
+
const h = this.getAMFValue(t, n, a);
|
|
1217
|
+
n = n + h.length, i[d] = h.value, r = 2 + o + 1 + h.length;
|
|
1171
1218
|
}
|
|
1172
1219
|
break;
|
|
1173
1220
|
case 8:
|
|
1174
1221
|
{
|
|
1175
1222
|
i = {};
|
|
1176
|
-
const
|
|
1223
|
+
const o = t.getUint32(n, !1);
|
|
1177
1224
|
n = n + 4;
|
|
1178
|
-
for (let d = 0; d <
|
|
1179
|
-
const
|
|
1225
|
+
for (let d = 0; d < o; d++) {
|
|
1226
|
+
const a = t.getUint16(n, !1);
|
|
1180
1227
|
n = n + 2;
|
|
1181
|
-
const h = this.getAMFName(t, n,
|
|
1182
|
-
n = n +
|
|
1228
|
+
const h = this.getAMFName(t, n, a);
|
|
1229
|
+
n = n + a;
|
|
1183
1230
|
const p = this.getAmfType(t, n);
|
|
1184
1231
|
n = n + 1;
|
|
1185
|
-
const
|
|
1186
|
-
n = n +
|
|
1232
|
+
const u = this.getAMFValue(t, n, p);
|
|
1233
|
+
n = n + u.length, i[h] = u.value, r = 2 + a + 1 + u.length;
|
|
1187
1234
|
}
|
|
1188
1235
|
}
|
|
1189
1236
|
break;
|
|
1190
1237
|
case 10:
|
|
1191
1238
|
{
|
|
1192
1239
|
i = [];
|
|
1193
|
-
const
|
|
1240
|
+
const o = t.getUint32(n, !1);
|
|
1194
1241
|
n = n + 4;
|
|
1195
|
-
for (let d = 0; d <
|
|
1196
|
-
const
|
|
1242
|
+
for (let d = 0; d < o; d++) {
|
|
1243
|
+
const a = this.getAmfType(t, n);
|
|
1197
1244
|
n = n + 1;
|
|
1198
|
-
const h = this.getAMFValue(t, n,
|
|
1199
|
-
n = n + h.length, i.push(h.value),
|
|
1245
|
+
const h = this.getAMFValue(t, n, a);
|
|
1246
|
+
n = n + h.length, i.push(h.value), r = 1 + h.length;
|
|
1200
1247
|
}
|
|
1201
1248
|
}
|
|
1202
1249
|
break;
|
|
1203
1250
|
}
|
|
1204
|
-
return { amfType: e, length:
|
|
1251
|
+
return { amfType: e, length: r, value: i };
|
|
1205
1252
|
};
|
|
1206
1253
|
}
|
|
1207
1254
|
class st {
|
|
@@ -1371,8 +1418,8 @@ class it {
|
|
|
1371
1418
|
if (!t) break;
|
|
1372
1419
|
let { timestamp: s, bitmap: e } = t;
|
|
1373
1420
|
if (this.cutOption) {
|
|
1374
|
-
const { sx: i = 0, sy:
|
|
1375
|
-
e = await createImageBitmap(e, i,
|
|
1421
|
+
const { sx: i = 0, sy: r = 0, sw: c = e.width, sh: o = e.height } = this.cutOption;
|
|
1422
|
+
e = await createImageBitmap(e, i, r, c, o);
|
|
1376
1423
|
}
|
|
1377
1424
|
const n = this.calculateTimeUntilNextFrame(s);
|
|
1378
1425
|
await new Promise((i) => setTimeout(() => i(!0), n)), this.drawImage({ timestamp: s, bitmap: e }), this.cutOption && e.close();
|
|
@@ -1393,8 +1440,8 @@ export {
|
|
|
1393
1440
|
nt as Decoder,
|
|
1394
1441
|
N as DecoderWorker,
|
|
1395
1442
|
st as Demuxer,
|
|
1396
|
-
|
|
1443
|
+
L as DemuxerWorker,
|
|
1397
1444
|
et as PrPlayer,
|
|
1398
1445
|
it as Render,
|
|
1399
|
-
|
|
1446
|
+
z as RenderWorker
|
|
1400
1447
|
};
|