From 412cde0656249adc0dc71f488b33a02a62f393a4 Mon Sep 17 00:00:00 2001 From: ZhaiSoul <842607283@qq.com> Date: Thu, 13 Mar 2025 22:37:05 +0800 Subject: [PATCH] feat: add Player i18n keys --- web/public/locales/en/components/player.json | 22 +++++++++++ .../locales/zh-CN/components/player.json | 22 +++++++++++ web/src/components/player/LivePlayer.tsx | 20 +++++++--- web/src/components/player/PlayerStats.tsx | 38 ++++++++++++------- 4 files changed, 82 insertions(+), 20 deletions(-) diff --git a/web/public/locales/en/components/player.json b/web/public/locales/en/components/player.json index 7e4fec646..8f565e75a 100644 --- a/web/public/locales/en/components/player.json +++ b/web/public/locales/en/components/player.json @@ -5,5 +5,27 @@ "submitFrigatePlus": { "title": "Submit this frame to Frigate+?", "submit": "Submit" + }, + "livePlayerRequiredIOSVersion": "iOS 17.1 or greater is required for this live stream type.", + "streamOffline": { + "title": "Stream Offline", + "desc": "No frames have been received on the {{cameraName}} detect stream, check error logs" + }, + "cameraDisabled": "Camera is disabled", + "stats": { + "streamType": "Stream Type:", + "streamType.short": "Type", + "bandwidth": "Bandwidth:", + "bandwidth.short": "Bandwidth", + "latency": "Latency:", + "latency.short": "Latency", + "latency.value": "{{secounds}} seconds", + "latency.short.value": "{{secounds}} sec", + "totalFrames": "Total Frames:", + "droppedFrames": "Dropped Frames:", + "droppedFrames.short": "Dropped", + "droppedFrames.short.value": "{{droppedFrames}} frames", + "decodedFrames": "Decoded Frames:", + "droppedFrameRate": "Dropped Frame Rate:" } } \ No newline at end of file diff --git a/web/public/locales/zh-CN/components/player.json b/web/public/locales/zh-CN/components/player.json index 0d582e472..ffb64e0d3 100644 --- a/web/public/locales/zh-CN/components/player.json +++ b/web/public/locales/zh-CN/components/player.json @@ -5,5 +5,27 @@ "submitFrigatePlus": { "title": "提交此帧到 Frigate+?", "submit": "提交" + }, + "livePlayerRequiredIOSVersion": "此直播流类型需要 iOS 17.1 或更高版本。", + "streamOffline": { + "title": "视频流离线", + "desc": "未在 {{cameraName}} 的 detect 流上接收到任何帧,请检查错误日志" + }, + "cameraDisabled": "摄像机已禁用", + "stats": { + "streamType": "流类型:", + "streamType.short": "类型", + "bandwidth": "带宽:", + "bandwidth.short": "带宽", + "latency": "延迟:", + "latency.short": "延迟", + "latency.value": "{{secounds}} 秒", + "latency.short.value": "{{secounds}} 秒", + "totalFrames": "总帧数:", + "droppedFrames": "丢帧数:", + "droppedFrames.short": "丢帧", + "droppedFrames.short.value": "{{droppedFrames}} 帧", + "decodedFrames": "解码帧数:", + "droppedFrameRate": "丢帧率:" } } \ No newline at end of file diff --git a/web/src/components/player/LivePlayer.tsx b/web/src/components/player/LivePlayer.tsx index c34f4c94c..b73e7991c 100644 --- a/web/src/components/player/LivePlayer.tsx +++ b/web/src/components/player/LivePlayer.tsx @@ -23,6 +23,7 @@ import { TooltipPortal } from "@radix-ui/react-tooltip"; import { baseUrl } from "@/api/baseUrl"; import { PlayerStats } from "./PlayerStats"; import { LuVideoOff } from "react-icons/lu"; +import { Trans, useTranslation } from "react-i18next"; type LivePlayerProps = { cameraRef?: (ref: HTMLDivElement | null) => void; @@ -71,6 +72,8 @@ export default function LivePlayer({ onError, onResetLiveMode, }: LivePlayerProps) { + const { t } = useTranslation(["components/player"]); + const internalContainerRef = useRef(null); // stats @@ -272,7 +275,7 @@ export default function LivePlayer({ } else { player = (
- iOS 17.1 or greater is required for this live stream type. + {t("livePlayerRequiredIOSVersion")}
); } @@ -400,12 +403,17 @@ export default function LivePlayer({ {offline && !showStillWithoutActivity && cameraEnabled && (
-

Stream offline

+

{t("streamOffline.title")}

- No frames have been received on the{" "} - {capitalizeFirstLetter(cameraConfig.name)} detect{" "} - stream, check error logs + + streamOffline.desc +

@@ -416,7 +424,7 @@ export default function LivePlayer({

- Camera is disabled + {t("cameraDisabled")}

diff --git a/web/src/components/player/PlayerStats.tsx b/web/src/components/player/PlayerStats.tsx index 50c49b846..4289b1257 100644 --- a/web/src/components/player/PlayerStats.tsx +++ b/web/src/components/player/PlayerStats.tsx @@ -1,5 +1,6 @@ import { cn } from "@/lib/utils"; import { PlayerStatsType } from "@/types/live"; +import { useTranslation } from "react-i18next"; type PlayerStatsProps = { stats: PlayerStatsType; @@ -7,45 +8,46 @@ type PlayerStatsProps = { }; export function PlayerStats({ stats, minimal }: PlayerStatsProps) { + const { t } = useTranslation(["components/player"]); const fullStatsContent = ( <>

- Stream Type:{" "} + {t("stats.streamType")}{" "} {stats.streamType}

- Bandwidth:{" "} + {t("stats.bandwidth")}{" "} {stats.bandwidth.toFixed(2)} kbps

{stats.latency != undefined && (

- Latency:{" "} + {t("stats.latency")}{" "} 2 ? "text-danger" : ""}`} > - {stats.latency.toFixed(2)} seconds + {t("stats.latency.value", { secounds: stats.latency.toFixed(2) })}

)}

- Total Frames:{" "} + {t("stats.totalFrames")}{" "} {stats.totalFrames}

{stats.droppedFrames != undefined && (

- Dropped Frames:{" "} + {t("stats.droppedFrames")}{" "} {stats.droppedFrames}

)} {stats.decodedFrames != undefined && (

- Decoded Frames:{" "} + {t("stats.decodedFrames")}{" "} {stats.decodedFrames}

)} {stats.droppedFrameRate != undefined && (

- Dropped Frame Rate:{" "} + {t("stats.droppedFrameRate")}{" "} {stats.droppedFrameRate.toFixed(2)}% @@ -57,27 +59,35 @@ export function PlayerStats({ stats, minimal }: PlayerStatsProps) { const minimalStatsContent = (

- Type + {t("stats.streamType.short")} {stats.streamType}
- Bandwidth{" "} + {t("stats.bandwidth.short")}{" "} {stats.bandwidth.toFixed(2)} kbps
{stats.latency != undefined && (
- Latency + {t("stats.latency.short")} = 2 ? "text-danger" : ""}`} > - {stats.latency.toFixed(2)} sec + {t("stats.latency.short.value", { + secounds: stats.latency.toFixed(2), + })}
)} {stats.droppedFrames != undefined && (
- Dropped - {stats.droppedFrames} frames + + {t("stats.droppedFrames.short")} + + + {t("stats.droppedFrames.short.value", { + droppedFrames: stats.droppedFrames, + })} +
)}