pr-player 0.1.5 → 0.1.7
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 -293
- 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 6: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 l=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:l,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:h,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:l=[]}=this.pat||{};if(l.find(u=>u.pmt_pid===o))return this.parsePMT(t,e)}const{streams:g=[]}=this.pmt||{},p=g.find(l=>l.elementary_pid===o);if(p){if(h===1){const l=this.payloadMap.get(o);if(l){switch(p.kind){case"audio":{const d=await this.parseAudio(l);this.on.chunk&&this.on.chunk(d)}break;case"video":{const d=await this.parseVideo(l);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 l=this.payloadMap.get(o),d=new Uint8Array(l.byteLength+r.byteLength);d.set(l,0),d.set(r,l.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),h=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=(h&192)>>6,l=h>>4&3,d=h&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:l,continuity_counter:d}};parsePAT=(t,s)=>{let e=s,n;{const h=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 l=t.getUint8(e);e+=1;const d=t.getUint8(e);e+=1,n={pointer_field:h,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:l,last_section_number:d}}const a=[];{const h=n.section_length-5-4,i=e+h;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 h=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 l=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:h,table_id:i,section_length:c,transport_stream_id:r,version_number:g,current_next_indicator:p,section_number:l,last_section_number:d,pcr_pid:u,program_info_length:f}}const a=[];{const h=n.section_length-9-4,i=e+h;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,h;const i=t.getUint8(e),c=!!(i&128),r=!!(i&64),g=!!(i&32),p=!!(i&16),l=!!(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),l&&(a=U(t,e),e+=6),d&&(o=t.getInt8(e),e+=1),u){const _=t.getUint8(e);e+=1,h=new Uint8Array(t.buffer,e,_),e+=_}return{discontinuity_indicator:c,random_access_indicator:r,elementary_stream_priority_indicator:g,pcr_flag:p,opcr_flag:l,splicing_point_flag:d,transport_private_data_flag:u,adaptation_field_extension_flag:f,pcr:n,opcr:a,splice_countdown:o,transport_private_data:h}};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 h=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,l;{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,l=(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:h,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:l,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),l=(g&248)>>3&3,d=p>>6&3,u=48e3,f=`mp4a.40.${l}`,U=d===3?1:2;this.audioConfig={kind:"audio",codec:f,sampleRate:u,numberOfChannels:U},this.on.config&&this.on.config(this.audioConfig)}}const{dts:o=0,pts:h=0}=n,i=h-o,c=a.slice(7);return{kind:"audio",type:"key",dts:o,pts:h,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 h=s.getUint8(e);e+=1;const i=s.getUint8(e)<<8|s.getUint8(e+1);e+=2;let c,r,g,p,l;{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,l=(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:h,pes_packet_length:i,scrambling_control:c,priority:r,data_alignment:g,copyright:p,original_copy:l,pts:d,dts:u}}a=t.slice(e);{const o=this.getNalus(a);if(!this.videoConfig){let l,d;if(l=o.find(f=>f.type===7)?.nalu.slice(4),d=o.find(f=>f.type===8)?.nalu.slice(4),l&&d){const u=I(l,d),{codec:f}=T(u);this.videoConfig={kind:"video",codec:f,description:u,sps:l,pps:d},this.on.config&&this.on.config(this.videoConfig)}}const h=[];let i="delta";for(const l of o){const{type:d,nalu:u}=l;switch(d){case 6:case 9:h.push(u);break;case 1:i="delta",h.push(u);break;case 5:i="key",h.push(u);break}}const c=C(h),{dts:r=0,pts:g=0}=n,p=g-r;return{kind:"video",type:i,dts:r,pts:g,cts:p,data:c,nalus:h}}};parsePtsDts(t,s){const e=t.getUint8(s),n=t.getUint8(s+1),a=t.getUint8(s+2),o=t.getUint8(s+3),h=t.getUint8(s+4),i=(BigInt(e)&0b00001110n)<<29n|(BigInt(n)&0b11111111n)<<22n|(BigInt(a)&0b11111110n)<<14n|(BigInt(o)&0b11111111n)<<7n|(BigInt(h)&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 h=t.slice(n,n+o),i=M(h);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:h}=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",l=r===void 0?void 0:r+h;this.on.chunk&&this.on.chunk({kind:"audio",type:p,dts:h,pts:l,cts:r,data:g})}}break;case"video":{const{avcPacketType:c}=i;if(c===0){const{codec:r,sps:g,pps:p,data:l}=i;this.videoConfig={kind:"video",codec:r,description:l,sps:g,pps:p},this.on.config&&this.on.config(this.videoConfig)}else{const{frameType:r,cts:g,data:p,nalus:l}=i,d=r===1?"key":"delta",u=g===void 0?void 0:g+h;this.on.chunk&&this.on.chunk({kind:"video",type:d,dts:h,pts:u,cts:g,data:p,nalus:l})}}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,h;{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),h=k(t,s+8),{tagType:e,dataSize:n,timestamp:a,timestampExtended:o,streamID:h}};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 h=new Int8Array(t.buffer.slice(e,e+n));if((this.textDecoder?.decode(h)||"")!=="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,h=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 l=t.getUint8(n),d=t.getUint8(n+1),u=(l&248)>>3,f=(l&7)<<1|d>>7,U=(d&120)>>3,_=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],b=`mp4a.40.${u}`,m=_[f];return{soundFormat:o,soundRate:h,soundSize:i,soundType:c,accPacketType:r,data:p,audioObjectType:u,samplingFrequencyIndex:f,channelConfiguration:U,codec:b,sampleRate:m}}return{soundFormat:o,soundRate:h,soundSize:i,soundType:c,accPacketType:r,data:p}};parseVideo=(t,s,e)=>{let n=s;const a=t.getUint8(n),o=a>>4&15,h=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(h){case 7:if(i===0){const p=T(g);return{frameType:o,codecID:h,avcPacketType:i,cts:c,data:g,...p}}else if(i===1){const p=[],l=n+e-5;for(;!(n+4>l);){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:h,avcPacketType:i,cts:c,data:g,nalus:p}}break;default:throw new Error("Unsupported codecID")}return{frameType:o,codecID:h,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 l=this.getAMFValue(t,n,p);n=n+l.length,a[g]=l.value,o=2+r+1+l.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 R(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 R();
|
|
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":
|
|
@@ -543,27 +549,27 @@ class et {
|
|
|
543
549
|
break;
|
|
544
550
|
}
|
|
545
551
|
}, this.demuxerWorker.on.chunk = (s) => {
|
|
546
|
-
if (this.on.demuxer.chunk && this.on.demuxer.chunk(s), !this.decoderWorker) return;
|
|
552
|
+
if (this.on.demuxer.chunk && this.on.demuxer.chunk(s), console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->pr-player: chunk", s), !this.decoderWorker) return;
|
|
547
553
|
const { kind: e } = s;
|
|
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
|
}
|
|
@@ -578,7 +584,7 @@ class et {
|
|
|
578
584
|
this.decoderWorker = new N(), this.decoderWorker.on.audio.decode = (t) => {
|
|
579
585
|
this.audioPlayer?.push(t), this.on.decoder.audio && this.on.decoder.audio(t);
|
|
580
586
|
}, this.decoderWorker.on.audio.error = (t) => {
|
|
581
|
-
|
|
587
|
+
console.log("\x1B[38;2;0;151;255m%c%s\x1B[0m", "color:#0097ff;", "------->Breathe: e", t), this.on.error && this.on.error(t);
|
|
582
588
|
}, this.decoderWorker.on.video.decode = async (t) => {
|
|
583
589
|
this.renderWorker?.push(t);
|
|
584
590
|
const s = [...this.cutRenders.keys()];
|
|
@@ -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,162 +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
|
|
869
|
-
return
|
|
875
|
+
const k = (b, w) => {
|
|
876
|
+
let U = BigInt(0);
|
|
877
|
+
U |= BigInt(b.getUint16(w)) << 25n, U |= BigInt(b.getUint16(w + 1)) << 17n, U |= BigInt(b.getUint16(w + 2)) << 9n, U |= BigInt(b.getUint16(w + 3)) << 1n, U |= BigInt(b.getUint16(w + 4) >> 7);
|
|
878
|
+
const B = (b.getUint16(w + 4) & 1) << 8 | b.getUint16(w + 5);
|
|
879
|
+
return U = U * 300n + BigInt(B), U;
|
|
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 = (h & 248) >> 3 & 3, g = p >> 6 & 3, f = 48e3, m = `mp4a.40.${u}`, k = g === 3 ? 1 : 2;
|
|
918
|
+
this.audioConfig = { kind: "audio", codec: m, sampleRate: f, numberOfChannels: k }, 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 };
|
|
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) {
|
|
920
965
|
case 6:
|
|
921
966
|
// sei
|
|
922
967
|
case 9:
|
|
923
|
-
|
|
968
|
+
c.push(f);
|
|
924
969
|
break;
|
|
925
970
|
case 1:
|
|
926
|
-
|
|
971
|
+
o = "delta", c.push(f);
|
|
927
972
|
break;
|
|
928
973
|
case 5:
|
|
929
|
-
|
|
974
|
+
o = "key", c.push(f);
|
|
930
975
|
break;
|
|
931
976
|
}
|
|
932
977
|
}
|
|
933
|
-
const d = X(
|
|
934
|
-
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 };
|
|
935
980
|
}
|
|
936
981
|
};
|
|
937
982
|
/**
|
|
938
983
|
* 解析 PTS/DTS 时间戳(33-bit,单位:90kHz)
|
|
939
984
|
*/
|
|
940
985
|
parsePtsDts(t, s) {
|
|
941
|
-
const e = t.getUint8(s), n = t.getUint8(s + 1), i = t.getUint8(s + 2),
|
|
942
|
-
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;
|
|
943
988
|
}
|
|
944
989
|
getNalus = (t) => {
|
|
945
990
|
const s = [];
|
|
@@ -959,16 +1004,16 @@ class Z {
|
|
|
959
1004
|
}
|
|
960
1005
|
break;
|
|
961
1006
|
}
|
|
962
|
-
let
|
|
963
|
-
if (t[e - 1] === 0 && (
|
|
964
|
-
const
|
|
965
|
-
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 });
|
|
966
1011
|
}
|
|
967
1012
|
}
|
|
968
1013
|
return s;
|
|
969
1014
|
};
|
|
970
1015
|
}
|
|
971
|
-
const _ = (
|
|
1016
|
+
const _ = (l, t) => l.getUint8(t) << 16 | l.getUint8(t + 1) << 8 | l.getUint8(t + 2);
|
|
972
1017
|
class tt {
|
|
973
1018
|
audioConfig;
|
|
974
1019
|
videoConfig;
|
|
@@ -981,53 +1026,53 @@ class tt {
|
|
|
981
1026
|
parse = async (t) => {
|
|
982
1027
|
let s = 0;
|
|
983
1028
|
for (this.header || (this.parseHeader(t, s), s += 9); this.isSurplusTag(t, s) !== !1; ) {
|
|
984
|
-
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;
|
|
985
1030
|
if (i) {
|
|
986
|
-
const
|
|
1031
|
+
const o = this.parseTagBody(i, t, s + 4 + 11, r);
|
|
987
1032
|
switch (i) {
|
|
988
1033
|
case "script":
|
|
989
|
-
this.on.info && this.on.info(
|
|
1034
|
+
this.on.info && this.on.info(o);
|
|
990
1035
|
break;
|
|
991
1036
|
case "audio":
|
|
992
1037
|
{
|
|
993
|
-
const { accPacketType: d } =
|
|
1038
|
+
const { accPacketType: d } = o;
|
|
994
1039
|
if (d === 0) {
|
|
995
|
-
const { codec:
|
|
996
|
-
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);
|
|
997
1042
|
} else {
|
|
998
|
-
const { cts:
|
|
999
|
-
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 });
|
|
1000
1045
|
}
|
|
1001
1046
|
}
|
|
1002
1047
|
break;
|
|
1003
1048
|
case "video":
|
|
1004
1049
|
{
|
|
1005
|
-
const { avcPacketType: d } =
|
|
1050
|
+
const { avcPacketType: d } = o;
|
|
1006
1051
|
if (d === 0) {
|
|
1007
|
-
const { codec:
|
|
1008
|
-
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);
|
|
1009
1054
|
} else {
|
|
1010
|
-
const { frameType:
|
|
1011
|
-
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 });
|
|
1012
1057
|
}
|
|
1013
1058
|
}
|
|
1014
1059
|
break;
|
|
1015
1060
|
}
|
|
1016
|
-
s = s + 4 + 11 +
|
|
1061
|
+
s = s + 4 + 11 + r;
|
|
1017
1062
|
}
|
|
1018
|
-
await new Promise((
|
|
1063
|
+
await new Promise((o) => setTimeout(() => o(!0), 8));
|
|
1019
1064
|
}
|
|
1020
1065
|
return s;
|
|
1021
1066
|
};
|
|
1022
1067
|
// Header
|
|
1023
1068
|
parseHeader = (t, s) => {
|
|
1024
|
-
let e, n, i,
|
|
1069
|
+
let e, n, i, r;
|
|
1025
1070
|
e = t.getUint8(s) << 16 | t.getUint8(s + 1) << 8 | t.getUint8(s + 2), n = t.getUint8(3);
|
|
1026
1071
|
{
|
|
1027
|
-
const
|
|
1028
|
-
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" };
|
|
1029
1074
|
}
|
|
1030
|
-
|
|
1075
|
+
r = t.getUint32(5), this.header = { signature: e, version: n, flags: i, dataOffset: r };
|
|
1031
1076
|
};
|
|
1032
1077
|
// 是否是完整tag
|
|
1033
1078
|
isSurplusTag = (t, s) => {
|
|
@@ -1044,11 +1089,11 @@ class tt {
|
|
|
1044
1089
|
return e;
|
|
1045
1090
|
};
|
|
1046
1091
|
parseTagHeader = (t, s) => {
|
|
1047
|
-
let e, n, i,
|
|
1092
|
+
let e, n, i, r, c;
|
|
1048
1093
|
{
|
|
1049
|
-
const
|
|
1094
|
+
const o = t.getUint8(s);
|
|
1050
1095
|
let d;
|
|
1051
|
-
switch (
|
|
1096
|
+
switch (o) {
|
|
1052
1097
|
case 18:
|
|
1053
1098
|
d = "script";
|
|
1054
1099
|
break;
|
|
@@ -1061,7 +1106,7 @@ class tt {
|
|
|
1061
1106
|
}
|
|
1062
1107
|
e = d;
|
|
1063
1108
|
}
|
|
1064
|
-
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 };
|
|
1065
1110
|
};
|
|
1066
1111
|
parseTagBody = (t, s, e, n) => {
|
|
1067
1112
|
let i;
|
|
@@ -1087,8 +1132,8 @@ class tt {
|
|
|
1087
1132
|
const n = t.getUint16(e, !1);
|
|
1088
1133
|
e = e + 2;
|
|
1089
1134
|
{
|
|
1090
|
-
const
|
|
1091
|
-
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");
|
|
1092
1137
|
e = e + n;
|
|
1093
1138
|
}
|
|
1094
1139
|
const i = this.getAmfType(t, e);
|
|
@@ -1096,44 +1141,44 @@ class tt {
|
|
|
1096
1141
|
};
|
|
1097
1142
|
parseAudio = (t, s, e) => {
|
|
1098
1143
|
let n = s;
|
|
1099
|
-
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;
|
|
1100
1145
|
n = n + 1;
|
|
1101
|
-
const
|
|
1146
|
+
const a = t.getUint8(n);
|
|
1102
1147
|
n = n + 1;
|
|
1103
1148
|
const h = e - 2, p = new Uint8Array(t.buffer.slice(n, n + h));
|
|
1104
|
-
if (
|
|
1105
|
-
const
|
|
1106
|
-
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], w = `mp4a.40.${f}`, U = b[m];
|
|
1151
|
+
return { soundFormat: r, soundRate: c, soundSize: o, soundType: d, accPacketType: a, data: p, audioObjectType: f, samplingFrequencyIndex: m, channelConfiguration: k, codec: w, sampleRate: U };
|
|
1107
1152
|
}
|
|
1108
|
-
return { soundFormat:
|
|
1153
|
+
return { soundFormat: r, soundRate: c, soundSize: o, soundType: d, accPacketType: a, data: p };
|
|
1109
1154
|
};
|
|
1110
1155
|
parseVideo = (t, s, e) => {
|
|
1111
1156
|
let n = s;
|
|
1112
|
-
const i = t.getUint8(n),
|
|
1157
|
+
const i = t.getUint8(n), r = i >> 4 & 15, c = i & 15;
|
|
1113
1158
|
n = n + 1;
|
|
1114
|
-
const
|
|
1159
|
+
const o = t.getUint8(n);
|
|
1115
1160
|
n = n + 1;
|
|
1116
1161
|
const d = _(t, n);
|
|
1117
1162
|
n = n + 3;
|
|
1118
|
-
const
|
|
1119
|
-
switch (
|
|
1163
|
+
const a = e - 5, h = new Uint8Array(t.buffer.slice(n, n + a));
|
|
1164
|
+
switch (c) {
|
|
1120
1165
|
case 7:
|
|
1121
|
-
if (
|
|
1166
|
+
if (o === 0) {
|
|
1122
1167
|
const p = I(h);
|
|
1123
|
-
return { frameType:
|
|
1124
|
-
} else if (
|
|
1125
|
-
const p = [],
|
|
1126
|
-
for (; !(n + 4 >
|
|
1127
|
-
const g = t.getUint32(n, !1),
|
|
1128
|
-
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);
|
|
1129
1174
|
}
|
|
1130
|
-
return { frameType:
|
|
1175
|
+
return { frameType: r, codecID: c, avcPacketType: o, cts: d, data: h, nalus: p };
|
|
1131
1176
|
}
|
|
1132
1177
|
break;
|
|
1133
1178
|
default:
|
|
1134
1179
|
throw new Error("Unsupported codecID");
|
|
1135
1180
|
}
|
|
1136
|
-
return { frameType:
|
|
1181
|
+
return { frameType: r, codecID: c, avcPacketType: o, cts: d, data: h };
|
|
1137
1182
|
};
|
|
1138
1183
|
getAmfType = (t, s) => t.getUint8(s);
|
|
1139
1184
|
getAMFName = (t, s, e) => {
|
|
@@ -1141,69 +1186,69 @@ class tt {
|
|
|
1141
1186
|
return this.textDecoder?.decode(n) || "";
|
|
1142
1187
|
};
|
|
1143
1188
|
getAMFValue = (t, s, e) => {
|
|
1144
|
-
let n = s, i,
|
|
1189
|
+
let n = s, i, r = 0;
|
|
1145
1190
|
switch (e) {
|
|
1146
1191
|
case 0:
|
|
1147
|
-
i = t.getFloat64(n, !1),
|
|
1192
|
+
i = t.getFloat64(n, !1), r = 8;
|
|
1148
1193
|
break;
|
|
1149
1194
|
case 1:
|
|
1150
|
-
i = !!t.getUint8(n),
|
|
1195
|
+
i = !!t.getUint8(n), r = 1;
|
|
1151
1196
|
break;
|
|
1152
1197
|
case 2:
|
|
1153
1198
|
{
|
|
1154
1199
|
i = "";
|
|
1155
|
-
const
|
|
1200
|
+
const o = t.getUint16(n, !1);
|
|
1156
1201
|
n = n + 2;
|
|
1157
|
-
const d = new Int8Array(t.buffer, n,
|
|
1158
|
-
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;
|
|
1159
1204
|
}
|
|
1160
1205
|
break;
|
|
1161
1206
|
case 3:
|
|
1162
1207
|
for (i = {}; n < t.byteLength; ) {
|
|
1163
|
-
const
|
|
1164
|
-
if (
|
|
1208
|
+
const o = t.getUint16(n, !1);
|
|
1209
|
+
if (o === 0) break;
|
|
1165
1210
|
n = n + 2;
|
|
1166
|
-
const d = this.getAMFName(t, n,
|
|
1167
|
-
n = n +
|
|
1168
|
-
const
|
|
1169
|
-
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;
|
|
1170
1215
|
n = n + 1;
|
|
1171
|
-
const h = this.getAMFValue(t, n,
|
|
1172
|
-
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;
|
|
1173
1218
|
}
|
|
1174
1219
|
break;
|
|
1175
1220
|
case 8:
|
|
1176
1221
|
{
|
|
1177
1222
|
i = {};
|
|
1178
|
-
const
|
|
1223
|
+
const o = t.getUint32(n, !1);
|
|
1179
1224
|
n = n + 4;
|
|
1180
|
-
for (let d = 0; d <
|
|
1181
|
-
const
|
|
1225
|
+
for (let d = 0; d < o; d++) {
|
|
1226
|
+
const a = t.getUint16(n, !1);
|
|
1182
1227
|
n = n + 2;
|
|
1183
|
-
const h = this.getAMFName(t, n,
|
|
1184
|
-
n = n +
|
|
1228
|
+
const h = this.getAMFName(t, n, a);
|
|
1229
|
+
n = n + a;
|
|
1185
1230
|
const p = this.getAmfType(t, n);
|
|
1186
1231
|
n = n + 1;
|
|
1187
|
-
const
|
|
1188
|
-
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;
|
|
1189
1234
|
}
|
|
1190
1235
|
}
|
|
1191
1236
|
break;
|
|
1192
1237
|
case 10:
|
|
1193
1238
|
{
|
|
1194
1239
|
i = [];
|
|
1195
|
-
const
|
|
1240
|
+
const o = t.getUint32(n, !1);
|
|
1196
1241
|
n = n + 4;
|
|
1197
|
-
for (let d = 0; d <
|
|
1198
|
-
const
|
|
1242
|
+
for (let d = 0; d < o; d++) {
|
|
1243
|
+
const a = this.getAmfType(t, n);
|
|
1199
1244
|
n = n + 1;
|
|
1200
|
-
const h = this.getAMFValue(t, n,
|
|
1201
|
-
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;
|
|
1202
1247
|
}
|
|
1203
1248
|
}
|
|
1204
1249
|
break;
|
|
1205
1250
|
}
|
|
1206
|
-
return { amfType: e, length:
|
|
1251
|
+
return { amfType: e, length: r, value: i };
|
|
1207
1252
|
};
|
|
1208
1253
|
}
|
|
1209
1254
|
class st {
|
|
@@ -1373,8 +1418,8 @@ class it {
|
|
|
1373
1418
|
if (!t) break;
|
|
1374
1419
|
let { timestamp: s, bitmap: e } = t;
|
|
1375
1420
|
if (this.cutOption) {
|
|
1376
|
-
const { sx: i = 0, sy:
|
|
1377
|
-
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);
|
|
1378
1423
|
}
|
|
1379
1424
|
const n = this.calculateTimeUntilNextFrame(s);
|
|
1380
1425
|
await new Promise((i) => setTimeout(() => i(!0), n)), this.drawImage({ timestamp: s, bitmap: e }), this.cutOption && e.close();
|
|
@@ -1395,8 +1440,8 @@ export {
|
|
|
1395
1440
|
nt as Decoder,
|
|
1396
1441
|
N as DecoderWorker,
|
|
1397
1442
|
st as Demuxer,
|
|
1398
|
-
|
|
1443
|
+
L as DemuxerWorker,
|
|
1399
1444
|
et as PrPlayer,
|
|
1400
1445
|
it as Render,
|
|
1401
|
-
|
|
1446
|
+
z as RenderWorker
|
|
1402
1447
|
};
|