Skip to content

Commit c89bfe5

Browse files
authored
Merge pull request #9 from ShouChenICU/dev
1、新增分辨率选项 2、后台日志脱敏
2 parents dad005d + cc65361 commit c89bfe5

5 files changed

Lines changed: 77 additions & 12 deletions

File tree

components/NavBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ onMounted(() => {
3636
<img src="/favicon.webp" alt="web camera" class="size-6 mr-2" />
3737
<div>
3838
<span>WebCamera</span>
39-
<span class="ml-2 text-xs">v0.1.2</span>
39+
<span class="ml-2 text-xs">v0.1.3</span>
4040
</div>
4141
</NuxtLink>
4242

i18n.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ export default defineI18nConfig(() => ({
3535
connectionID: 'Connection ID',
3636
audioDev: 'Audio device',
3737
videoDev: 'Video device',
38+
resolution: 'Resolution',
39+
'4K_priority': '4K Priority',
40+
'2K_priority': '2K Priority',
41+
'1080P_priority': '1080P Priority',
42+
'720P_priority': '720P Priority',
3843
record: 'Record',
3944
recordSettings: 'Record settings',
4045
format: 'Format',
@@ -119,6 +124,11 @@ export default defineI18nConfig(() => ({
119124
connectionID: '连接ID',
120125
audioDev: '音频设备',
121126
videoDev: '视频设备',
127+
resolution: '分辨率',
128+
'4K_priority': '4K优先',
129+
'2K_priority': '2K优先',
130+
'1080P_priority': '1080P优先',
131+
'720P_priority': '720P优先',
122132
record: '录制',
123133
recordSettings: '录制设置',
124134
format: '格式',

pages/camera.vue

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,17 @@ const curStream = ref<MediaStream>()
1212
// 当前音视频设备
1313
const curVideoDevInfo = ref({ id: undefined, label: undefined })
1414
const curAudioDevInfo = ref({ id: undefined, label: undefined })
15+
const curResolution = ref('4K_priority')
1516
1617
// 可选音视频设备
1718
const videoDevList = ref<Array<any>>([])
1819
const audioDevList = ref<Array<any>>([])
20+
const resolutionList = ref<Array<any>>([
21+
'4K_priority',
22+
'2K_priority',
23+
'1080P_priority',
24+
'720P_priority'
25+
])
1926
2027
const isOpenAudio = ref(true)
2128
@@ -261,8 +268,31 @@ function closeStream() {
261268
async function refreshStream() {
262269
closeStream()
263270
try {
271+
// 解析分辨率
272+
let idealWidth = 3840
273+
let idealHeight = 2160
274+
if (curResolution.value === '2K_priority') {
275+
idealWidth = 2560
276+
idealHeight = 1440
277+
} else if (curResolution.value === '1080P_priority') {
278+
idealWidth = 1920
279+
idealHeight = 1080
280+
} else if (curResolution.value === '720P_priority') {
281+
idealWidth = 1280
282+
idealHeight = 720
283+
}
284+
// 如果是移动端,则翻转宽高
285+
// if (window.innerHeight > window.innerWidth) {
286+
// const tmp = idealWidth
287+
// idealWidth = idealHeight
288+
// idealHeight = tmp
289+
// }
264290
curStream.value = await navigator?.mediaDevices?.getUserMedia({
265-
video: { deviceId: curVideoDevInfo.value.id },
291+
video: {
292+
deviceId: curVideoDevInfo.value.id,
293+
width: { ideal: idealWidth },
294+
height: { ideal: idealHeight }
295+
},
266296
audio: isOpenAudio.value ? { deviceId: curAudioDevInfo.value.id } : false
267297
})
268298
if (!curStream.value) {
@@ -290,6 +320,7 @@ async function refreshStream() {
290320
})
291321
localStorage.setItem('audioDev', JSON.stringify(curAudioDevInfo.value))
292322
}
323+
localStorage.setItem('videoResolution', curResolution.value)
293324
videoElm.value.srcObject = curStream.value
294325
} catch (e) {
295326
logInfo.value.logs.push({
@@ -328,6 +359,10 @@ onMounted(async () => {
328359
if (tmpDev) {
329360
curAudioDevInfo.value = JSON.parse(tmpDev)
330361
}
362+
let tmpResolution = localStorage.getItem('videoResolution')
363+
if (tmpResolution) {
364+
curResolution.value = tmpResolution
365+
}
331366
332367
// 更新媒体流
333368
if (!(await refreshStream())) {
@@ -364,6 +399,7 @@ onMounted(async () => {
364399
365400
watch(curAudioDevInfo, refreshStream)
366401
watch(curVideoDevInfo, refreshStream)
402+
watch(curResolution, refreshStream)
367403
watch(isOpenAudio, refreshStream)
368404
369405
// 获取上次使用的连接ID
@@ -399,15 +435,27 @@ onUnmounted(() => {
399435
<div class="bg-neutral-50 dark:bg-black" :style="{ 'padding-top': navHeight + 'px' }">
400436
<div class="overflow-y-auto md:flex md:flex-row p-4">
401437
<div class="md:flex-1 md:p-4 space-y-4">
438+
<!-- 选择视频设备 -->
402439
<UFormGroup :label="$t('label.videoDev')">
403440
<USelectMenu :options="videoDevList" v-model="curVideoDevInfo" :disabled="isConnecting" />
404441
</UFormGroup>
442+
443+
<UFormGroup :label="$t('label.resolution')">
444+
<USelectMenu :options="resolutionList" v-model="curResolution" :disabled="isConnecting">
445+
<template #label>{{ $t('label.' + curResolution) }}</template>
446+
<template #option="opt">{{ $t('label.' + opt.option) }}</template>
447+
</USelectMenu>
448+
</UFormGroup>
449+
450+
<!-- 选择音频设备 -->
405451
<UFormGroup :label="$t('label.audioDev')">
406452
<USelectMenu
407453
:options="audioDevList"
408454
v-model="curAudioDevInfo"
409455
:disabled="!isOpenAudio || isConnecting"
410456
/>
457+
458+
<!-- 是否启用音频 -->
411459
</UFormGroup>
412460
<div class="flex flex-row items-center justify-end gap-4 text-sm">
413461
<label class="contents">
@@ -416,6 +464,7 @@ onUnmounted(() => {
416464
</label>
417465
</div>
418466

467+
<!-- 连接ID -->
419468
<UFormGroup :label="$t('label.connectionID')">
420469
<UInput
421470
:type="isShowConnectId ? 'text' : 'password'"

pages/monitor.vue

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script setup lang="ts">
22
import { RTCNode } from '#imports'
3-
import type { _1 } from '#tailwind-config/theme/aspectRatio'
43
import { SSE } from 'sse.js'
54
65
const { t } = useI18n()
@@ -42,7 +41,7 @@ const sse = shallowRef<SSE>()
4241
const rtcNode = shallowRef<RTCNode>()
4342
4443
let stateJobId: any
45-
let watchDogJonId: any
44+
let watchDogJobId: any
4645
4746
const isModernFileAPISupport = ref(false)
4847
@@ -75,11 +74,18 @@ async function startRecording() {
7574
recordSize.value = 0
7675
videoChunks = []
7776
if (isModernFileAPIAvailable()) {
78-
// 支持现代化文件访问,数据直接写入磁盘
79-
fileHandler = await showSaveFilePicker({
80-
startIn: 'downloads',
81-
suggestedName: 'Video_' + formatDateTime(new Date(), 'yyyyMMddHHmmss') + '.webm'
82-
})
77+
try {
78+
// 支持现代化文件访问,数据直接写入磁盘
79+
fileHandler = await showSaveFilePicker({
80+
startIn: 'downloads',
81+
suggestedName: 'Video_' + formatDateTime(new Date(), 'yyyyMMddHHmmss') + '.webm'
82+
})
83+
} catch (e) {
84+
console.warn(e)
85+
recordingStartTime.value = 0
86+
isRecording.value = false
87+
return
88+
}
8389
const writer = await fileHandler.createWritable()
8490
8591
mediaRecoder = new MediaRecorder(curStream.value, { mimeType: recordSetting.value.mimeType })
@@ -142,7 +148,7 @@ function closeStream() {
142148
function disconnect() {
143149
stopRecording()
144150
clearInterval(stateJobId)
145-
clearInterval(watchDogJonId)
151+
clearInterval(watchDogJobId)
146152
logInfo.value.logs.push({
147153
time: toISOStringWithTimezone(new Date()),
148154
type: 'info',
@@ -311,7 +317,7 @@ function doConnect() {
311317
connectSignServer()
312318
313319
// 超时检测
314-
watchDogJonId = setTimeout(() => {
320+
watchDogJobId = setTimeout(() => {
315321
if (isConnecting.value) {
316322
logInfo.value.logs.push({
317323
time: toISOStringWithTimezone(new Date()),

server/utils/sseMap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const sseMap = new TTLCache<string, any>({
66
ttl: 600e3,
77
dispose: (val, key) => {
88
try {
9-
console.log(toISOStringWithTimezone(new Date()) + ' dispose: ' + key)
9+
console.log(toISOStringWithTimezone(new Date()) + ' dispose: ' + key.substring(0, 6) + '...')
1010
val.close()
1111
} catch (e) {
1212
console.warn(e)

0 commit comments

Comments
 (0)