Browse Source

feat: 国际化优化
1. 优化了更多的国际化文本内容

kindring 3 weeks ago
parent
commit
f3d7950e61

+ 186 - 133
web_src/src/assets/i18/lang/en-us.js

@@ -1,14 +1,15 @@
+// en-us.js
 export default {
     lang: 'English',
-    title: 'szhfy Video Platform',
+    title: 'HeFangYuan Video Platform',
     username: 'Username',
     password: 'Password',
     login: 'Login',
     register: 'Register Admin',
-    copyright: 'szhfy Tech © All Rights Reserved',
+    copyright: 'HeFangYuan Technology © All Rights Reserved',
     viewNow: 'View Now',
     view: 'View',
-    loading: 'loading...',
+    loading: 'Loading...',
     search: 'Search',
     save: 'Save',
     cancel: 'Cancel',
@@ -16,56 +17,65 @@ export default {
     delete: 'Delete',
     confirm: 'Confirm',
     operation: 'Operation',
-    operationSuccess: 'Operation Success',
+    operationSuccess: 'Operation Successful',
     name: 'Name',
     unknown: 'Unknown',
     pleaseSelect: 'Please Select',
-    state: "state",
+    state: 'Status',
     refresh: 'Refresh',
-    addSuccess: 'Add Success',
+    addSuccess: 'Added Successfully',
     keyword: 'Keyword',
-    readState: "read state",
+    readState: "Read Status",
     ignoreAll: 'Ignore All',
     readEnum: {
-        unread: 'unread',
-        read: 'read',
-        ignore: 'ignore'
+        unread: 'Unread',
+        ignore: 'Ignored',
+        read: 'Read',
     },
-    uploadTime: 'UploadTime',
+    address: 'Address',
+    copy: 'Copy',
+    uploadTime: 'Upload Time',
     notification: {
-        register: 'No admin account, please register first',
+        register: 'No administrator account, please register first',
         success: 'Admin account registered successfully',
         timeout: 'Login timeout',
         error: 'Login failed, incorrect username or password',
         warning: 'Please enter username and password',
-        copyTips: 'Copy Success',
-        copyError: 'Copy Failed',
-        queryFailed: 'Request Failed {msg}',
-        loadSipFail: 'Load Sip Config Failed',
-        deleteDevice: 'Are you sure to delete the device?',
-        editDeviceMessage: 'Device modified successfully, the channel character set will take effect after the next update',
+        copyTips: 'Copied successfully',
+        copyError: 'Copy failed',
+        queryFailed: 'Request failed {msg}',
+        loadSipFail: 'Failed to get SIP configuration',
+        deleteDevice: 'Are you sure to delete this device?',
+        editDeviceMessage: 'Device modified successfully, channel charset will take effect after next update',
         nameNotEmpty: 'Name cannot be empty',
-        waitForQuery: 'Please wait for the request to complete',
-        ignoreTitle: 'This operation will ignore all alarm content, please confirm again?',
+        waitingForQuery: 'Please wait for the request to complete',
+        ignoreTitle: 'This operation will ignore all alarms, please confirm?',
+        pushFail: "Stream push failed, {msg}",
+        noStreamInfo: "Unable to get stream information",
+        noStreamSize: "Unable to get video dimensions",
+        noConnectZlm: "Unable to connect to ZLM",
+        zlmFailMsg: `<span>Failed to connect to ZLM service {msg}</span> <br/><a href=\"{url}\" target=\"_blank\"><span>Manual access</span></a>`,
+        sdpFail: `SDP interaction failed, recommend using Chrome browser`,
+        playSuccess: 'Playback successful'
     },
     menu: {
         console: 'Dashboard',
-        liveMonitor: 'Live Monitor',
+        liveMonitor: 'Multi-screen Monitoring',
         deviceList: 'GB Devices',
         map: 'Electronic Map',
-        pushList: 'Push Streams',
-        pullProxy: 'Pull Proxies',
+        pushList: 'Stream Push List',
+        pullProxy: 'Stream Pull Proxy',
         cloudRecord: 'Cloud Recording',
-        mediaServer: 'Media Servers',
+        mediaServer: 'Media Server Management',
         cascade: 'GB Cascading',
         aiManager: 'AI Management',
         alarmCenter: 'Alarm Center',
-        alarmInfo: 'Alarm Info',
-        system: 'System',
+        alarmInfo: 'Alarm Details',
+        system: 'System Management',
     },
     user: {
-        welcome: 'Welcome',
-        profile: 'User Center',
+        welcome: 'Welcome back',
+        profile: 'Profile',
         changePassword: 'Change Password',
         logout: 'Logout'
     },
@@ -74,136 +84,179 @@ export default {
         message: 'Fire alarm detected, please handle immediately!',
     },
     info: {
-        title: 'Platform Info',
+        title: 'Platform Information',
         message: 'HeFangYuan Video Platform',
         version: 'Version',
-        copyright: 'Copyright © 2020 HeFangYuan Tech'
+        copyright: 'Copyright © 2020 HeFangYuan Technology',
     },
     sips: {
-        edit: "Edit Sip Config",
-        all: "all sip config"
+        edit: "Edit SIP Configuration",
+        all: "All SIP Configurations"
     },
     device: {
-        title: "device",
-        subDir: "sub directory",
-        list: "device list",
-        all: "all device",
-        id: "device id",
-        ip: "device ip",
-        name: "device name",
+        title: "Device",
+        subDir: "Subdirectory",
+        list: "Device List",
+        all: "All Devices",
+        id: "Device ID",
+        ip: "Device IP",
+        name: "Device Name",
         info: {
-            title: "device info",
-            battery: "Battery",
-            temp_env: "Env",
-            temp_cpu: "cpu",
-            version: "Version",
-            signal: "Signal"
+            title: "Device Information",
+            battery: "Battery Voltage",
+            temp_env: "Ambient Temperature",
+            temp_cpu: "CPU Temperature",
+            version: "Firmware Version",
+            signal: "Signal Strength",
         },
-        domain: "device domain",
-        manufacturer: "manufacturer",
-        onlineState: "online state",
-        offline: "offline",
-        online: "online",
-        enablePs: "enable ps",
-        disablePs: "disable ps",
-        lastKeepAlive: "last keep alive",
-        lastRegister: "last register",
-        offlineNotAllowLive: "offline device not allow live",
-        offlineNotAllowRecord: "offline device not allow record",
-        steamType: "stream type",
-        steamByTcpActive: "tcp active",
-        steamByTcpPassive: "tcp passive",
-        pushFail: "push fail",
-        pushSuccess: "push success",
-        getPushListFail: "get push list fail",
-        channelList: "channel list",
-        channelCount: "channel count",
-        channel: "channel",
-        channelId: "channel id",
-        channelName: "channel name",
-        channelType: "channel type",
-        channelCode: "channel code",
-        channelStatus: "channel status",
-        channelOnline: "channel online",
-        channelOffline: "channel offline",
-        ptzType: "ptz type",
-        enableAudio: "enable audio",
-        ptz: "ptz",
-        play: "play",
-        stop: "stop",
-        record: "device record",
-        ptzControl: "ptz control",
-        position: "position",
+        domain: "Device Domain",
+        manufacturer: "Manufacturer",
+        onlineState: "Online Status",
+        online: "Online",
+        offline: "Offline",
+        enablePs: "Enable PS",
+        disablePs: "Disable PS",
+        lastKeepAlive: "Last Keepalive Time",
+        lastRegister: "Last Registration Time",
+        offlineNotAllowLive: "Offline devices cannot be streamed",
+        offlineNotAllowPlayback: "Offline devices cannot be played back",
+        steamByTcpActive: "TCP Active",
+        steamByTcpPassive: "TCP Passive",
+        pushFail: "Stream push failed",
+        pushSuccess: "Stream pull successful",
+        rePush: "Re-push Stream",
+        getPushListFail: "Failed to get push list",
+        channelList: "Channel List",
+        channelCount: "Channel Count",
+        channel: "Channel",
+        channelId: "Channel ID",
+        channelName: "Channel Name",
+        channelType: "Channel Type",
+        channelCode: "Channel Code",
+        channelStatus: "Channel Status",
+        channelOnline: "Channel Online",
+        channelOffline: "Channel Offline",
+        ptzType: "PTZ Type",
+        enableAudio: "Enable Audio",
+        ptz: "PTZ",
+        play: "Play",
+        stop: "Stop",
+        record: "Device Recording",
+        ptzControl: "PTZ Control",
+        position: "Position",
         share: {
-            title: "share device",
-            openFailed: 'open share failed',
-            openSuccess: 'open share success',
-            closeFailed: 'close share failed',
-            close: 'close share',
-            closeSuccess: 'close share success',
+            title: "Share Device",
+            address: "Share URL",
+            openFailed: 'Failed to enable sharing, please retry later',
+            openSuccess: 'Sharing enabled successfully',
+            closeFailed: 'Failed to disable sharing, please retry later',
+            close: 'Disable Sharing',
+            closeSuccess: 'Sharing disabled successfully',
         },
         operator: {
-            add: "add device",
-            edit: "edit device",
-            delete: "delete device",
-            config: "config device",
-            viewOnline: "view online device",
+            add: "Add Device",
+            edit: "Edit Device",
+            delete: "Delete Device",
+            config: "Configure Device",
+            viewOnline: "View Online Devices",
         },
+        preset: {
+            title: "Preset",
+        }
     },
     aiManager: {
-        title: "AI manager",
-        list: "AI list",
-        all: "all AI",
-        id: "AI id",
-        name: "AI name",
-        type: "AI type",
-        status: "AI status",
-        enable: "enable",
-        disable: "disable",
-        triggerType: "triggerType",
-        isDetect: "isDetect",
-        detectType: "detectType",
+        title: "AI Manager",
+        list: "AI List",
+        all: "All AI",
+        id: "AI ID",
+        name: "AI Name",
+        type: "AI Type",
+        status: "AI Status",
+        enable: "Enabled",
+        disable: "Disabled",
+        triggerType: "Trigger Type",
+        isDetect: "Detection Status",
+        detectType: "Detection Type",
         operator: {
-            add: "addAI",
-            edit: "editAI",
-            delete: "deleteAI",
-            config: "configAI"
+            add: "Add AI",
+            edit: "Edit AI",
+            delete: "Delete AI",
+            config: "Configure AI",
         },
         data: {
-            title: "AI database",
-            list: "algorithm library list",
-            all: "all algorithm library",
-            id: "algorithm library id",
-            name: "algorithm library name",
-            type: "algorithm library type",
-            status: "algorithm library status",
-            version: "algorithm library version",
-            enable: "enable",
-            disable: "disable",
+            title: "AI",
+            list: "Algorithm Library List",
+            all: "All Algorithm Libraries",
+            id: "Algorithm Library ID",
+            name: "Algorithm Library Name",
+            type: "Algorithm Library Type",
+            status: "Algorithm Library Status",
+            version: "Algorithm Library Version",
+            enable: "Enabled",
+            disable: "Disabled",
             operator: {
-                add: "add algorithm library",
-                edit: "edit algorithm library",
-                delete: "delete algorithm library",
+                add: "Add Algorithm Library",
+                edit: "Edit Algorithm Library",
+                delete: "Delete Algorithm Library",
             },
         },
         triggerEnum: {
-            unlimited: "unlimited",
-            whiteList: "white list",
-            blackList: "black list",
+            unlimited: "Unlimited",
+            whiteList: "Whitelist",
+            blackList: "Blacklist",
         },
         typeEnum: {
-            face: "face",
-            fire: "fire",
-            plate: "plate",
-            crane: "crane",
-            craneTower: "crane tower",
-            construction: "construction",
-            craneLine: "crane line",
-            smoke: "smoke",
+            face: "Face Recognition",
+            fire: "Fire Detection",
+            plate: "License Plate Recognition",
+            crane: "Crane",
+            craneTower: "Tower Crane",
+            construction: "Construction Machinery",
+            craneLine: "Cable Foreign Object",
+            smoke: "Smoke Detection",
         },
         faceAlarmType: {
-            internal: "internal",
-            stranger: "stranger",
+            internal: "Internal Personnel",
+            stranger: "Stranger",
+        }
+    },
+    video: {
+        title: "Video",
+        liveTitle: "Video Streaming Interface",
+        play: {
+            webrtc: {
+                title: "WebRTC Player",
+                description: "Low-latency player, requires browser support"
+            },
+            flv: {
+                title: "FLV Player",
+                description: "For playing FLV format videos, supports AAC audio"
+            },
+            jessibuca: {
+                title: "H.265 Jessibuca Player",
+                description: "For playing H.265 format videos"
+            },
+            h265: {
+                title: "H.265 Player",
+                description: "For playing H.265 format videos"
+            },
+        },
+        media: {
+            title: "Media",
+            address: "Stream URL",
+            video: "Video",
+            audio: "Audio",
+            codec: "Codec",
+            resolution: "Resolution",
+            fps: "Frame Rate",
+            bitrate: "Bitrate",
+            frameSize: "Frame Size",
+            streamType: "Stream Type",
+        },
+        pushFailCode: {
+            100: "Unable to start stream, please retry later: {msg}",
+            101: "VOD port allocation exception",
+            102: "VOD timeout, no video stream received from device"
         }
     },
 }

+ 54 - 1
web_src/src/assets/i18/lang/zh-cn.js

@@ -1,3 +1,4 @@
+// zh-cn.js
 export default {
     lang: '简体中文',
     title: '合方圆视频平台',
@@ -31,6 +32,8 @@ export default {
         ignore: '忽略',
         read: '已读',
     },
+    address: '地址',
+    copy: '复制',
     uploadTime: '上传时间',
     notification: {
         register: '没有管理员账户, 请先注册账户',
@@ -47,6 +50,13 @@ export default {
         nameNotEmpty: '名称不能为空',
         waitingForQuery: '请等待请求完成',
         ignoreTitle: '此操作将忽略全部告警内容,请再次确认?',
+        pushFail: "推流失败, {msg}",
+        noStreamInfo: "无法获取流信息",
+        noStreamSize: "无法获取视频宽高",
+        noConnectZlm: "无法连接ZLM",
+        zlmFailMsg: `<span>连接zlm服务失败{msg}</span> <br/><a href=\"{url}\" target=\"_blank\"><span>手动访问</span></a>`,
+        sdpFail: `sdp 交互失败, 推荐使用chrome浏览器`,
+        playSuccess: '播放成功'
     },
     menu: {
         console: '控制台',
@@ -110,11 +120,11 @@ export default {
         lastRegister: "最后注册时间",
         offlineNotAllowLive: "离线设备不允许直播",
         offlineNotAllowPlayback: "离线设备不允许回放",
-        steamType: "流类型",
         steamByTcpActive: "TCP主动",
         steamByTcpPassive: "TCP被动",
         pushFail: "推流失败",
         pushSuccess: "拉流成功",
+        rePush: "重新推流",
         getPushListFail: "获取推流列表失败",
         channelList: "通道列表",
         channelCount: "通道数",
@@ -136,6 +146,7 @@ export default {
         position: "定位",
         share: {
             title: "分享设备",
+            address: "分享地址",
             openFailed: '开启分享失败, 稍后重试',
             openSuccess: '开启分享成功',
             closeFailed: '关闭分享失败, 稍后重试',
@@ -149,6 +160,9 @@ export default {
             config: "配置设备",
             viewOnline: "查看在线设备",
         },
+        preset: {
+            title: "预置位",
+        }
     },
     aiManager: {
         title: "AI管理",
@@ -206,4 +220,43 @@ export default {
             stranger: "陌生人",
         }
     },
+    video: {
+        title: "视频",
+        liveTitle: "视频推流界面",
+        play: {
+            webrtc: {
+                  title: "WebRTC播放器",
+                  description: "延迟较低的播放器,需要浏览器支持"
+              },
+            flv: {
+                title: "flv 播放器",
+                description: "用于播放flv格式视频,可支持aac音频"
+            },
+            jessibuca: {
+                title: "265 jessibuca播放器",
+                description: "用于播放265格式视频"
+            },
+            h265: {
+                title: "265 播放器",
+                description: "用于播放265格式视频"
+            },
+        },
+        media: {
+          title: "媒体信息",
+          address: "流地址",
+          video: "视频",
+          audio: "音频",
+          codec: "编码",
+          resolution: "分辨率",
+          fps: "帧率",
+          bitrate: "码率",
+          frameSize: "帧大小",
+          streamType: "流类型",
+        },
+        pushFailCode: {
+            100: "无法打开推流,请稍后重试: {msg}",
+            101: "点播端口分配异常",
+            102: "点播超时, 未收到设备视频流"
+        }
+    },
 }

+ 7 - 4
web_src/src/components/DeviceList.vue

@@ -10,8 +10,8 @@
                    size="mini"
         >
           <el-option
-              v-for="item in sipConfigs"
-              :key="item.value"
+              v-for="(item, i) in sipConfigs"
+              :key="item.value + i"
               :label="item.label"
               :value="item.value">
           </el-option>
@@ -41,7 +41,9 @@
       </div>
     </div>
     <!--设备列表-->
-    <el-table :data="deviceList" style="width: 100%;font-size: 12px;" :height="winHeight" header-row-class-name="table-header">
+    <el-table :data="deviceList" style="width: 100%;font-size: 12px;" :height="winHeight"
+              :row-key="record=>record.deviceId"
+              header-row-class-name="table-header">
       <el-table-column prop="name" :label="$t('name')" min-width="160">
       </el-table-column>
       <el-table-column prop="deviceId" :label="$t('device.id')" min-width="200" >
@@ -274,10 +276,11 @@ export default {
       });
     },
     deleteDevice: function (row) {
-      let msg = $t('notification.deleteDevice');
+      let msg = this.$t('notification.deleteDevice');
       if (row.online !== 0) {
         msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>"
       }
+      let that = this;
       this.$confirm(msg, 'tips', {
         dangerouslyUseHTMLString: true,
         confirmButtonText: this.$t('confirm'),

+ 1 - 1
web_src/src/components/bell.vue

@@ -338,7 +338,7 @@ export default {
 
     // 全部忽略
     markAllEventRead(){
-      this.$confirm(this.$t('ignoreTitle'), '提示', {
+      this.$confirm(this.$t('ignoreTitle'), 'Tips', {
         confirmButtonText: this.$t('confirm'),
         cancelButtonText: this.$t('cancel'),
         type: 'warning'

+ 12 - 4
web_src/src/components/channelList.vue

@@ -53,7 +53,9 @@
         <DeviceTree ref="deviceTree" :device="device" :onlyCatalog="true" :clickEvent="treeNodeClickEvent"></DeviceTree>
       </el-aside>
       <el-main style="padding: 5px;">
-        <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" style="width: 100%"
+        <el-table ref="channelListTable" :data="deviceChannelList"
+                  :height="winHeight" style="width: 100%"
+                  :row-key="record=>record.id"
                   header-row-class-name="table-header">
           <el-table-column prop="channelId" :label="$t('device.channelId')" min-width="200">
           </el-table-column>
@@ -114,13 +116,13 @@
               </el-button>
               <el-button size="medium" v-bind:disabled="device == null || device.online === 0"
                          icon="el-icon-switch-button" type="text" style="color: #f56c6c" v-if="!!scope.row.streamId"
-                         @click="stopDevicePush(scope.row)">$t('device.enablePs')
+                         @click="stopDevicePush(scope.row)">
                 {{ $t('device.stop') }}
               </el-button>
               <el-divider direction="vertical"></el-divider>
               <el-button size="medium" icon="el-icon-s-open" type="text"
                          v-if="scope.row.subCount > 0 || scope.row.parental === 1"
-                         @click="changeSubchannel(scope.row)">$t('device.enablePs')
+                         @click="changeSubchannel(scope.row)">
                 {{ $t('view') }}
               </el-button>
               <el-divider v-if="scope.row.subCount > 0 || scope.row.parental === 1" direction="vertical"></el-divider>
@@ -315,8 +317,14 @@ export default {
       }
       console.log(res);
       this.isLoging = false;
+      let msg = ''
       if (res.data.code !== 0) {
-        this.$message.error(res.data.msg);
+        msg = this.$t(`video.pushFailCode.${res.data.code}`, { msg: res.data.msg })
+        if (!msg) {
+          msg = this.$t("notification.pushFail", { msg: res.data.msg })
+        }
+        console.log(msg)
+        this.$message.error(msg);
         return;
       }
       setTimeout(() => {

+ 59 - 41
web_src/src/components/com/livePlayBox.vue

@@ -226,7 +226,7 @@ export default {
 
       if (err) {
         console.error(err);
-        this.$message.warning("流媒体信息获取失败")
+        this.$message.warning(this.$t('notification.noStreamInfo'))
         return;
       }
       console.log(res);
@@ -234,7 +234,7 @@ export default {
         this.tracksNotLoaded = true;
         this.$message({
           showClose: true,
-          message: '获取编码信息失败,',
+          message: this.$t('notification.noStreamInfo'),
           type: 'warning'
         });
         return;
@@ -290,22 +290,21 @@ export default {
       // 防抖,防止多次触发
       if (type === webrtcEvent.apiFail.code) {
         this.$notify.error({
-          title: 'ZLM连接失败',
+          title: this.$t('notification.noStreamInfo'),
           dangerouslyUseHTMLString: true,
-          message: `<span>连接zlm服务失败${e.message}</span> <br/>
-                        <a href="${this.videoUrl}" target="_blank"><span>手动访问</span></a>`,
+          message: this.$t('notification.zlmFailMsg',  {msg: e.message, url: this.videoUrl}),
           duration: 0
         });
         this.videoError = true;
         this.videoUrl = '';
 
       } else if (type === webrtcEvent.played.code) {
-        this.$message.success('播放成功');
+        this.$message.success(this.$t('notification.playSuccess'));
       } else if (type === webrtcEvent.sdpFail.code) {
         console.log(e);
         this.$notify.error({
-          title: 'sdp 交互失败',
-          duration: 4500
+          title: this.$t('notification.sdpFail'),
+          duration: 14500
         })
       }
     },
@@ -319,7 +318,7 @@ export default {
       let videoTrack = null;
       let el_playerBox = this.$refs.playerBox;
       if(!tracks){
-        return this.$message.warning("无法获取编码信息,无法计算是否填满高度");
+        return this.$message.warning(this.$t('notification.noStreamInfo'));
       }
       for(let track of tracks){
         if(track.fps || track.width){
@@ -328,12 +327,12 @@ export default {
         }
       }
       if(!videoTrack){
-        return this.$message.warning("无法获取流信息,无法计算是否填满高度");
+        return this.$message.warning(this.$t('notification.noStreamInfo'));
       }
       let height = videoTrack.height;
       let width = videoTrack.width;
       if(!height || !width){
-        return this.$message.warning("无法获取视频宽高");
+        return this.$message.warning(this.$t('notification.noStreamSize'));
       }
       // let mediaStyle = domTool.computeMediaStyle(el_playerBox);
       if(height < width){
@@ -368,6 +367,15 @@ export default {
     videoError(e) {
       console.log("播放器错误:" + JSON.stringify(e));
     },
+    destroyPlayer()
+    {
+      console.log("销毁播放器")
+    }
+
+  },
+  beforeDestroy() {
+    // 销毁播放器
+    this.destroyPlayer();
   }
 
 }
@@ -419,33 +427,39 @@ export default {
                    type="card"
                    @tab-click="handleTabClick"
           >
-            <el-tab-pane label="媒体信息" name="mediaInfo">
+            <el-tab-pane :label="$t('video.media.title')" name="mediaInfo">
               <el-card v-for="(item, index) in tracks" :key="`track-${index}`" loading>
                 <div slot="header" class="clearfix">
-                  <span>{{ index }}</span>
+                  <span>{{ $t('video.media.streamType') + index }}</span>
                   <span class="mx-2">---</span>
-                  <span v-if="item.codec_type === 0">视频</span>
-                  <span v-else-if="item.codec_type === 1">音频</span>
-                  <span v-else>未知</span>
+                  <span v-if="item.codec_type === 0">
+                    {{ $t('video.media.video') }}
+                  </span>
+                  <span v-else-if="item.codec_type === 1">
+                    {{ $t('video.media.audio') }}
+                  </span>
+                  <span v-else>
+                    {{ $t('unknown') }}
+                  </span>
                 </div>
                 <div class="trankInfo">
-                  <p>格式: {{ item.codec_id_name }}</p>
+                  <p>{{ $t('video.media.codec') }} : {{ item.codec_id_name }}</p>
 
                   <p v-if="item.codec_type === 0">
-                    <span>分辨率: {{ item.width }} x {{ item.height }}</span>
-                    <span>帧率: {{ item.fps }}</span>
+                    <span>{{ $t('video.media.resolution') }} : {{ item.width }} x {{ item.height }}</span>
+                    <span>{{ $t('video.media.fps') }} : {{ item.fps }}</span>
                   </p>
 
                   <p v-if="item.codec_type === 1">
-                    <span>采样位数: {{ item.sample_bit }}</span>
-                    <span>采样率: {{ item.sample_rate }}</span>
+                    <span>{{ $t('video.media.frameSize') }}: {{ item.sample_bit }}</span>
+                    <span>{{ $t('video.media.bitrate') }}: {{ item.sample_rate }}</span>
                   </p>
 
                 </div>
 
               </el-card>
             </el-tab-pane>
-            <el-tab-pane label="预置位查询" name="prest">
+            <el-tab-pane :label="$t('device.preset.title')" name="prest">
               <preset
                   ref="preset"
                   :channel-id="channelId"
@@ -454,55 +468,58 @@ export default {
                   :share-code="shareCode"
               ></preset>
             </el-tab-pane>
-            <el-tab-pane label="流地址" name="streamUrl">
-              <el-input class="mt-1" placeholder="分享地址"
+            <el-tab-pane :label="$t('video.media.address')" name="streamUrl">
+              <el-input class="mt-1" :placeholder="$t('device.share.address')"
                         v-if="shareUrl"
                         :value="shareUrl">
-                <template slot="prepend">分享地址</template>
-                <el-button slot="append" type="primary" icon="el-icon-s-order" @click="copy(shareUrl)">复制</el-button>
+                <template slot="prepend">{{ $t('device.share.address') }}</template>
+                <el-button slot="append" type="primary" icon="el-icon-s-order" @click="copy(shareUrl)">
+                  {{ $t('copy') }}
+                </el-button>
               </el-input>
               <el-button
                   class="mt-1"
                   v-if="!shareCode"
                   @click="sharePlay"
                   type="primary"
-              >分享推流
+              >
+                {{ $t('device.share.title') }}
               </el-button>
 
-              <el-input class="mt-1" placeholder="rtc 地址"
+              <el-input class="mt-1" placeholder="rtc"
                         :value="info.rtc">
                 <template slot="prepend">rtc</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtc)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtc)">{{ $t('copy') }}</el-button>
               </el-input>
 
-              <el-input class="mt-1" placeholder="rtmp 地址"
+              <el-input class="mt-1" placeholder="rtmp"
                         :value="info.rtmp">
                 <template slot="prepend">rtmp</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtmp)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtmp)">{{ $t('copy') }}</el-button>
               </el-input>
 
-              <el-input class="mt-1" placeholder="flv 地址"
+              <el-input class="mt-1" placeholder="flv"
                         :value="info.flv">
                 <template slot="prepend">flv</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.flv)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.flv)">{{ $t('copy') }}</el-button>
               </el-input>
 
-              <el-input class="mt-1" placeholder="hls 地址"
+              <el-input class="mt-1" placeholder="hls"
                         :value="info.hls">
                 <template slot="prepend">hls</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.hls)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.hls)">{{ $t('copy') }}</el-button>
               </el-input>
 
-              <el-input class="mt-1" placeholder="fmp4 地址"
+              <el-input class="mt-1" placeholder="fmp4"
                         :value="info.rtsp">
                 <template slot="prepend">rtsp</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtsp)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.rtsp)">{{ $t('copy') }}</el-button>
               </el-input>
 
-              <el-input class="mt-1" placeholder="fmp4 地址"
+              <el-input class="mt-1" placeholder="fmp4"
                         :value="info.fmp4">
                 <template slot="prepend">fmp4</template>
-                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.fmp4)">复制</el-button>
+                <el-button slot="append" icon="el-icon-s-order" @click="copy(info.fmp4)">{{ $t('copy') }}</el-button>
               </el-input>
 
             </el-tab-pane>
@@ -520,12 +537,13 @@ export default {
             v-for="(item,i) in playerList"
             :key="item.key + i"
             :label="item.key">
-          {{ item.text }}
+          {{ $t(item.key) }}
         </el-radio-button>
       </el-radio-group>
 
       <el-button-group>
-        <el-button @click="handleRePush">重新拉流</el-button>
+        <el-button @click="handleRePush">
+          {{ $t('device.rePush') }}</el-button>
       </el-button-group>
     </div>
   </div>

+ 1 - 1
web_src/src/components/devAiEdit.vue

@@ -4,7 +4,7 @@
       <div class="page-title">
         <el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="back" ></el-button>
         <el-divider direction="vertical"></el-divider>
-        $t('aiManager.title')
+        {{ $t('aiManager.title') }}
       </div>
 
       <div class="page-header-btn">

+ 2 - 0
web_src/src/components/dialog/rtcPlayer.vue

@@ -271,6 +271,8 @@ export default {
   beforeDestroy() {
     // 移除resize事件
     window.removeEventListener('resize', this.comVideoWh);
+    // 移除播放器
+    this.pause();
   },
   destroyed() {
     clearTimeout(this.timer);

+ 1 - 1
web_src/src/router/index.js

@@ -51,7 +51,7 @@ export default new VueRouter({
       path: '/',
       name: 'home',
       component: Layout,
-      redirect: '/console',
+      redirect: '/deviceList',
       children: [
           {
               path: '/console',