From d1f364e230864ffa106d1b97ba22d6ac0fcbb373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=E4=BA=86=E4=B8=AAJ?= Date: Tue, 12 May 2026 12:04:26 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=A2=9E=E5=8A=A0=E7=9B=B4?= =?UTF-8?q?=E6=92=AD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 106 +++++++++++ src/page/home/index.vue | 50 ++--- src/page/live/StreamVideo.vue | 36 ++++ src/page/live/index.vue | 322 ++++++++++++++++++++++++++++++++ src/page/live/room-ws-client.ts | 276 +++++++++++++++++++++++++++ src/page/live/routes.ts | 10 + src/stores/student-access.ts | 1 + 8 files changed, 780 insertions(+), 22 deletions(-) create mode 100644 src/page/live/StreamVideo.vue create mode 100644 src/page/live/index.vue create mode 100644 src/page/live/room-ws-client.ts create mode 100644 src/page/live/routes.ts diff --git a/package.json b/package.json index cca1dad..cde9404 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "lottie-web": "^5.12.2", "markdown-it": "^14.1.0", "mathjax": "3.0.1", + "mediasoup-client": "^3.20.0", "mermaid-it-markdown": "^1.0.8", "nprogress": "^0.2.0", "pinia": "^2.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ccde22..1ff42c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,6 +92,9 @@ importers: mathjax: specifier: 3.0.1 version: 3.0.1 + mediasoup-client: + specifier: ^3.20.0 + version: 3.20.0 mermaid-it-markdown: specifier: ^1.0.8 version: 1.0.8(mermaid@10.9.3)(typescript@5.8.2) @@ -655,6 +658,14 @@ packages: '@kurkle/color@0.3.4': resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + + '@lukeed/uuid@2.0.1': + resolution: {integrity: sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==} + engines: {node: '>=8'} + '@microsoft/fetch-event-source@2.0.1': resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} @@ -909,9 +920,15 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/events@3.0.3': + resolution: {integrity: sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==} + '@types/hammerjs@2.0.46': resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==} @@ -1341,6 +1358,10 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + awaitqueue@3.3.0: + resolution: {integrity: sha512-zLxDhzQbzHmOyvxi7g3OlfR7jLrcmElStPxfLPpJkrFSDm71RSrY/MvsDA8Btlx8X1nOHUzGhQvc6bdUjL2f2w==} + engines: {node: '>=20'} + axios@1.8.4: resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} @@ -1758,6 +1779,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} @@ -2078,6 +2108,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -2088,6 +2122,10 @@ packages: ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + fake-mediastreamtrack@2.2.1: + resolution: {integrity: sha512-SITLc7UTDirSdgLGORrlmqjWLJtbtfIz/xO7DwVbJH3f0ds+NQok4ccl/WEzz49NSgiUlXf2wDW0+y5C+TO6EA==} + engines: {node: '>=20'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2256,6 +2294,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + h264-profile-level-id@2.3.2: + resolution: {integrity: sha512-hnq1UDlw7WGJV6GCr/g7wnkHYUjdAY2bis9rgn2JqSdQS2WfVvnt1ZE9g8nTguracodf5LLKZOwURsDN49YtBQ==} + engines: {node: '>=20'} + hammerjs@2.0.8: resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==} engines: {node: '>=0.8.0'} @@ -2712,6 +2754,10 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + mediasoup-client@3.20.0: + resolution: {integrity: sha512-FL6RlsGwvmXbXkbMoc1eW2EqW7k8Cw/Mhls3QewQXH+mioWVeVNWjzcDPmTZ3Sw+mua/n0IH5C/ntuVsx+KegA==} + engines: {node: '>=22'} + memoize-one@6.0.0: resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} @@ -3220,6 +3266,10 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + sdp-transform@3.0.0: + resolution: {integrity: sha512-gfYVRGxjHkGF2NPeUWHw5u6T/KGFtS5/drPms73gaSuMaVHKCY3lpLnGDfswVQO0kddeePoti09AwhYP4zA8dQ==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -3363,6 +3413,10 @@ packages: stylis@4.3.6: resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -4192,6 +4246,12 @@ snapshots: '@kurkle/color@0.3.4': {} + '@lukeed/csprng@1.1.0': {} + + '@lukeed/uuid@2.0.1': + dependencies: + '@lukeed/csprng': 1.1.0 + '@microsoft/fetch-event-source@2.0.1': {} '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': @@ -4364,8 +4424,14 @@ snapshots: dependencies: '@types/ms': 2.1.0 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.7': {} + '@types/events@3.0.3': {} + '@types/hammerjs@2.0.46': {} '@types/json-schema@7.0.15': {} @@ -4914,6 +4980,12 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + awaitqueue@3.3.0(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + axios@1.8.4: dependencies: follow-redirects: 1.15.9 @@ -5360,6 +5432,12 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.3(supports-color@10.2.2): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 + decamelize@1.2.0: {} decode-named-character-reference@1.1.0: @@ -5789,6 +5867,8 @@ snapshots: eventemitter3@5.0.1: {} + events@3.3.0: {} + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -5807,6 +5887,10 @@ snapshots: dependencies: type: 2.7.3 + fake-mediastreamtrack@2.2.1: + dependencies: + '@lukeed/uuid': 2.0.1 + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5993,6 +6077,12 @@ snapshots: graphemer@1.4.0: {} + h264-profile-level-id@2.3.2(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + hammerjs@2.0.8: {} has-bigints@1.1.0: {} @@ -6441,6 +6531,18 @@ snapshots: mdurl@2.0.0: {} + mediasoup-client@3.20.0: + dependencies: + '@types/debug': 4.1.13 + '@types/events-alias': '@types/events@3.0.3' + awaitqueue: 3.3.0(supports-color@10.2.2) + debug: 4.4.3(supports-color@10.2.2) + events-alias: events@3.3.0 + fake-mediastreamtrack: 2.2.1 + h264-profile-level-id: 2.3.2(supports-color@10.2.2) + sdp-transform: 3.0.0 + supports-color: 10.2.2 + memoize-one@6.0.0: {} meow@12.1.1: {} @@ -7040,6 +7142,8 @@ snapshots: scule@1.3.0: {} + sdp-transform@3.0.0: {} + semver@6.3.1: {} semver@7.7.2: {} @@ -7197,6 +7301,8 @@ snapshots: stylis@4.3.6: {} + supports-color@10.2.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 diff --git a/src/page/home/index.vue b/src/page/home/index.vue index 9b9653e..c16ee89 100644 --- a/src/page/home/index.vue +++ b/src/page/home/index.vue @@ -46,8 +46,6 @@ const { system, checkUpdate } = globalStore() const isHomePageLoading = ref(false) const navMain = computed(() => { - // const { purchasedInspector, nextInspectorCourseDate, conductInspectorPlanId } = - // inspectorInfo.value ?? {} return [ { id: '2', @@ -55,23 +53,6 @@ const navMain = computed(() => { key: 'subject', path: '/subject', }, - // { - // id: '3', - // url: homeUrge, - // key: 'urge', - // path: '', - // show: !isHide.value, - // // id: '3', - // // url: homeUrge, - // // key: 'urge', - // // path: conductInspectorPlanId - // // ? '/urge/learning' - // // : purchasedInspector - // // ? '/urge/timetable' - // // : '/urge/service', - // // desc: nextInspectorCourseDate && dayjs(nextInspectorCourseDate).format('MM-DD HH:mm'), - // // showTip: true, - // }, { id: '5', url: homeTask, @@ -95,6 +76,9 @@ const navMain = computed(() => { ] }) +const navMainVisible = computed(() => navMain.value.filter(item => !(item.show === false))) +const navMainIsFourGrid = computed(() => navMainVisible.value.length === 4) + const navLeft = computed(() => { const hideAppSchools = ['勤智', '德艺', '领航', '黄古'] // 如果是特定学校的 @@ -467,9 +451,9 @@ onUnmounted(() => { @click="clickPhoto" > --> -
-