Register 直播切片 as a video-only material type. Upload and edit flows collect required title, live date (defaults to today), optional host with user link, and live platform presets. Persist the fields on Material and skip SPU formatting for free-text titles.
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
export const TAOXI_MAIN_VIDEO_TYPE = '淘系-主图视频'
|
|
export const TAOXI_GUANGGUANG_VIDEO_TYPE = '淘系-逛逛视频'
|
|
export const DOUYIN_QIANCHUAN_VIDEO_TYPE = '抖音-千川素材'
|
|
export const DOUYIN_ACCOUNT_MAINTENANCE_VIDEO_TYPE = '抖音-账号维护'
|
|
export const INSTALL_VIDEO_TYPE = '安装视频'
|
|
export const LIVE_CLIP_VIDEO_TYPE = '直播切片'
|
|
|
|
const MATERIAL_TYPE_ALIASES: Record<string, string> = {
|
|
主图视频: TAOXI_MAIN_VIDEO_TYPE,
|
|
种草视频: TAOXI_GUANGGUANG_VIDEO_TYPE,
|
|
}
|
|
|
|
export const CANONICAL_VIDEO_MATERIAL_TYPES = [
|
|
TAOXI_MAIN_VIDEO_TYPE,
|
|
INSTALL_VIDEO_TYPE,
|
|
TAOXI_GUANGGUANG_VIDEO_TYPE,
|
|
DOUYIN_QIANCHUAN_VIDEO_TYPE,
|
|
DOUYIN_ACCOUNT_MAINTENANCE_VIDEO_TYPE,
|
|
LIVE_CLIP_VIDEO_TYPE,
|
|
] as const
|
|
|
|
export const LEGACY_COMPATIBLE_VIDEO_MATERIAL_TYPES = [
|
|
'视频',
|
|
'VIDEO',
|
|
...CANONICAL_VIDEO_MATERIAL_TYPES,
|
|
...Object.keys(MATERIAL_TYPE_ALIASES),
|
|
] as const
|
|
|
|
export function normalizeVideoMaterialType(materialType?: string | null): string {
|
|
const trimmed = (materialType || '').trim()
|
|
if (!trimmed) {
|
|
return ''
|
|
}
|
|
|
|
return MATERIAL_TYPE_ALIASES[trimmed] || trimmed
|
|
}
|
|
|
|
export function getCompatibleVideoMaterialTypes(materialType?: string | null): string[] {
|
|
const trimmed = (materialType || '').trim()
|
|
if (!trimmed) {
|
|
return []
|
|
}
|
|
|
|
const normalized = normalizeVideoMaterialType(trimmed)
|
|
const candidates = new Set<string>([trimmed, normalized])
|
|
|
|
for (const [legacyType, canonicalType] of Object.entries(MATERIAL_TYPE_ALIASES)) {
|
|
if (canonicalType === normalized) {
|
|
candidates.add(legacyType)
|
|
}
|
|
}
|
|
|
|
return Array.from(candidates)
|
|
}
|
|
|
|
export function isVideoMaterialType(materialType?: string | null): boolean {
|
|
const normalized = normalizeVideoMaterialType(materialType)
|
|
return LEGACY_COMPATIBLE_VIDEO_MATERIAL_TYPES.includes(
|
|
normalized as (typeof LEGACY_COMPATIBLE_VIDEO_MATERIAL_TYPES)[number],
|
|
)
|
|
}
|
|
|
|
export function isVideoTranscodeInFlight(status?: string | null): boolean {
|
|
const normalized = String(status || '').trim().toLowerCase()
|
|
return normalized === 'pending' || normalized === 'processing'
|
|
}
|
|
|
|
/**
|
|
* 轮询只依赖可公开返回的素材类型和处理状态,不能依赖 videoSourceUrl。
|
|
* 15 天访问策略会有意隐藏源视频地址,但后台封面生成状态仍需正常刷新。
|
|
*/
|
|
export function shouldPollVideoTranscode(
|
|
materialType?: string | null,
|
|
status?: string | null,
|
|
): boolean {
|
|
return isVideoMaterialType(materialType) && isVideoTranscodeInFlight(status)
|
|
}
|
|
|
|
export function isBatchVideoMaterialType(materialType?: string | null): boolean {
|
|
return normalizeVideoMaterialType(materialType) === TAOXI_GUANGGUANG_VIDEO_TYPE
|
|
}
|
|
|
|
export function isSingleVideoUploadMaterialType(materialType?: string | null): boolean {
|
|
const normalized = normalizeVideoMaterialType(materialType)
|
|
return (
|
|
isVideoMaterialType(normalized) &&
|
|
normalized !== TAOXI_GUANGGUANG_VIDEO_TYPE &&
|
|
normalized !== '视频' &&
|
|
normalized !== 'VIDEO'
|
|
)
|
|
}
|