iscream-webrtc-sdk
Version:
I-scream WebRTC SDK for browser - LiveKit based real-time communication with teacher/student roles
2 lines (1 loc) • 49.3 kB
JavaScript
var s=(g,e,t)=>new Promise((i,r)=>{var a=c=>{try{o(t.next(c))}catch(l){r(l)}},n=c=>{try{o(t.throw(c))}catch(l){r(l)}},o=c=>c.done?i(c.value):Promise.resolve(c.value).then(a,n);o((t=t.apply(g,e)).next())});import{Room as v,RoomEvent as u,Track as m}from"livekit-client";var P=class{constructor(e=!1){this.currentPresenter=null;this.room=null;this.userRole=null;this.localIdentity=null;this.debug=!1;this.debug=e}setRoom(e,t,i){this.room=e,this.userRole=t,this.localIdentity=i}getCurrentPresenter(){return this.currentPresenter}isPresenter(e){return this.currentPresenter===e}setPresenter(e,t){return s(this,null,function*(){if(!this.room||this.userRole!=="teacher")throw new Error("\uC120\uC0DD\uB2D8\uB9CC \uBC1C\uD45C\uC790\uB97C \uC9C0\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");let i=t.find(n=>n.identity===e);if(!i)throw new Error("\uCC38\uAC00\uC790\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");if(i.role!=="student")throw new Error("\uD559\uC0DD\uB9CC \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");let r=this.currentPresenter;if(r&&r!==e){this.debug&&console.log(`\u{1F504} \uAE30\uC874 \uBC1C\uD45C\uC790 ${r} \uC790\uB3D9 \uD574\uC81C`);let n={type:"presenter_cleared",previousPresenter:r,timestamp:Date.now()};yield this.sendDataMessage(n)}this.currentPresenter=e;let a={type:"presenter_assigned",presenterIdentity:e,timestamp:Date.now()};yield this.sendDataMessage(a),this.debug&&console.log(`\u2705 \uBC1C\uD45C\uC790 \uC9C0\uC815 \uC644\uB8CC: ${e} (\uC774\uC804: ${r||"\uC5C6\uC74C"})`)})}clearPresenter(){return s(this,null,function*(){if(!this.room||this.userRole!=="teacher")throw new Error("\uC120\uC0DD\uB2D8\uB9CC \uBC1C\uD45C\uC790\uB97C \uD574\uC81C\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");let e=this.currentPresenter;if(!e)return this.debug&&console.log("\uD604\uC7AC \uBC1C\uD45C\uC790\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."),null;let t={type:"presenter_cleared",previousPresenter:e,timestamp:Date.now()};return yield this.sendDataMessage(t),this.currentPresenter=null,this.debug&&console.log(`\u2705 \uBC1C\uD45C\uC790 \uD574\uC81C \uC644\uB8CC: ${e}`),e})}handlePresenterMessage(e,t){if(e.type==="presenter_assigned"){let i=this.currentPresenter,r=i===this.localIdentity;return this.currentPresenter=e.presenterIdentity||null,this.debug&&console.log("\u{1F468}\u200D\u{1F3EB} \uBC1C\uD45C\uC790 \uC9C0\uC815\uB428:",e.presenterIdentity,"(\uC774\uC804:",i,")"),t.forEach(a=>{a.isPresenter=a.identity===e.presenterIdentity}),{action:"assigned",presenterIdentity:e.presenterIdentity||null,previousPresenter:i,isMe:e.presenterIdentity===this.localIdentity}}else{if(e.type==="presenter_sync")return this.currentPresenter=e.presenterIdentity||null,this.debug&&console.log("\u{1F504} \uBC1C\uD45C\uC790 \uC815\uBCF4 \uB3D9\uAE30\uD654:",e.presenterIdentity),t.forEach(i=>{i.isPresenter=i.identity===e.presenterIdentity}),{action:"synced",presenterIdentity:e.presenterIdentity||null,previousPresenter:null,isMe:e.presenterIdentity===this.localIdentity};if(e.type==="presenter_cleared"){let i=this.currentPresenter===this.localIdentity;return this.currentPresenter=null,this.debug&&console.log("\u{1F468}\u200D\u{1F3EB} \uBC1C\uD45C\uC790 \uD574\uC81C\uB428:",e.previousPresenter),t.forEach(r=>{r.isPresenter=!1}),{action:"cleared",presenterIdentity:null,previousPresenter:e.previousPresenter||null,isMe:i}}}return null}handleTeacherChange(e){return s(this,null,function*(){if(this.currentPresenter){this.debug&&console.log(`\u{1F6A8} \uC120\uC0DD\uB2D8 ${e==="joined"?"\uC785\uC7A5":"\uD1F4\uC7A5"} - \uBC1C\uD45C\uC790 \uC790\uB3D9 \uD574\uC81C`);let t={type:"presenter_cleared",previousPresenter:this.currentPresenter,timestamp:Date.now(),reason:e==="joined"?"teacher_joined":"teacher_left"};this.currentPresenter=null,this.room&&(yield this.sendDataMessage(t))}})}sendDataMessage(e){return s(this,null,function*(){if(!this.room)return;let i=new TextEncoder().encode(JSON.stringify(e));try{yield this.room.localParticipant.publishData(i,{reliable:!0})}catch(r){throw console.error("\uB370\uC774\uD130 \uBA54\uC2DC\uC9C0 \uC804\uC1A1 \uC2E4\uD328:",r),r}})}syncPresenterForNewParticipant(){return s(this,null,function*(){this.userRole==="teacher"&&this.currentPresenter&&this.room&&setTimeout(()=>s(this,null,function*(){let e={type:"presenter_sync",presenterIdentity:this.currentPresenter,timestamp:Date.now()};this.debug&&console.log("\u{1F4E2} \uC0C8 \uCC38\uAC00\uC790\uC5D0\uAC8C \uBC1C\uD45C\uC790 \uC815\uBCF4 \uC804\uC1A1:",this.currentPresenter),yield this.sendDataMessage(e)}),500)})}canPublishMedia(e,t){return e==="teacher"||e==="student"&&t===this.currentPresenter}shouldShowParticipantVideo(e,t,i){return t==="teacher"?(this.debug&&console.log(`\u{1F6AB} \uC120\uC0DD\uB2D8\uC740 \uB2E4\uB978 \uCC38\uAC00\uC790 \uBE44\uB514\uC624 \uD45C\uC2DC \uC548 \uD568: ${e.identity}`),!1):t==="student"?i==="teacher"?(this.debug&&console.log(`\u2705 \uD559\uC0DD\uC774 \uC120\uC0DD\uB2D8 \uBE44\uB514\uC624 \uD45C\uC2DC: ${e.identity}`),!0):e.identity===this.currentPresenter?(this.debug&&console.log(`\u2705 \uD559\uC0DD\uC774 \uBC1C\uD45C\uC790 \uBE44\uB514\uC624 \uD45C\uC2DC: ${e.identity}`),!0):(this.debug&&console.log(`\u{1F6AB} \uD559\uC0DD\uC774 \uC77C\uBC18 \uD559\uC0DD \uBE44\uB514\uC624 \uC81C\uC678: ${e.identity}`),!1):!1}};import{Track as d}from"livekit-client";var f={low:{width:640,height:360,frameRate:15,bitrate:4e5},medium:{width:854,height:480,frameRate:25,bitrate:8e5},high:{width:1280,height:720,frameRate:30,bitrate:15e5},ultra:{width:1920,height:1080,frameRate:30,bitrate:3e6},auto:{adaptive:!0}},S={low:{sampleRate:16e3,bitrate:32e3},medium:{sampleRate:44100,bitrate:64e3},high:{sampleRate:48e3,bitrate:128e3}};var b=class{constructor(e=!1){this.room=null;this.userRole=null;this.canPublishMedia=!1;this.isScreenSharing=!1;this.currentVideoQuality="high";this.currentAudioQuality="high";this.selectedAudioInputId=null;this.selectedAudioOutputId=null;this.debug=!1;this.debug=e}setRoom(e,t,i){this.room=e,this.userRole=t,this.canPublishMedia=i}updatePublishPermission(e){this.canPublishMedia=e}canPublishMediaStream(){return this.canPublishMedia}toggleCamera(){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(!this.canPublishMediaStream())throw new Error("\uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC120\uC0DD\uB2D8\uC774\uAC70\uB098 \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.");try{let e=this.room.localParticipant,t=e.isCameraEnabled;this.debug&&console.log("\u{1F50D} \uD604\uC7AC \uCE74\uBA54\uB77C \uC0C1\uD0DC:",{isCameraEnabled:t,videoTracksSize:e.videoTrackPublications.size});let i=e.getTrackPublication(d.Source.Camera);if(this.debug&&console.log("\u{1F50D} Track Publication \uBC29\uC2DD \uCE74\uBA54\uB77C \uC0C1\uD0DC:",{hasPublication:!!i,hasTrack:!!(i!=null&&i.track),isCameraEnabled:t}),t){let a=e.getTrackPublication(d.Source.Camera);if(a&&a.track){let n=a.track;yield e.unpublishTrack(n),n&&typeof n.stop=="function"&&(n.stop(),this.debug&&console.log("\u{1F6D1} \uCE74\uBA54\uB77C LocalVideoTrack \uC911\uC9C0\uB428"));try{let o=n.mediaStreamTrack||n._mediaStreamTrack;o&&typeof o.stop=="function"&&(o.stop(),this.debug&&console.log("\u{1F6D1} \uB0B4\uBD80 MediaStreamTrack\uB3C4 \uC911\uC9C0\uB428"))}catch(o){this.debug&&console.error("\uB0B4\uBD80 MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",o)}}}else{let a=e.getTrackPublication(d.Source.Camera);if(a&&a.track)return console.log("\u{1F4F9} \uCE74\uBA54\uB77C\uAC00 \uC774\uBBF8 \uD65C\uC131\uD654\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."),!0;let o=(yield navigator.mediaDevices.getUserMedia({video:!0,audio:!1})).getVideoTracks()[0];o&&(yield e.publishTrack(o,{name:"camera",source:d.Source.Camera}))}let r=e.isCameraEnabled;return this.debug&&console.log(`\u{1F4F9} \uCE74\uBA54\uB77C ${r?"\uCF1C\uC9D0":"\uAEBC\uC9D0"}`),r}catch(e){throw console.error("\uCE74\uBA54\uB77C \uD1A0\uAE00 \uC2E4\uD328:",e),e}})}toggleMicrophone(){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(!this.canPublishMediaStream())throw new Error("\uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC120\uC0DD\uB2D8\uC774\uAC70\uB098 \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.");try{let e=this.room.localParticipant,t=e.isMicrophoneEnabled;if(this.debug&&console.log("\u{1F50D} \uD604\uC7AC \uB9C8\uC774\uD06C \uC0C1\uD0DC:",{isMicrophoneEnabled:t,audioTracksSize:e.audioTrackPublications.size}),t){let r=e.getTrackPublication(d.Source.Microphone);if(r&&r.track){let a=r.track;yield e.unpublishTrack(a),a&&typeof a.stop=="function"&&(a.stop(),this.debug&&console.log("\u{1F6D1} \uB9C8\uC774\uD06C LocalAudioTrack \uC911\uC9C0\uB428"));try{let n=a.mediaStreamTrack||a._mediaStreamTrack;n&&typeof n.stop=="function"&&(n.stop(),this.debug&&console.log("\u{1F6D1} \uB0B4\uBD80 MediaStreamTrack\uB3C4 \uC911\uC9C0\uB428"))}catch(n){this.debug&&console.error("\uB0B4\uBD80 MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",n)}}}else{let r=e.getTrackPublication(d.Source.Microphone);if(r&&r.track)return console.log("\u{1F3A4} \uB9C8\uC774\uD06C\uAC00 \uC774\uBBF8 \uD65C\uC131\uD654\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."),!0;let n=(yield navigator.mediaDevices.getUserMedia({video:!1,audio:!0})).getAudioTracks()[0];n&&(yield e.publishTrack(n,{name:"microphone",source:d.Source.Microphone}))}let i=e.isMicrophoneEnabled;return this.debug&&console.log(`\u{1F3A4} \uB9C8\uC774\uD06C ${i?"\uCF1C\uC9D0":"\uAEBC\uC9D0"}`),i}catch(e){throw console.error("\uB9C8\uC774\uD06C \uD1A0\uAE00 \uC2E4\uD328:",e),e}})}enableVideo(e){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(e&&!this.canPublishMediaStream())throw new Error("\uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC120\uC0DD\uB2D8\uC774\uAC70\uB098 \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.");try{let t=this.room.localParticipant;if(e){let i=t.getTrackPublication(d.Source.Camera);if(i&&i.track)return console.log("\u{1F4F9} \uCE74\uBA54\uB77C\uAC00 \uC774\uBBF8 \uD65C\uC131\uD654\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."),!0;let r=!0;if(this.currentVideoQuality&&this.currentVideoQuality!=="auto"){let o=f[this.currentVideoQuality];o&&(r={width:{ideal:o.width},height:{ideal:o.height},frameRate:{ideal:o.frameRate}})}let n=(yield navigator.mediaDevices.getUserMedia({video:r,audio:!1})).getVideoTracks()[0];if(n){let o;if(this.currentVideoQuality&&this.currentVideoQuality!=="auto"){let h=f[this.currentVideoQuality];h&&(o={maxBitrate:h.bitrate,maxFramerate:h.frameRate})}let c={name:"camera",source:d.Source.Camera};o&&(c.videoEncoding=o);let l=yield t.publishTrack(n,c);l&&l.track&&setTimeout(()=>{let h=document.getElementById("localVideo");h&&!h.srcObject&&l.track&&(l.track.attach(h),this.debug&&console.log("\u2705 \uB85C\uCEEC \uBE44\uB514\uC624 \uD2B8\uB799 \uC9C1\uC811 \uC5F0\uACB0 \uC131\uACF5"))},100)}}else{let i=t.getTrackPublication(d.Source.Camera);if(i&&i.track){let r=i.track;yield t.unpublishTrack(r),r&&typeof r.stop=="function"&&(r.stop(),this.debug&&console.log("\u{1F6D1} \uCE74\uBA54\uB77C LocalVideoTrack \uC911\uC9C0\uB428 (enableVideo)"));try{let a=r.mediaStreamTrack||r._mediaStreamTrack;a&&typeof a.stop=="function"&&(a.stop(),this.debug&&console.log("\u{1F6D1} \uB0B4\uBD80 MediaStreamTrack\uB3C4 \uC911\uC9C0\uB428 (enableVideo)"))}catch(a){this.debug&&console.error("\uB0B4\uBD80 MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",a)}}}return e}catch(t){throw console.error("\uCE74\uBA54\uB77C \uC81C\uC5B4 \uC2E4\uD328:",t),t}})}enableAudio(e){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(e&&!this.canPublishMediaStream())throw new Error("\uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC120\uC0DD\uB2D8\uC774\uAC70\uB098 \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.");try{let t=this.room.localParticipant;if(e){let i=t.getTrackPublication(d.Source.Microphone);if(i&&i.track)return console.log("\u{1F3A4} \uB9C8\uC774\uD06C\uAC00 \uC774\uBBF8 \uD65C\uC131\uD654\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."),!0;let a=(yield navigator.mediaDevices.getUserMedia({video:!1,audio:!0})).getAudioTracks()[0];if(a){let n=yield t.publishTrack(a,{name:"microphone",source:d.Source.Microphone})}}else{let i=t.getTrackPublication(d.Source.Microphone);if(i&&i.track){let r=i.track;yield t.unpublishTrack(r),r&&typeof r.stop=="function"&&(r.stop(),this.debug&&console.log("\u{1F6D1} \uB9C8\uC774\uD06C LocalAudioTrack \uC911\uC9C0\uB428 (enableAudio)"));try{let a=r.mediaStreamTrack||r._mediaStreamTrack;a&&typeof a.stop=="function"&&(a.stop(),this.debug&&console.log("\u{1F6D1} \uB0B4\uBD80 MediaStreamTrack\uB3C4 \uC911\uC9C0\uB428 (enableAudio)"))}catch(a){this.debug&&console.error("\uB0B4\uBD80 MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",a)}}}return e}catch(t){throw console.error("\uB9C8\uC774\uD06C \uC81C\uC5B4 \uC2E4\uD328:",t),t}})}startScreenShare(){return s(this,null,function*(){var e;if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(!this.canPublishMediaStream())throw new Error("\uD654\uBA74 \uACF5\uC720 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC120\uC0DD\uB2D8\uC774\uAC70\uB098 \uBC1C\uD45C\uC790\uB85C \uC9C0\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.");if(this.isScreenSharing)return this.debug&&console.log("\u{1F5A5}\uFE0F \uC774\uBBF8 \uD654\uBA74 \uACF5\uC720 \uC911\uC785\uB2C8\uB2E4"),!1;try{return yield this.room.localParticipant.setScreenShareEnabled(!0),this.isScreenSharing=!0,this.debug&&console.log("\u{1F5A5}\uFE0F \uD654\uBA74 \uACF5\uC720 \uC2DC\uC791"),!0}catch(t){if((e=t.message)!=null&&e.includes("Permission denied")||t.name==="NotAllowedError")return this.debug&&console.log("\u274C \uC0AC\uC6A9\uC790\uAC00 \uD654\uBA74 \uACF5\uC720\uB97C \uCDE8\uC18C\uD588\uC2B5\uB2C8\uB2E4"),!1;throw console.error("\uD654\uBA74 \uACF5\uC720 \uC2DC\uC791 \uC2E4\uD328:",t),t}})}stopScreenShare(){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");try{if(yield this.room.localParticipant.setScreenShareEnabled(!1),this.isScreenSharing=!1,this.debug&&console.log("\u{1F5A5}\uFE0F \uD654\uBA74 \uACF5\uC720 \uC911\uC9C0"),this.canPublishMediaStream()&&!this.room.localParticipant.isCameraEnabled)try{let e=!0;if(this.currentVideoQuality&&this.currentVideoQuality!=="auto"){let r=f[this.currentVideoQuality];r&&(e={width:{ideal:r.width},height:{ideal:r.height},frameRate:{ideal:r.frameRate}})}let i=(yield navigator.mediaDevices.getUserMedia({video:e,audio:!1})).getVideoTracks()[0];if(i){let r=yield this.room.localParticipant.publishTrack(i,{name:"camera",source:d.Source.Camera});r&&r.track&&setTimeout(()=>{let a=document.getElementById("localVideo");a&&!a.srcObject&&r.track&&(r.track.attach(a),this.debug&&console.log("\u2705 \uD654\uBA74 \uACF5\uC720 \uC911\uC9C0 \uD6C4 \uCE74\uBA54\uB77C \uD2B8\uB799 \uB2E4\uC2DC \uC5F0\uACB0\uB428"))},100),this.debug&&console.log("\u2705 \uD654\uBA74 \uACF5\uC720 \uC911\uC9C0 \uD6C4 \uCE74\uBA54\uB77C \uB2E4\uC2DC \uCF1C\uC9D0")}}catch(e){console.warn("\u26A0\uFE0F \uCE74\uBA54\uB77C \uB2E4\uC2DC \uCF1C\uAE30 \uC2E4\uD328:",e)}}catch(e){throw console.error("\uD654\uBA74 \uACF5\uC720 \uC911\uC9C0 \uC2E4\uD328:",e),e}})}setVideoQuality(e,t,i=!1){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uB8F8\uC5D0 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(!i&&this.userRole!=="teacher"&&!t)throw new Error("\uD654\uC9C8 \uC124\uC815 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");let r=f;if(!r[e])throw new Error(`\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD654\uC9C8: ${e}. \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uAC12: ${Object.keys(r).join(", ")}`);try{let a=r[e];if("adaptive"in a&&a.adaptive)this.currentVideoQuality="auto",this.debug&&console.log("\u{1F3A5} \uC790\uB3D9 \uD654\uC9C8 \uBAA8\uB4DC \uD65C\uC131\uD654");else{let n=a,o=this.room.localParticipant.getTrackPublications().find(c=>c.source===d.Source.Camera);o&&o.track?this.room.localParticipant.isCameraEnabled?(this.currentVideoQuality=e,yield this.room.localParticipant.setCameraEnabled(!1),yield new Promise(l=>setTimeout(l,200)),yield this.room.localParticipant.setCameraEnabled(!0),this.debug&&(console.log(`\u{1F3A5} \uD654\uC9C8 \uBCC0\uACBD\uC744 \uC704\uD574 \uCE74\uBA54\uB77C \uC7AC\uC2DC\uC791 \uC644\uB8CC: ${e}`),setTimeout(()=>{var h;let l=(h=this.room)==null?void 0:h.localParticipant.getTrackPublication(d.Source.Camera);if(l!=null&&l.track&&"mediaStreamTrack"in l.track){let p=l.track.mediaStreamTrack.getSettings();console.log("\u{1F3A5} \uC2E4\uC81C \uC801\uC6A9\uB41C \uD654\uC9C8:",{width:p.width,height:p.height,frameRate:p.frameRate,\uC694\uCCAD\uD55C\uD654\uC9C8:e})}},1e3))):this.debug&&console.log("\u{1F3A5} \uCE74\uBA54\uB77C\uAC00 \uAEBC\uC838\uC788\uC5B4 \uD654\uC9C8 \uC124\uC815\uB9CC \uC800\uC7A5\uD569\uB2C8\uB2E4."):this.room.localParticipant.isCameraEnabled||this.debug&&console.log("\u{1F3A5} \uCE74\uBA54\uB77C\uAC00 \uAEBC\uC838\uC788\uC5B4 \uD654\uC9C8 \uC124\uC815\uB9CC \uC800\uC7A5\uD569\uB2C8\uB2E4."),this.currentVideoQuality=e,this.debug&&console.log(`\u{1F3A5} \uBE44\uB514\uC624 \uD654\uC9C8 \uBCC0\uACBD: ${e} (${n.width}x${n.height}@${n.frameRate}fps, ${n.bitrate}bps)`)}}catch(a){throw console.error("\uBE44\uB514\uC624 \uD654\uC9C8 \uC124\uC815 \uC2E4\uD328:",a),a}})}setAudioQuality(e,t){return s(this,null,function*(){if(!this.room||!this.room.localParticipant)throw new Error("\uB8F8\uC5D0 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");if(this.userRole!=="teacher"&&!t)throw new Error("\uC624\uB514\uC624 \uD654\uC9C8 \uC124\uC815 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");let i=S;if(!i[e])throw new Error(`\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uC624\uB514\uC624 \uD654\uC9C8: ${e}. \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uAC12: ${Object.keys(i).join(", ")}`);try{let r=i[e],a=this.room.localParticipant.getTrackPublications().find(n=>n.source===d.Source.Microphone);a&&a.track&&this.debug&&console.log(`\u{1F3B5} \uC624\uB514\uC624 \uD654\uC9C8 \uC124\uC815 \uC694\uCCAD: ${r.bitrate}bps (\uD604\uC7AC LiveKit\uC5D0\uC11C \uC9C1\uC811 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC74C)`),this.currentAudioQuality=e,this.debug&&console.log(`\u{1F3B5} \uC624\uB514\uC624 \uD654\uC9C8 \uBCC0\uACBD: ${e} (${r.sampleRate}Hz, ${r.bitrate}bps)`)}catch(r){throw console.error("\uC624\uB514\uC624 \uD654\uC9C8 \uC124\uC815 \uC2E4\uD328:",r),r}})}switchAudioInput(e){return s(this,null,function*(){if(!this.room)throw new Error("\uB8F8\uC5D0 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");try{yield this.room.switchActiveDevice("audioinput",e),this.selectedAudioInputId=e,this.debug&&console.log("\u{1F3A4} \uC624\uB514\uC624 \uC785\uB825 \uC7A5\uCE58 \uBCC0\uACBD:",e)}catch(t){throw console.error("\uC624\uB514\uC624 \uC785\uB825 \uC7A5\uCE58 \uBCC0\uACBD \uC2E4\uD328:",t),t}})}switchAudioOutput(e){return s(this,null,function*(){if(!this.room)throw new Error("\uB8F8\uC5D0 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");try{yield this.room.switchActiveDevice("audiooutput",e),this.selectedAudioOutputId=e,this.debug&&console.log("\u{1F50A} \uC624\uB514\uC624 \uCD9C\uB825 \uC7A5\uCE58 \uBCC0\uACBD:",e)}catch(t){throw console.error("\uC624\uB514\uC624 \uCD9C\uB825 \uC7A5\uCE58 \uBCC0\uACBD \uC2E4\uD328:",t),t}})}getMediaDevices(){return s(this,null,function*(){try{return yield navigator.mediaDevices.enumerateDevices()}catch(e){return console.error("\uBBF8\uB514\uC5B4 \uC7A5\uCE58 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328:",e),[]}})}getMediaState(e){var i;if(!this.room||!e)return{camera:!1,microphone:!1,screenShare:!1,canPublish:!1};let t=this.room.localParticipant;return{camera:t.isCameraEnabled||!1,microphone:t.isMicrophoneEnabled||!1,screenShare:((i=e.mediaState)==null?void 0:i.screenShareEnabled)||!1,canPublish:this.canPublishMediaStream()}}setMediaState(e){return s(this,null,function*(){var i,r,a,n;let t={};if(e.camera!==void 0)try{let o=((r=(i=this.room)==null?void 0:i.localParticipant)==null?void 0:r.isCameraEnabled)||!1;o!==e.camera?t.camera=yield this.toggleCamera():t.camera=o}catch(o){t.camera={error:o.message}}if(e.microphone!==void 0)try{let o=((n=(a=this.room)==null?void 0:a.localParticipant)==null?void 0:n.isMicrophoneEnabled)||!1;o!==e.microphone?t.microphone=yield this.toggleMicrophone():t.microphone=o}catch(o){t.microphone={error:o.message}}if(e.screenShare!==void 0)try{e.screenShare?t.screenShare=yield this.startScreenShare():(yield this.stopScreenShare(),t.screenShare=!1)}catch(o){t.screenShare={error:o.message}}return t})}getCurrentVideoQuality(){return this.currentVideoQuality}getCurrentAudioQuality(){return this.currentAudioQuality}getIsScreenSharing(){return this.isScreenSharing}isScreenShareActive(){return this.isScreenSharing||!1}};var y=class{constructor(e){this.room=null;this.isConnected=!1;this.isConnecting=!1;this.eventListeners=new Map;this.authToken=null;this.tokenExpiry=null;this.iceServers=[];this.participants=[];this.localParticipant=null;this.currentPresenter=null;this.userRole=null;this.roomName=null;this.canPublishMedia=!1;this.isScreenSharing=!1;this.currentVideoQuality="high";this.currentAudioQuality="high";this.adaptiveStreamEnabled=!1;this.selectedAudioInputId=null;this.selectedAudioOutputId=null;this.reconnectAttempts=0;this.maxReconnectAttempts=3;this.reconnectDelay=2e3;if(!e.auth||!e.auth.clientId||!e.auth.clientSecret)throw new Error("\uC778\uC99D \uC815\uBCF4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. config.auth.clientId\uC640 config.auth.clientSecret\uC744 \uC81C\uACF5\uD574\uC8FC\uC138\uC694.");this.config={serverHost:e.serverHost||"rtc.i-screammedia.com",tokenEndpoint:e.tokenEndpoint||"/api/token",livekitEndpoint:e.livekitEndpoint||"/livekit/",useHttps:e.useHttps!==!1,debug:e.debug||!1,auth:e.auth},this.presenterManager=new P(this.config.debug),this.mediaController=new b(this.config.debug),this.setupBeforeUnloadHandler(),this.config.debug&&console.log(`\u{1F366} I-scream WebRTC SDK v${SDK_VERSION} \uCD08\uAE30\uD654:`,this.config)}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,[]),this.eventListeners.get(e).push(t)}off(e,t){let i=this.eventListeners.get(e);if(i){let r=i.indexOf(t);r>-1&&i.splice(r,1)}}emit(e,...t){let i=this.eventListeners.get(e);i&&i.forEach(r=>{try{r(...t)}catch(a){console.error(`Error in event handler for ${e}:`,a)}})}authenticate(){return s(this,null,function*(){let t=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}/auth/token`;this.config.debug&&console.log("\u{1F510} \uC778\uC99D \uD1A0\uD070 \uC694\uCCAD:",t);try{let i=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"client_credentials",client_id:this.config.auth.clientId,client_secret:this.config.auth.clientSecret})});if(!i.ok){let a=yield i.json();throw new Error(a.error_description||"\uC778\uC99D \uC2E4\uD328")}let r=yield i.json();return this.authToken=r.access_token,this.tokenExpiry=Date.now()+r.expires_in*1e3,this.config.debug&&console.log("\u{1F510} \uC778\uC99D \uD1A0\uD070 \uD68D\uB4DD \uC131\uACF5:",{clientName:r.client_name,expiresIn:r.expires_in}),this.authToken}catch(i){throw console.error("\u{1F510} \uC778\uC99D \uC2E4\uD328:",i),i}})}getToken(e){return s(this,null,function*(){(!this.authToken||Date.now()>=(this.tokenExpiry||0))&&(yield this.authenticate());let i=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}${this.config.tokenEndpoint}`,r={roomName:e.roomName,participantName:e.participantName,role:e.role},a=yield fetch(i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify(r)});if(!a.ok){if(a.status===401){this.config.debug&&console.log("\u{1F510} \uC778\uC99D \uD1A0\uD070 \uB9CC\uB8CC, \uC7AC\uC778\uC99D \uC2DC\uB3C4"),yield this.authenticate();let o=yield fetch(i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify(r)});if(!o.ok)throw new Error(`\uD1A0\uD070 \uBC1C\uAE09 \uC2E4\uD328: ${o.status} ${o.statusText}`);return o.json()}if(a.status===429){let o=yield a.json();throw new Error(o.error||"\uD1A0\uD070 \uC0DD\uC131\uC774 \uC9C4\uD589\uC911\uC785\uB2C8\uB2E4. \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.")}throw new Error(`\uD1A0\uD070 \uBC1C\uAE09 \uC2E4\uD328: ${a.status} ${a.statusText}`)}let n=yield a.json();return n.iceServers?(this.iceServers=n.iceServers,this.config.debug&&console.log("\u{1F510} \uD1A0\uD070 \uC11C\uBC84\uC5D0\uC11C \uBC1B\uC740 ICE \uC11C\uBC84 \uC815\uBCF4:",{count:this.iceServers.length,servers:this.iceServers.map(o=>({urls:o.urls,hasCredentials:!!(o.username&&o.credential)}))})):console.warn("\u26A0\uFE0F \uD1A0\uD070 \uC751\uB2F5\uC5D0 ICE \uC11C\uBC84 \uC815\uBCF4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4"),n})}getRoomInfoFromServer(e){return s(this,null,function*(){try{let i=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}/api/room-info`;(!this.authToken||Date.now()>=(this.tokenExpiry||0))&&(yield this.authenticate());let r=yield fetch(i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify({roomName:e})});return r.ok?r.json():(console.warn("\u26A0\uFE0F \uB8F8 \uC815\uBCF4 \uC870\uD68C API \uD638\uCD9C \uC2E4\uD328:",r.status),{participants:[]})}catch(t){return console.error("\uB8F8 \uC815\uBCF4 \uC870\uD68C \uC2E4\uD328:",t),{participants:[]}}})}preValidateRoom(e){return s(this,null,function*(){let i=(yield this.getRoomInfoFromServer(e.roomName)).participants||[];if(e.role==="teacher"){let a=i.filter(n=>{var o;return n.role==="teacher"||((o=n.metadata)==null?void 0:o.role)==="teacher"});if(a.length>0){let n=a.map(o=>o.name||o.identity).join(", ");throw new Error(`\uC774\uBBF8 \uC120\uC0DD\uB2D8\uC774 \uC785\uC7A5\uD574 \uC788\uC2B5\uB2C8\uB2E4. (${n}). \uAC19\uC740 \uB8F8\uC5D0\uB294 \uC120\uC0DD\uB2D8\uC774 \uD55C \uBA85\uB9CC \uC785\uC7A5\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`)}}if(e.role==="student"){if(!i.some(o=>{var c;return o.role==="teacher"||((c=o.metadata)==null?void 0:c.role)==="teacher"}))throw new Error("\uC120\uC0DD\uB2D8\uC774 \uBA3C\uC800 \uC785\uC7A5\uD574\uC57C \uD569\uB2C8\uB2E4.");if(i.filter(o=>{var c;return o.role==="student"||((c=o.metadata)==null?void 0:c.role)==="student"}).length>=50)throw new Error("\uD559\uC0DD\uC740 \uCD5C\uB300 50\uBA85\uAE4C\uC9C0\uB9CC \uC785\uC7A5\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.")}if(i.find(a=>a.name===e.participantName||a.identity===e.participantName))throw new Error("\uAC19\uC740 \uC774\uB984\uC758 \uCC38\uAC00\uC790\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uC774\uB984\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694.")})}cleanupGhostParticipantsBeforeJoin(e){return s(this,null,function*(){try{console.log("\u{1F47B} \uC5F0\uACB0 \uC804 \uC720\uB839 \uC0AC\uC6A9\uC790 \uC815\uB9AC \uC2DC\uC791...");let i=(yield this.getRoomInfoFromServer(e)).participants||[];if(i.length===0)return{success:!0,removed:[]};let r=[],n=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}/api/participant-leave`;for(let o of i)if(o)try{(yield(yield fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify({roomName:e,participantName:o.name||o.identity})})).json()).success&&(r.push(o.identity||"unknown"),this.config.debug&&console.log(`\u2705 \uC720\uB839 \uC0AC\uC6A9\uC790 \uC81C\uAC70: ${o.identity||"unknown"}`))}catch(c){this.config.debug&&console.log(`\u26A0\uFE0F ${o.identity||"unknown"} \uC81C\uAC70 \uC2E4\uD328:`,c)}return{success:!0,removed:r}}catch(t){return console.error("\uC720\uB839 \uC0AC\uC6A9\uC790 \uC815\uB9AC \uC2E4\uD328:",t),{success:!1,error:t,removed:[]}}})}connect(e){return s(this,null,function*(){if(this.isConnecting)throw new Error("\uC5F0\uACB0\uC774 \uC774\uBBF8 \uC9C4\uD589 \uC911\uC785\uB2C8\uB2E4.");if(this.isConnected)throw new Error("\uC774\uBBF8 \uC5F0\uACB0\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.");this.isConnecting=!0;try{if(e.role==="teacher"){try{let h=yield this.cleanupGhostParticipantsBeforeJoin(e.roomName);h.removed&&h.removed.length>0&&(console.log(`\u2705 ${h.removed.length}\uBA85\uC758 \uC720\uB839 \uC0AC\uC6A9\uC790\uAC00 \uC790\uB3D9\uC73C\uB85C \uC81C\uAC70\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`),yield new Promise(p=>setTimeout(p,1e3)))}catch(h){console.warn("\u26A0\uFE0F \uC720\uB839 \uC0AC\uC6A9\uC790 \uC790\uB3D9 \uC815\uB9AC \uC2E4\uD328 (\uBB34\uC2DC\uD558\uACE0 \uACC4\uC18D):",h)}yield this.presenterManager.handleTeacherChange("joined")}try{yield this.preValidateRoom(e)}catch(h){if(h.message.includes("\uC120\uC0DD\uB2D8\uC774 \uBA3C\uC800 \uC785\uC7A5\uD574\uC57C"))console.warn("\u26A0\uFE0F \uC120\uC0DD\uB2D8 \uAC80\uC99D \uC2E4\uD328 - \uBA54\uD0C0\uB370\uC774\uD130 \uB3D9\uAE30\uD654 \uBB38\uC81C\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uC5F0\uACB0\uC744 \uACC4\uC18D \uC9C4\uD589\uD569\uB2C8\uB2E4.");else throw h}this.roomName=e.roomName,this.userRole=e.role;let t=yield this.getToken(e),i=t.token||t,r={adaptiveStream:e.adaptiveStream!==!1,dynacast:e.dynacast!==!1,publishDefaults:{videoCodec:"h264",stopMicTrackOnMute:!1},disconnectOnPageLeave:!1,stopLocalTrackOnUnpublish:!1};this.room=new v(r),this.setupRoomEvents();let n=`${this.config.useHttps?"wss":"ws"}://${this.config.serverHost}${this.config.livekitEndpoint}`,o=JSON.stringify({role:this.userRole,name:e.participantName,joinedAt:Date.now()}),c={iceTransportPolicy:"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"};this.iceServers&&this.iceServers.length>0?(c.iceServers=this.iceServers,this.config.debug&&console.log(`\u{1F510} \uC11C\uBC84\uC5D0\uC11C \uBC1B\uC740 ICE \uC11C\uBC84 \uC0AC\uC6A9: ${this.iceServers.length}\uAC1C`)):(c.iceServers=[{urls:["stun:stun.l.google.com:19302"]},{urls:["stun:stun1.l.google.com:19302"]}],this.config.debug&&console.log("\u26A0\uFE0F \uC11C\uBC84\uC5D0\uC11C ICE \uC11C\uBC84 \uC815\uBCF4\uB97C \uBC1B\uC9C0 \uBABB\uD568, \uAE30\uBCF8 STUN \uC11C\uBC84\uB9CC \uC0AC\uC6A9"));let l={autoSubscribe:!0,metadata:o,rtcConfig:c};this.config.debug&&console.log("\u{1F50C} LiveKit \uC5F0\uACB0 \uC2DC\uB3C4 \uC911...",{serverUrl:n,hasIceServers:!!c.iceServers,iceServerCount:c.iceServers?c.iceServers.length:0}),yield this.room.connect(n,i,l),this.setupLocalParticipant(),this.setup2NStructure(),this.presenterManager.setRoom(this.room,this.userRole,this.room.localParticipant.identity),this.mediaController.setRoom(this.room,this.userRole,this.canPublishMedia),this.syncExistingParticipants(),this.isConnected=!0,this.isConnecting=!1,this.emit("connected",{room:this.roomName,localParticipant:this.localParticipant}),e.publishOnJoin&&this.canPublishMedia&&setTimeout(()=>s(this,null,function*(){try{yield this.enableVideo(!0),yield this.enableAudio(!0)}catch(h){console.error("\uC790\uB3D9 \uBBF8\uB514\uC5B4 \uBC1C\uD589 \uC2E4\uD328:",h)}}),1e3)}catch(t){throw this.isConnecting=!1,console.error("\uB8F8 \uC5F0\uACB0 \uC2E4\uD328:",t),this.emit("error",t),t}})}setupLocalParticipant(){!this.room||!this.room.localParticipant||(this.localParticipant={identity:this.room.localParticipant.identity,name:this.room.localParticipant.name||this.room.localParticipant.identity,role:this.userRole,isLocal:!0,isPresenter:!1,mediaState:{cameraEnabled:!1,microphoneEnabled:!1,screenShareEnabled:!1}},this.participants=[this.localParticipant])}setup2NStructure(){this.config.debug&&console.log("\u{1F3D7}\uFE0F 2:N \uAD6C\uC870 \uC124\uC815 \uC2DC\uC791"),this.userRole==="teacher"?(this.canPublishMedia=!0,this.config.debug&&console.log("\u{1F468}\u200D\u{1F3EB} \uC120\uC0DD\uB2D8: \uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uD65C\uC131\uD654")):this.userRole==="student"&&(this.canPublishMedia=!1,this.config.debug&&console.log("\u{1F468}\u200D\u{1F393} \uD559\uC0DD: \uBBF8\uB514\uC5B4 \uC1A1\uCD9C \uBE44\uD65C\uC131\uD654 (\uBC1C\uD45C\uC790 \uC9C0\uC815 \uC2DC \uD65C\uC131\uD654)")),this.emit("media:publishPermissionChanged",{canPublish:this.canPublishMedia,role:this.userRole})}syncExistingParticipants(){if(!this.room)return;let e=[];return this.room.remoteParticipants.forEach(t=>{let i=this.getParticipantRole(t),r={identity:t.identity,name:t.name||t.identity,role:i,isLocal:!1,isPresenter:this.currentPresenter===t.identity,mediaState:{cameraEnabled:!1,microphoneEnabled:!1,screenShareEnabled:!1}};this.participants.push(r),e.push({participantInfo:r,participant:t})}),setTimeout(()=>{e.forEach(({participantInfo:t,participant:i})=>{this.emit("participant:joined",t),this.emit("participantJoined",i)})},500),e}setupRoomEvents(){this.room&&(this.room.on(u.Connected,()=>{this.config.debug&&console.log("\u{1F517} Room connected"),this.emit("room:connectionStateChanged","connected")}),this.room.on(u.Disconnected,e=>{this.config.debug&&console.log("\u{1F50C} Room disconnected:",e),this.isConnected=!1,this.emit("disconnected",e),this.emit("room:connectionStateChanged","disconnected")}),this.room.on(u.ParticipantConnected,e=>{this.handleParticipantJoined(e)}),this.room.on(u.ParticipantDisconnected,e=>{this.handleParticipantLeft(e)}),this.room.on(u.TrackSubscribed,(e,t,i)=>{this.handleTrackSubscribed(e,t,i)}),this.room.on(u.TrackUnsubscribed,(e,t,i)=>{this.handleTrackUnsubscribed(e,t,i)}),this.room.on(u.LocalTrackPublished,e=>{this.handleLocalTrackPublished(e)}),this.room.on(u.DataReceived,(e,t,i)=>{this.handleDataReceived(e,t)}),this.room.on(u.ParticipantMetadataChanged,(e,t)=>{t!==this.room.localParticipant&&this.handleParticipantMetadataChanged(e,t)}),this.room.on(u.ConnectionQualityChanged,(e,t)=>{this.emit("connectionQualityChanged",{quality:e,participant:t})}))}handleParticipantJoined(e){let t=this.getParticipantRole(e);if(t==="teacher"){let a=this.participants.filter(n=>n.role==="teacher"&&!n.isLocal);a.length>0&&console.error("\u274C \uC2E4\uC2DC\uAC04 \uC120\uC0DD\uB2D8 \uC911\uBCF5 \uAC10\uC9C0:",{newTeacher:e.identity,existingTeachers:a.map(n=>n.identity)})}let i={identity:e.identity,name:e.name||e.identity,role:t,isLocal:!1,isPresenter:this.presenterManager.isPresenter(e.identity),mediaState:{cameraEnabled:e.isCameraEnabled,microphoneEnabled:e.isMicrophoneEnabled,screenShareEnabled:!1}};this.participants.push(i),this.emit("participant:joined",i),this.emit("participantJoined",e);let r=this.participants.filter(a=>a.role==="student").length;r>50&&console.warn("\u26A0\uFE0F \uD559\uC0DD \uC218\uAC00 50\uBA85\uC744 \uCD08\uACFC\uD588\uC2B5\uB2C8\uB2E4:",r),this.presenterManager.syncPresenterForNewParticipant()}handleParticipantLeft(e){let t=this.participants.find(i=>i.identity===e.identity);t&&(t.role==="teacher"&&this.presenterManager.handleTeacherChange("left").catch(console.error),this.participants=this.participants.filter(i=>i.identity!==e.identity),this.emit("participant:left",t),this.emit("participantLeft",e))}handleTrackSubscribed(e,t,i){if(this.config.debug&&console.log("\u{1F4FA} \uD2B8\uB799 \uAD6C\uB3C5:",{kind:e.kind,participant:i.identity,source:t.source}),this.emit("trackSubscribed",e,t,i),e.kind==="video"&&(this.emit("media:remoteVideoTrack",{participant:i,track:e}),this.attachRemoteVideoTrack(e,i)),e.kind==="video"&&t.source===m.Source.ScreenShare){let r=this.participants.find(a=>a.identity===i.identity);r&&(r.mediaState.screenShareEnabled=!0)}else if(e.kind==="video"&&t.source!==m.Source.ScreenShare){let r=this.getParticipantRole(i);this.presenterManager.shouldShowParticipantVideo(i,this.userRole,r)&&this.emit("video:shouldDisplay",{participant:i,track:e,publication:t})}}handleTrackUnsubscribed(e,t,i){if(this.config.debug&&console.log("\u{1F4FA} \uD2B8\uB799 \uAD6C\uB3C5 \uD574\uC81C:",{kind:e.kind,participant:i.identity,source:t.source}),e.kind==="video"&&t.source===m.Source.ScreenShare){let r=this.participants.find(a=>a.identity===i.identity);r&&(r.mediaState.screenShareEnabled=!1)}this.emit("trackUnsubscribed",e,t,i)}handleLocalTrackPublished(e){var t;this.config.debug&&console.log("\u{1F4E1} \uB85C\uCEEC \uD2B8\uB799 \uBC1C\uD589:",{kind:e.kind,hasTrack:!!e.track}),this.emit("localTrackPublished",e.track),e.kind===m.Kind.Video&&e.track&&this.emit("media:localVideoTrack",{participant:(t=this.room)==null?void 0:t.localParticipant,track:e.track})}handleDataReceived(e,t){return s(this,null,function*(){var a;let r=new TextDecoder().decode(e);try{let n=JSON.parse(r);if(n.type==="chat"){let o=t?this.participants.find(c=>c.identity===t.identity):this.localParticipant;this.emit("chatMessage",n.content,o)}else if(n.type==="quality:change"&&t){let o=this.participants.find(c=>c.identity===t.identity);if(o&&o.role==="teacher"){let c=n.quality;this.config.debug&&console.log("\u{1F4E1} \uC120\uC0DD\uB2D8\uC73C\uB85C\uBD80\uD130 \uD654\uC9C8 \uBCC0\uACBD \uC218\uC2E0:",c);let l=this.presenterManager.isPresenter(((a=this.localParticipant)==null?void 0:a.identity)||"");yield this.mediaController.setVideoQuality(c,l,!0),this.emit("media:videoQualityChanged",c)}}else if(n.type==="presenter_assigned"||n.type==="presenter_sync"||n.type==="presenter_cleared"){let o=this.presenterManager.handlePresenterMessage(n,this.participants);o&&(this.emit("presenter:changed",o),o.isMe&&o.action==="assigned"?(this.canPublishMedia=!0,this.mediaController.updatePublishPermission(!0),this.emit("media:publishPermissionChanged",{canPublish:!0,role:this.userRole})):o.isMe&&o.action==="cleared"&&this.userRole==="student"&&(this.canPublishMedia=!1,this.mediaController.updatePublishPermission(!1),this.emit("media:publishPermissionChanged",{canPublish:!1,role:this.userRole}),this.disableMediaForStudent()))}}catch(n){console.error("\uBA54\uC2DC\uC9C0 \uD30C\uC2F1 \uC2E4\uD328:",n)}})}handleParticipantMetadataChanged(e,t){let i=this.participants.find(r=>r.identity===t.identity);if(i&&e)try{let r=JSON.parse(e);i.role=r.role||"student"}catch(r){console.error("\uBA54\uD0C0\uB370\uC774\uD130 \uD30C\uC2F1 \uC2E4\uD328:",r)}}disableMediaForStudent(){return s(this,null,function*(){if(!(!this.room||!this.room.localParticipant))try{if(this.room.localParticipant.isCameraEnabled){let e=this.room.localParticipant.getTrackPublication(m.Source.Camera);if(e&&e.track){let t=e.track;yield this.room.localParticipant.unpublishTrack(t),t&&typeof t.stop=="function"&&(t.stop(),this.config.debug&&console.log("\u{1F6D1} \uBC1C\uD45C\uC790 \uD574\uC81C: \uCE74\uBA54\uB77C LocalVideoTrack \uC911\uC9C0\uB428"));try{let i=t.mediaStreamTrack||t._mediaStreamTrack;i&&typeof i.stop=="function"&&(i.stop(),this.config.debug&&console.log("\u{1F6D1} \uBC1C\uD45C\uC790 \uD574\uC81C: \uCE74\uBA54\uB77C MediaStreamTrack \uC911\uC9C0\uB428"))}catch(i){console.error("\uCE74\uBA54\uB77C MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",i)}}this.localParticipant&&(this.localParticipant.mediaState.cameraEnabled=!1)}if(this.room.localParticipant.isMicrophoneEnabled){let e=this.room.localParticipant.getTrackPublication(m.Source.Microphone);if(e&&e.track){let t=e.track;yield this.room.localParticipant.unpublishTrack(t),t&&typeof t.stop=="function"&&(t.stop(),this.config.debug&&console.log("\u{1F6D1} \uBC1C\uD45C\uC790 \uD574\uC81C: \uB9C8\uC774\uD06C LocalAudioTrack \uC911\uC9C0\uB428"));try{let i=t.mediaStreamTrack||t._mediaStreamTrack;i&&typeof i.stop=="function"&&(i.stop(),this.config.debug&&console.log("\u{1F6D1} \uBC1C\uD45C\uC790 \uD574\uC81C: \uB9C8\uC774\uD06C MediaStreamTrack \uC911\uC9C0\uB428"))}catch(i){console.error("\uB9C8\uC774\uD06C MediaStreamTrack \uC911\uC9C0 \uC2E4\uD328:",i)}}this.localParticipant&&(this.localParticipant.mediaState.microphoneEnabled=!1)}this.config.debug&&console.log("\u{1F4F9}\u{1F3A4} \uBC1C\uD45C\uC790 \uD574\uC81C\uB85C \uBBF8\uB514\uC5B4 \uC790\uB3D9 \uB044\uAE30 \uC644\uB8CC")}catch(e){console.error("\uBBF8\uB514\uC5B4 \uB044\uAE30 \uC2E4\uD328:",e)}})}canPublishMediaStream(){return this.mediaController.canPublishMediaStream()}enableVideo(e){return s(this,null,function*(){let t=yield this.mediaController.enableVideo(e);return this.localParticipant&&(this.localParticipant.mediaState.cameraEnabled=e),this.emit("media:cameraStateChanged",e),t})}enableAudio(e){return s(this,null,function*(){let t=yield this.mediaController.enableAudio(e);return this.localParticipant&&(this.localParticipant.mediaState.microphoneEnabled=e),this.emit("media:microphoneStateChanged",e),t})}toggleCamera(){return s(this,null,function*(){let e=yield this.mediaController.toggleCamera();return this.localParticipant&&this.room&&(this.localParticipant.mediaState.cameraEnabled=this.room.localParticipant.isCameraEnabled),this.emit("media:cameraStateChanged",e),e})}toggleMicrophone(){return s(this,null,function*(){let e=yield this.mediaController.toggleMicrophone();return this.localParticipant&&this.room&&(this.localParticipant.mediaState.microphoneEnabled=this.room.localParticipant.isMicrophoneEnabled),this.emit("media:microphoneStateChanged",e),e})}startScreenShare(){return s(this,null,function*(){let e=yield this.mediaController.startScreenShare();return e&&this.localParticipant&&(this.localParticipant.mediaState.screenShareEnabled=!0),this.emit("media:screenShareStateChanged",e),e})}stopScreenShare(){return s(this,null,function*(){yield this.mediaController.stopScreenShare(),this.localParticipant&&(this.localParticipant.mediaState.screenShareEnabled=!1),this.emit("media:screenShareStateChanged",!1)})}isScreenShareActive(){return this.mediaController.isScreenShareActive()}setVideoQuality(e){return s(this,null,function*(){var i;let t=this.presenterManager.isPresenter(((i=this.localParticipant)==null?void 0:i.identity)||"");if(this.userRole==="teacher"&&this.room){let a=new TextEncoder().encode(JSON.stringify({type:"quality:change",quality:e}));yield this.room.localParticipant.publishData(a,{reliable:!0}),this.config.debug&&console.log("\u{1F4E1} \uC120\uC0DD\uB2D8\uC774 \uD654\uC9C8 \uBCC0\uACBD \uC804\uD30C:",e)}yield this.mediaController.setVideoQuality(e,t),this.emit("media:videoQualityChanged",e)})}setAudioQuality(e){return s(this,null,function*(){var i;let t=this.presenterManager.isPresenter(((i=this.localParticipant)==null?void 0:i.identity)||"");yield this.mediaController.setAudioQuality(e,t),this.emit("media:audioQualityChanged",e)})}switchAudioInput(e){return s(this,null,function*(){yield this.mediaController.switchAudioInput(e)})}switchAudioOutput(e){return s(this,null,function*(){yield this.mediaController.switchAudioOutput(e)})}getMediaDevices(){return s(this,null,function*(){return this.mediaController.getMediaDevices()})}getMediaState(){return this.mediaController.getMediaState(this.localParticipant)}setMediaState(e){return s(this,null,function*(){return this.mediaController.setMediaState(e)})}disconnect(){return s(this,null,function*(){var e,t;if(this.room){yield this.room.disconnect();try{let r=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}/api/participant-leave`;yield fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify({roomName:this.roomName,participantName:((e=this.localParticipant)==null?void 0:e.name)||((t=this.localParticipant)==null?void 0:t.identity)})})}catch(i){console.error("\uCC38\uAC00\uC790 \uB098\uAC00\uAE30 API \uD638\uCD9C \uC2E4\uD328:",i)}yield this.room.disconnect(),this.room=null,this.isConnected=!1,this.isConnecting=!1,this.participants=[],this.localParticipant=null}})}getParticipantRole(e){let t=e.metadata;if(t)try{return JSON.parse(t).role||"student"}catch(i){return"student"}return"student"}setupBeforeUnloadHandler(){typeof window!="undefined"&&window.addEventListener("beforeunload",()=>s(this,null,function*(){this.isConnected&&(yield this.disconnect())}))}cleanupGhostParticipants(){return s(this,null,function*(){if(this.userRole!=="teacher")throw new Error("\uC120\uC0DD\uB2D8\uB9CC \uC720\uB839 \uC0AC\uC6A9\uC790 \uC815\uB9AC\uB97C \uC218\uD589\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");try{this.config.debug&&console.log("\u{1F47B} \uC720\uB839 \uC0AC\uC6A9\uC790 \uC815\uB9AC \uC2DC\uC791...");let t=(yield this.getRoomInfoFromServer(this.roomName||"")).participants||[],i=new Set;this.room&&(i.add(this.room.localParticipant.identity),this.room.remoteParticipants.forEach(c=>{i.add(c.identity)}));let r=t.filter(c=>!i.has(c.identity));if(r.length===0)return this.config.debug&&console.log("\u2705 \uC720\uB839 \uC0AC\uC6A9\uC790\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."),{success:!0,removed:[]};let a=[],o=`${this.config.useHttps?"https":"http"}://${this.config.serverHost}/api/participant-leave`;for(let c of r)try{(yield(yield fetch(o,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.authToken}`},body:JSON.stringify({roomName:this.roomName,participantName:c.name||c.identity})})).json()).success&&(a.push(c.identity),this.config.debug&&console.log(`\u2705 \uC720\uB839 \uC0AC\uC6A9\uC790 \uC81C\uAC70: ${c.identity}`))}catch(l){this.config.debug&&console.log(`\u26A0\uFE0F ${c.identity} \uC81C\uAC70 \uC2E4\uD328:`,l)}return console.log(`\u2705 ${a.length}\uBA85\uC758 \uC720\uB839 \uC0AC\uC6A9\uC790\uAC00 \uC81C\uAC70\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`),{success:!0,removed:a}}catch(e){return console.error("\uC720\uB839 \uC0AC\uC6A9\uC790 \uC815\uB9AC \uC2E4\uD328:",e),{success:!1,removed:[]}}})}getParticipants(){return[...this.participants]}setPresenter(e){return s(this,null,function*(){yield this.presenterManager.setPresenter(e,this.participants);let t=this.participants.find(i=>i.identity===e);t&&(t.isPresenter=!0,this.emit("presenter:changed",{action:"assigned",presenterIdentity:e,previousPresenter:null,isMe:!1}))})}clearPresenter(){return s(this,null,function*(){let e=yield this.presenterManager.clearPresenter();return this.participants.forEach(t=>{t.isPresenter=!1}),this.emit("presenter:changed",{action:"cleared",presenterIdentity:null,previousPresenter:e,isMe:!1}),e})}getCurrentPresenter(){return this.presenterManager.getCurrentPresenter()}sendMessage(e){return s(this,null,function*(){if(!this.room)throw new Error("\uC5F0\uACB0\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");let i=new TextEncoder().encode(JSON.stringify({type:"chat",content:e,sender:this.room.localParticipant.identity,timestamp:new Date().toISOString()}));yield this.room.localParticipant.publishData(i,{reliable:!0})})}getParticipantsByRole(e){return this.participants.filter(t=>t.role===e)}getRemoteParticipants(){return this.participants.filter(e=>!e.isLocal)}getConnectionInfo(){var e;return{isConnected:this.isConnected,roomName:this.roomName,participantName:((e=this.localParticipant)==null?void 0:e.name)||null,role:this.userRole,participantCount:this.participants.length,canPublish:this.canPublishMediaStream()}}getDebugInfo(){return{connection:this.getConnectionInfo(),media:this.getMediaState(),participants:{total:this.participants.length,teachers:this.getParticipantsByRole("teacher").length,students:this.getParticipantsByRole("student").length,presenter:this.getCurrentPresenter()},quality:{video:this.mediaController.getCurrentVideoQuality(),adaptive:!1}}}getRoomName(){return this.roomName}getUserRole(){return this.userRole}getLocalParticipant(){return this.localParticipant}isConnectionActive(){return this.isConnected}attachLocalVideoTrack(e){var t;!e||!((t=this.room)!=null&&t.localParticipant)||setTimeout(()=>{let i=this.room.localParticipant.identity,r=document.getElementById(`video-${i}`)||document.querySelector(`video[data-participant="${i}"]`)||document.getElementById("localVideo")||document.querySelector(".local-video video")||document.querySelector(".video-item video#localVideo");if(r)try{if(e.attach)e.attach(r);else if(e instanceof MediaStreamTrack){let a=new MediaStream([e]);r.srcObject=a,r.play()}this.config.debug&&console.log("\u2705 \uB85C\uCEEC \uBE44\uB514\uC624 \uD2B8\uB799 \uC5F0\uACB0 \uC131\uACF5")}catch(a){console.error("\u274C \uB85C\uCEEC \uBE44\uB514\uC624 \uD2B8\uB799 \uC5F0\uACB0 \uC2E4\uD328:",a)}else this.config.debug&&console.warn("\u26A0\uFE0F \uB85C\uCEEC \uBE44\uB514\uC624 \uC694\uC18C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4:",i)},100)}attachRemoteVideoTrack(e,t){e&&setTimeout(()=>{let i=t.identity,r=document.getElementById(`video-${i}`)||document.querySelector(`video[data-participant="${i}"]`)||document.querySelector(`.video-item[data-participant="${i}"] video`);if(r)try{if(e.attach)e.attach(r);else if(e instanceof MediaStreamTrack){let a=new MediaStream([e]);r.srcObject=a,r.play()}this.config.debug&&console.log("\u2705 \uC6D0\uACA9 \uBE44\uB514\uC624 \uD2B8\uB799 \uC5F0\uACB0 \uC131\uACF5:",i)}catch(a){console.error("\u274C \uC6D0\uACA9 \uBE44\uB514\uC624 \uD2B8\uB799 \uC5F0\uACB0 \uC2E4\uD328:",a)}else this.config.debug&&console.warn("\u26A0\uFE0F \uC6D0\uACA9 \uBE44\uB514\uC624 \uC694\uC18C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4:",i)},100)}},J=y;export{y as IScreamWebRTC,J as default};