107 lines
3.6 KiB
Vue
107 lines
3.6 KiB
Vue
<!-- Author: fruit.com.cn -->
|
|
<!-- 剧集转码清晰度表格与播放地址操作 -->
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import type { MediaRenditionItem } from '@/api/admin/types'
|
|
import { AppIcon } from '@/components/AppIcon'
|
|
import { AppIcons } from '@/constants/icons'
|
|
import { useI18n } from '@/hooks/web/useI18n'
|
|
import RenditionPlayerDialog from './RenditionPlayerDialog.vue'
|
|
import {
|
|
formatBytes,
|
|
formatDuration,
|
|
renditionStatusLabelKey,
|
|
renditionStatusType
|
|
} from './episodeTranscodeUi'
|
|
|
|
defineProps<{
|
|
renditions: MediaRenditionItem[]
|
|
}>()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const playerVisible = ref(false)
|
|
const playerUrl = ref('')
|
|
const playerTitle = ref('')
|
|
|
|
function statusLabel(rendition: MediaRenditionItem) {
|
|
return t(`episodeTranscode.status.${renditionStatusLabelKey(rendition.status)}`)
|
|
}
|
|
|
|
function playRendition(rendition: MediaRenditionItem) {
|
|
if (!rendition.hlsUrl) return
|
|
playerUrl.value = rendition.hlsUrl
|
|
playerTitle.value = `${rendition.qualityName} · ${rendition.resolution}`
|
|
playerVisible.value = true
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="episode-transcode-renditions__heading">
|
|
<h4>{{ t('episodeTranscode.renditionTitle') }}</h4>
|
|
</div>
|
|
<el-table
|
|
:data="renditions"
|
|
size="small"
|
|
border
|
|
class="episode-transcode-renditions__table"
|
|
:empty-text="t('episodeTranscode.noRendition')"
|
|
>
|
|
<el-table-column prop="qualityName" :label="t('episodeTranscode.quality')" min-width="88" />
|
|
<el-table-column prop="resolution" :label="t('episodeTranscode.resolution')" min-width="105" />
|
|
<el-table-column :label="t('episodeTranscode.videoBitrate')" min-width="105">
|
|
<template #default="{ row }">{{ row.videoBitrateKbps }} kbps</template>
|
|
</el-table-column>
|
|
<el-table-column :label="t('episodeTranscode.audioBitrate')" min-width="105">
|
|
<template #default="{ row }">{{ row.audioBitrateKbps }} kbps</template>
|
|
</el-table-column>
|
|
<el-table-column prop="videoCodec" :label="t('episodeTranscode.codec')" min-width="82" />
|
|
<el-table-column prop="container" :label="t('episodeTranscode.container')" min-width="82" />
|
|
<el-table-column :label="t('episodeTranscode.fileSize')" min-width="92">
|
|
<template #default="{ row }">{{ formatBytes(row.sizeBytes) }}</template>
|
|
</el-table-column>
|
|
<el-table-column :label="t('episodeTranscode.duration')" min-width="76">
|
|
<template #default="{ row }">{{ formatDuration(row.durationSec) }}</template>
|
|
</el-table-column>
|
|
<el-table-column prop="segmentCount" :label="t('episodeTranscode.segments')" min-width="76" />
|
|
<el-table-column :label="t('episodeTranscode.statusColumn')" min-width="82">
|
|
<template #default="{ row }">
|
|
<el-tag :type="renditionStatusType(row.status)" effect="light" size="small">
|
|
{{ statusLabel(row) }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column :label="t('episodeTranscode.actions')" width="76" fixed="right" align="center">
|
|
<template #default="{ row }">
|
|
<el-tooltip :content="t('episodeTranscode.play')" placement="top">
|
|
<el-button text circle @click="playRendition(row)">
|
|
<AppIcon :icon="AppIcons.videoPlay" :size="17" />
|
|
</el-button>
|
|
</el-tooltip>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<RenditionPlayerDialog v-model="playerVisible" :url="playerUrl" :title="playerTitle" />
|
|
</template>
|
|
|
|
<style scoped>
|
|
.episode-transcode-renditions__heading {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
margin: 18px 0 10px;
|
|
}
|
|
|
|
.episode-transcode-renditions__heading h4 {
|
|
margin: 0;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.episode-transcode-renditions__table {
|
|
width: 100%;
|
|
}
|
|
</style>
|