|  |  | 
 |  |  |     console.log(RTCRtpReceiver.getCapabilities('video').codecs) | 
 |  |  |     console.log(RTCRtpReceiver.getCapabilities('audio').codecs) | 
 |  |  |     //whep操作方法 | 
 |  |  |     const restartPause = 2000; | 
 |  |  |     const unquoteCredential = (v) => ( | 
 |  |  |         JSON.parse(`"${v}"`) | 
 |  |  |     ); | 
 |  |  |     const linkToIceServers = (links) => ( | 
 |  |  |         (links !== null) ? links.split(', ').map((link) => { | 
 |  |  |             const m = link.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i); | 
 |  |  | 
 |  |  |                     if (res.status !== 201) { | 
 |  |  |                         throw new Error('bad status code'); | 
 |  |  |                     } | 
 |  |  |                    // this.eTag = res.headers.get('ETag'); | 
 |  |  |                     // this.eTag = res.headers.get('ETag'); | 
 |  |  |                     this.eTag = res.headers.get("ETag") || res.headers.get('E-Tag'); | 
 |  |  |                     return res.text(); | 
 |  |  |                 }) | 
 |  |  | 
 |  |  |                     'Content-Type': 'application/trickle-ice-sdpfrag', | 
 |  |  |                     'If-Match': this.eTag, | 
 |  |  |                 }, | 
 |  |  |  | 
 |  |  |                 body: generateSdpFragment(this.offerData, candidates), | 
 |  |  |             }) | 
 |  |  |                 .then((res) => { |