feat: 使用全局ip与port配置摄像头
This commit is contained in:
parent
48501d79e2
commit
15f9b68e7d
|
@ -5,19 +5,7 @@
|
|||
<div class="card bg-base-200 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-primary">
|
||||
<svg
|
||||
class="w-6 h-6"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4"
|
||||
/>
|
||||
</svg>
|
||||
<Settings class="w-6 h-6" />
|
||||
控制面板
|
||||
</h2>
|
||||
|
||||
|
@ -45,19 +33,7 @@
|
|||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-figure text-secondary">
|
||||
<svg
|
||||
class="w-8 h-8"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<Video class="w-8 h-8" />
|
||||
</div>
|
||||
<div class="stat-title">视频规格</div>
|
||||
<div class="stat-value text-secondary">
|
||||
|
@ -71,19 +47,7 @@
|
|||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-figure text-accent">
|
||||
<svg
|
||||
class="w-8 h-8"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
|
||||
/>
|
||||
</svg>
|
||||
<Users class="w-8 h-8" />
|
||||
</div>
|
||||
<div class="stat-title">连接数</div>
|
||||
<div class="stat-value text-accent">
|
||||
|
@ -124,70 +88,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 摄像头配置 -->
|
||||
<div class="card bg-base-100 shadow-sm mt-4">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm text-info">
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
</svg>
|
||||
摄像头配置
|
||||
</h3>
|
||||
|
||||
<div class="flex flex-row justify-around gap-4">
|
||||
<div class="grow">
|
||||
<IpInputField
|
||||
v-model="tempCameraConfig.address"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grow">
|
||||
<PortInputField
|
||||
v-model="tempCameraConfig.port"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-actions justify-end mt-4">
|
||||
<button
|
||||
class="btn btn-ghost"
|
||||
@click="resetCameraConfig"
|
||||
:disabled="isDefaultCamera"
|
||||
>
|
||||
<RotateCcw class="w-4 h-4" />
|
||||
重置
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="confirmCameraConfig"
|
||||
:disabled="!isValidCameraConfig || !hasChangesCamera"
|
||||
:class="{ loading: configuring }"
|
||||
>
|
||||
<Save class="w-4 h-4" v-if="!configuring" />
|
||||
{{ configuring ? "配置中..." : "保存配置" }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="card-actions justify-end mt-4">
|
||||
<button
|
||||
|
@ -195,26 +95,8 @@
|
|||
@click="refreshStatus"
|
||||
:disabled="loading"
|
||||
>
|
||||
<svg
|
||||
v-if="loading"
|
||||
class="animate-spin h-4 w-4 mr-2"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
class="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
></circle>
|
||||
<path
|
||||
class="opacity-75"
|
||||
fill="currentColor"
|
||||
d="m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
<RefreshCw v-if="loading" class="animate-spin h-4 w-4 mr-2" />
|
||||
<RefreshCw v-else class="h-4 w-4 mr-2" />
|
||||
{{ loading ? "刷新中..." : "刷新状态" }}
|
||||
</button>
|
||||
<button
|
||||
|
@ -222,26 +104,8 @@
|
|||
@click="testConnection"
|
||||
:disabled="testing"
|
||||
>
|
||||
<svg
|
||||
v-if="testing"
|
||||
class="animate-spin h-4 w-4 mr-2"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
class="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
></circle>
|
||||
<path
|
||||
class="opacity-75"
|
||||
fill="currentColor"
|
||||
d="m4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path>
|
||||
</svg>
|
||||
<RefreshCw v-if="testing" class="animate-spin h-4 w-4 mr-2" />
|
||||
<TestTube v-else class="h-4 w-4 mr-2" />
|
||||
{{ testing ? "测试中..." : "测试连接" }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -252,19 +116,7 @@
|
|||
<div class="card bg-base-200 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-primary">
|
||||
<svg
|
||||
class="w-6 h-6"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<Video class="w-6 h-6" />
|
||||
视频预览
|
||||
</h2>
|
||||
|
||||
|
@ -294,20 +146,7 @@
|
|||
<div class="card bg-error text-white shadow-lg w-full max-w-lg">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
||||
/>
|
||||
</svg>
|
||||
<AlertTriangle class="h-6 w-6" />
|
||||
视频流加载失败
|
||||
</h3>
|
||||
<p>无法连接到视频服务器,请检查以下内容:</p>
|
||||
|
@ -334,19 +173,7 @@
|
|||
class="absolute inset-0 flex items-center justify-center text-white"
|
||||
>
|
||||
<div class="text-center">
|
||||
<svg
|
||||
class="w-16 h-16 mx-auto mb-4 opacity-50"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<Video class="w-16 h-16 mx-auto mb-4 opacity-50" />
|
||||
<p class="text-lg opacity-75">{{ videoStatus }}</p>
|
||||
<p class="text-sm opacity-60 mt-2">
|
||||
点击"播放视频流"按钮开始查看实时视频
|
||||
|
@ -370,20 +197,7 @@
|
|||
role="button"
|
||||
class="btn btn-sm btn-outline btn-accent"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<MoreHorizontal class="w-4 h-4 mr-1" />
|
||||
更多功能
|
||||
</div>
|
||||
<ul
|
||||
|
@ -391,15 +205,22 @@
|
|||
class="dropdown-content z-[1] menu p-2 shadow bg-base-200 rounded-box w-52"
|
||||
>
|
||||
<li>
|
||||
<a @click="openInNewTab(streamInfo.htmlUrl)"
|
||||
>在新标签打开视频页面</a
|
||||
>
|
||||
<a @click="openInNewTab(streamInfo.htmlUrl)">
|
||||
<ExternalLink class="w-4 h-4" />
|
||||
在新标签打开视频页面
|
||||
</a>
|
||||
</li>
|
||||
<li><a @click="takeSnapshot">获取并下载快照</a></li>
|
||||
<li>
|
||||
<a @click="copyToClipboard(streamInfo.mjpegUrl)"
|
||||
>复制MJPEG地址</a
|
||||
>
|
||||
<a @click="takeSnapshot">
|
||||
<Camera class="w-4 h-4" />
|
||||
获取并下载快照
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @click="copyToClipboard(streamInfo.mjpegUrl)">
|
||||
<Copy class="w-4 h-4" />
|
||||
复制MJPEG地址
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -408,25 +229,7 @@
|
|||
@click="startStream"
|
||||
:disabled="isPlaying"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<Play class="w-4 h-4 mr-1" />
|
||||
播放视频流
|
||||
</button>
|
||||
<button
|
||||
|
@ -434,25 +237,7 @@
|
|||
@click="stopStream"
|
||||
:disabled="!isPlaying"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"
|
||||
/>
|
||||
</svg>
|
||||
<Square class="w-4 h-4 mr-1" />
|
||||
停止视频流
|
||||
</button>
|
||||
</div>
|
||||
|
@ -464,19 +249,7 @@
|
|||
<div class="card bg-base-200 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-primary">
|
||||
<svg
|
||||
class="w-6 h-6"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
<FileText class="w-6 h-6" />
|
||||
操作日志
|
||||
</h2>
|
||||
|
||||
|
@ -511,21 +284,30 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive, watch, onMounted, onUnmounted } from "vue";
|
||||
import { useStorage } from "@vueuse/core";
|
||||
import { z } from "zod";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import {
|
||||
Save,
|
||||
RotateCcw,
|
||||
Settings,
|
||||
Video,
|
||||
Users,
|
||||
RefreshCw,
|
||||
TestTube,
|
||||
Play,
|
||||
Square,
|
||||
ExternalLink,
|
||||
Camera,
|
||||
Copy,
|
||||
FileText,
|
||||
AlertTriangle,
|
||||
MoreHorizontal,
|
||||
} from "lucide-vue-next";
|
||||
import { VideoStreamClient, CameraConfigRequest } from "@/APIClient";
|
||||
import { IpInputField, PortInputField } from "@/components/InputField";
|
||||
import { useEquipments } from "@/stores/equipments";
|
||||
|
||||
const eqps = useEquipments();
|
||||
|
||||
// 状态管理
|
||||
const loading = ref(false);
|
||||
const testing = ref(false);
|
||||
const configuring = ref(false);
|
||||
const testingCamera = ref(false);
|
||||
const isPlaying = ref(false);
|
||||
const hasVideoError = ref(false);
|
||||
const videoStatus = ref('点击"播放视频流"按钮开始查看实时视频');
|
||||
|
@ -551,92 +333,6 @@ const streamInfo = ref({
|
|||
snapshotUrl: "",
|
||||
});
|
||||
|
||||
// 摄像头配置类型定义
|
||||
const cameraConfigSchema = z.object({
|
||||
address: z
|
||||
.string()
|
||||
.ip({ version: "v4", message: "请输入有效的IPv4地址" })
|
||||
.min(1, "请输入IP地址"),
|
||||
port: z
|
||||
.number()
|
||||
.int("端口必须是整数")
|
||||
.min(1, "端口必须大于0")
|
||||
.max(65535, "端口必须小于等于65535"),
|
||||
});
|
||||
|
||||
type CameraConfig = z.infer<typeof cameraConfigSchema>;
|
||||
|
||||
// 默认摄像头配置
|
||||
const defaultCameraConfig: CameraConfig = {
|
||||
address: "192.168.1.100",
|
||||
port: 8080,
|
||||
};
|
||||
|
||||
// 使用 VueUse 存储摄像头配置
|
||||
const cameraConfig = useStorage<CameraConfig>(
|
||||
"camera-config",
|
||||
defaultCameraConfig,
|
||||
localStorage,
|
||||
{
|
||||
serializer: {
|
||||
read: (value: string) => {
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
const result = cameraConfigSchema.safeParse(parsed);
|
||||
return result.success ? result.data : defaultCameraConfig;
|
||||
} catch {
|
||||
return defaultCameraConfig;
|
||||
}
|
||||
},
|
||||
write: (value: CameraConfig) => JSON.stringify(value),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// 临时摄像头配置(用于编辑)
|
||||
const tempCameraConfig = reactive<CameraConfig>({
|
||||
address: cameraConfig.value.address,
|
||||
port: cameraConfig.value.port,
|
||||
});
|
||||
|
||||
// 摄像头配置验证
|
||||
const isValidCameraConfig = computed(() => {
|
||||
return tempCameraConfig.address && tempCameraConfig.port &&
|
||||
tempCameraConfig.port >= 1 && tempCameraConfig.port <= 65535 &&
|
||||
/^(\d{1,3}\.){3}\d{1,3}$/.test(tempCameraConfig.address);
|
||||
});
|
||||
|
||||
// 检查摄像头配置是否有更改
|
||||
const hasChangesCamera = computed(() => {
|
||||
return (
|
||||
tempCameraConfig.address !== cameraConfig.value.address ||
|
||||
tempCameraConfig.port !== cameraConfig.value.port
|
||||
);
|
||||
});
|
||||
|
||||
const isDefaultCamera = computed(() => {
|
||||
return (
|
||||
defaultCameraConfig.address === tempCameraConfig.address &&
|
||||
defaultCameraConfig.port === tempCameraConfig.port
|
||||
);
|
||||
});
|
||||
|
||||
// 重置摄像头配置
|
||||
const resetCameraConfig = () => {
|
||||
tempCameraConfig.address = defaultCameraConfig.address;
|
||||
tempCameraConfig.port = defaultCameraConfig.port;
|
||||
};
|
||||
|
||||
// 监听存储的摄像头配置变化,同步到临时配置
|
||||
watch(
|
||||
cameraConfig,
|
||||
(newConfig) => {
|
||||
tempCameraConfig.address = newConfig.address;
|
||||
tempCameraConfig.port = newConfig.port;
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
const currentVideoSource = ref("");
|
||||
const logs = ref<Array<{ time: Date; level: string; message: string }>>([]);
|
||||
|
||||
|
@ -656,71 +352,6 @@ const addLog = (level: string, message: string) => {
|
|||
}
|
||||
};
|
||||
|
||||
// 加载摄像头配置
|
||||
const loadCameraConfig = async () => {
|
||||
try {
|
||||
addLog("info", "正在加载摄像头配置...");
|
||||
|
||||
const config = await videoClient.getCameraConfig();
|
||||
if (config && config.address && config.port) {
|
||||
// 更新存储的配置
|
||||
cameraConfig.value = {
|
||||
address: config.address,
|
||||
port: config.port,
|
||||
};
|
||||
addLog("success", `摄像头配置加载成功: ${config.address}:${config.port}`);
|
||||
} else {
|
||||
addLog("warning", "未找到保存的摄像头配置,使用默认值");
|
||||
}
|
||||
} catch (error) {
|
||||
addLog("error", `加载摄像头配置失败: ${error}`);
|
||||
console.error("加载摄像头配置失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 确认摄像头配置
|
||||
const confirmCameraConfig = async () => {
|
||||
if (!isValidCameraConfig.value) return;
|
||||
|
||||
configuring.value = true;
|
||||
try {
|
||||
addLog(
|
||||
"info",
|
||||
`正在配置摄像头: ${tempCameraConfig.address}:${tempCameraConfig.port}`,
|
||||
);
|
||||
|
||||
// 模拟保存延迟
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
|
||||
// 保存配置
|
||||
cameraConfig.value = {
|
||||
address: tempCameraConfig.address,
|
||||
port: tempCameraConfig.port,
|
||||
};
|
||||
|
||||
// 使用新配置调用API
|
||||
const result = await videoClient.configureCamera(
|
||||
CameraConfigRequest.fromJS({
|
||||
address: tempCameraConfig.address,
|
||||
port: tempCameraConfig.port,
|
||||
}),
|
||||
);
|
||||
|
||||
if (result) {
|
||||
addLog("success", "摄像头配置保存成功");
|
||||
// 配置成功后刷新状态
|
||||
await refreshStatus();
|
||||
} else {
|
||||
addLog("error", "摄像头配置保存失败");
|
||||
}
|
||||
} catch (error) {
|
||||
addLog("error", `配置摄像头失败: ${error}`);
|
||||
console.error("配置摄像头失败:", error);
|
||||
} finally {
|
||||
configuring.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (time: Date) => {
|
||||
return time.toLocaleTimeString();
|
||||
|
@ -798,6 +429,13 @@ const takeSnapshot = async () => {
|
|||
const refreshStatus = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
addLog("info", "正在配置并初始化摄像头...");
|
||||
const boardconfig = new CameraConfigRequest({
|
||||
address: eqps.boardAddr,
|
||||
port: eqps.boardPort,
|
||||
});
|
||||
await videoClient.configureCamera(boardconfig);
|
||||
|
||||
addLog("info", "正在获取服务状态...");
|
||||
|
||||
// 使用新的API方法名称
|
||||
|
@ -909,7 +547,6 @@ const stopStream = () => {
|
|||
// 生命周期
|
||||
onMounted(async () => {
|
||||
addLog("info", "HTTP 视频流页面已加载");
|
||||
await loadCameraConfig();
|
||||
await refreshStatus();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue