refactor(types): remove obsolete format/quality/codec fields and related logic to simplify download and avoid redundant storage

This commit is contained in:
Nexmoe
2025-11-10 21:25:43 +08:00
parent 56351941ee
commit 9040224319
5 changed files with 93 additions and 119 deletions

View File

@@ -407,8 +407,7 @@ class DownloadEngine extends EventEmitter {
createdAt,
tags: options.tags,
origin,
subscriptionId: options.subscriptionId,
subscriptionTitle: options.subscriptionTitle
subscriptionId: options.subscriptionId
}
this.queue.add(id, options, item)
@@ -420,8 +419,7 @@ class DownloadEngine extends EventEmitter {
downloadPath: targetDownloadPath,
tags: options.tags,
origin,
subscriptionId: options.subscriptionId,
subscriptionTitle: options.subscriptionTitle
subscriptionId: options.subscriptionId
})
}
@@ -441,8 +439,6 @@ class DownloadEngine extends EventEmitter {
let availableFormats: VideoFormat[] = []
let selectedFormat: VideoFormat | undefined
let actualFormat: string | null = null
let actualQuality: string | null = null
let actualCodec: string | null = null
let videoInfo: VideoInfo | undefined
// First, get detailed video info to capture basic metadata and formats
@@ -455,20 +451,6 @@ class DownloadEngine extends EventEmitter {
if (selectedFormat) {
actualFormat = selectedFormat.ext || actualFormat
if (selectedFormat.height) {
actualQuality = `${selectedFormat.height}p${
selectedFormat.fps && selectedFormat.fps === 60 ? '60' : ''
}`
} else if (selectedFormat.format_note) {
actualQuality = selectedFormat.format_note
}
if (options.type === 'audio' || options.type === 'extract') {
actualCodec = selectedFormat.acodec || actualCodec
} else {
actualCodec = selectedFormat.vcodec || selectedFormat.acodec || actualCodec
}
}
this.updateDownloadInfo(id, {
@@ -513,18 +495,6 @@ class DownloadEngine extends EventEmitter {
selectedFormat = candidate
actualFormat = candidate.ext || actualFormat
if (candidate.height) {
actualQuality = `${candidate.height}p${candidate.fps === 60 ? '60' : ''}`
} else if (candidate.format_note) {
actualQuality = candidate.format_note
}
if (options.type === 'audio' || options.type === 'extract') {
actualCodec = candidate.acodec || actualCodec
} else {
actualCodec = candidate.vcodec || candidate.acodec || actualCodec
}
this.updateDownloadInfo(id, {
selectedFormat: candidate
})
@@ -640,16 +610,6 @@ class DownloadEngine extends EventEmitter {
if (extMatch && !actualFormat) {
actualFormat = extMatch[1]
}
const heightMatch = formatInfo.match(/(\d+)p/)
if (heightMatch && !actualQuality) {
actualQuality = `${heightMatch[1]}p`
}
const codecMatch = formatInfo.match(/(?:vcodec|acodec)[:\s]*([^\s,]+)/)
if (codecMatch && !actualCodec) {
actualCodec = codecMatch[1]
}
}
}
@@ -759,9 +719,6 @@ class DownloadEngine extends EventEmitter {
status: 'completed',
completedAt: Date.now(),
fileSize,
format: willMerge ? 'mp4' : actualFormat || undefined,
quality: actualQuality || undefined,
codec: actualCodec || undefined,
savedFileName
})
scopedLoggers.download.info('Download completed successfully for ID:', id)
@@ -848,15 +805,6 @@ class DownloadEngine extends EventEmitter {
if (updates.fileSize !== undefined) {
historyUpdates.fileSize = updates.fileSize
}
if (updates.format !== undefined) {
historyUpdates.format = updates.format
}
if (updates.quality !== undefined) {
historyUpdates.quality = updates.quality
}
if (updates.codec !== undefined) {
historyUpdates.codec = updates.codec
}
if (updates.description !== undefined) {
historyUpdates.description = updates.description
}
@@ -884,6 +832,9 @@ class DownloadEngine extends EventEmitter {
if (updates.playlistSize !== undefined) {
historyUpdates.playlistSize = updates.playlistSize
}
if (updates.selectedFormat !== undefined) {
historyUpdates.selectedFormat = updates.selectedFormat
}
if (updates.status !== undefined) {
historyUpdates.status = updates.status
}
@@ -893,9 +844,6 @@ class DownloadEngine extends EventEmitter {
if (updates.error !== undefined) {
historyUpdates.error = updates.error
}
if (updates.selectedFormat !== undefined) {
historyUpdates.selectedFormat = updates.selectedFormat
}
if (updates.savedFileName !== undefined) {
historyUpdates.savedFileName = updates.savedFileName
}
@@ -924,9 +872,6 @@ class DownloadEngine extends EventEmitter {
error,
duration: completedDownload?.item.duration,
fileSize: completedDownload?.item.fileSize,
format: completedDownload?.item.format,
quality: completedDownload?.item.quality,
codec: completedDownload?.item.codec,
description: completedDownload?.item.description,
channel: completedDownload?.item.channel,
uploader: completedDownload?.item.uploader,
@@ -934,7 +879,6 @@ class DownloadEngine extends EventEmitter {
tags: completedDownload?.item.tags,
origin: completedDownload?.item.origin,
subscriptionId: completedDownload?.item.subscriptionId,
subscriptionTitle: completedDownload?.item.subscriptionTitle,
playlistId: completedDownload?.item.playlistId,
playlistTitle: completedDownload?.item.playlistTitle,
playlistIndex: completedDownload?.item.playlistIndex,
@@ -964,9 +908,6 @@ class DownloadEngine extends EventEmitter {
downloadedAt: updates.downloadedAt ?? Date.now(),
completedAt: updates.completedAt,
error: updates.error,
format: updates.format,
quality: updates.quality,
codec: updates.codec,
description: updates.description,
channel: updates.channel,
uploader: updates.uploader,
@@ -974,7 +915,6 @@ class DownloadEngine extends EventEmitter {
tags: updates.tags ?? options.tags,
origin: updates.origin ?? options.origin,
subscriptionId: updates.subscriptionId ?? options.subscriptionId,
subscriptionTitle: updates.subscriptionTitle ?? options.subscriptionTitle,
// Download-specific format info
selectedFormat: updates.selectedFormat,
playlistId: updates.playlistId,
@@ -995,8 +935,7 @@ class DownloadEngine extends EventEmitter {
downloadPath: resolvedDownloadPath ?? base.downloadPath,
tags: updates.tags ?? base.tags,
origin: updates.origin ?? base.origin,
subscriptionId: updates.subscriptionId ?? base.subscriptionId,
subscriptionTitle: updates.subscriptionTitle ?? base.subscriptionTitle
subscriptionId: updates.subscriptionId ?? base.subscriptionId
}
historyManager.addHistoryItem(merged)

View File

@@ -371,8 +371,7 @@ export class SubscriptionScheduler extends EventEmitter {
customFilenameTemplate: namingTemplate,
tags,
origin: 'subscription',
subscriptionId,
subscriptionTitle: subscription.title
subscriptionId
})
this.downloads.set(downloadId, {

View File

@@ -55,6 +55,73 @@ const tryFileOperation = async (
return false
}
const getSavedFileExtension = (fileName?: string): string | undefined => {
if (!fileName) {
return undefined
}
const normalized = fileName.trim()
if (!normalized.includes('.')) {
return undefined
}
const ext = normalized.split('.').pop()
return ext?.toLowerCase()
}
const resolveDownloadExtension = (download: DownloadRecord): string => {
const savedExt = getSavedFileExtension(download.savedFileName)
if (savedExt) {
return savedExt
}
const selectedExt = download.selectedFormat?.ext?.toLowerCase()
if (selectedExt) {
return selectedExt
}
return download.type === 'audio' ? 'mp3' : 'mp4'
}
const getFormatLabel = (download: DownloadRecord): string | undefined => {
if (download.selectedFormat?.ext) {
return download.selectedFormat.ext.toUpperCase()
}
const savedExt = getSavedFileExtension(download.savedFileName)
return savedExt ? savedExt.toUpperCase() : undefined
}
const getQualityLabel = (download: DownloadRecord): string | undefined => {
const format = download.selectedFormat
if (!format) {
return undefined
}
if (format.height) {
return `${format.height}p${format.fps === 60 ? '60' : ''}`
}
if (format.format_note) {
return format.format_note
}
if (typeof format.quality === 'number') {
return format.quality.toString()
}
return undefined
}
const sanitizeCodec = (codec?: string | null): string | undefined => {
if (!codec || codec === 'none') {
return undefined
}
return codec
}
const getCodecLabel = (download: DownloadRecord): string | undefined => {
const format = download.selectedFormat
if (!format) {
return undefined
}
if (download.type === 'audio' || download.type === 'extract') {
return sanitizeCodec(format.acodec)
}
return sanitizeCodec(format.vcodec) ?? sanitizeCodec(format.acodec)
}
interface DownloadItemProps {
download: DownloadRecord
}
@@ -106,8 +173,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
const removeHistory = useSetAtom(removeHistoryRecordAtom)
const isHistory = download.entryType === 'history'
const isSubscriptionDownload = download.origin === 'subscription'
const subscriptionLabel =
download.subscriptionTitle ?? download.subscriptionId ?? t('subscriptions.labels.unknown')
const subscriptionLabel = download.subscriptionId ?? t('subscriptions.labels.unknown')
const timestamp = download.completedAt ?? download.downloadedAt ?? download.createdAt
const showActionsWithoutHover = isHistory || download.status === 'completed'
const actionsContainerBaseClass =
@@ -115,6 +181,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
const actionsContainerClass = showActionsWithoutHover
? actionsContainerBaseClass
: `${actionsContainerBaseClass} sm:opacity-0 sm:group-hover:opacity-100`
const resolvedExtension = resolveDownloadExtension(download)
// Track if the file exists
const [fileExists, setFileExists] = useState(false)
@@ -129,7 +196,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
}
try {
const formatForPath = download.format || (download.type === 'audio' ? 'mp3' : 'mp4')
const formatForPath = resolvedExtension
const filePaths = generateFilePathCandidates(
download.downloadPath,
download.title,
@@ -151,13 +218,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
}
checkFileExists()
}, [
download.title,
download.downloadPath,
download.format,
download.savedFileName,
download.type
])
}, [download.title, download.downloadPath, download.savedFileName, resolvedExtension])
const handleCancel = async () => {
if (isHistory) return
@@ -172,7 +233,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
const handleOpenFolder = async () => {
try {
const downloadPath = download.downloadPath || settings.downloadPath
const format = download.format || (download.type === 'audio' ? 'mp3' : 'mp4')
const format = resolvedExtension
const filePaths = generateFilePathCandidates(
downloadPath,
download.title,
@@ -193,12 +254,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
}
// Check if copy to clipboard is available
const canCopyToClipboard = () => {
return !!(
download.title &&
download.downloadPath &&
fileExists &&
(download.savedFileName || download.format)
)
return Boolean(download.title && download.downloadPath && fileExists)
}
// need title, downloadPath, format
@@ -210,10 +266,10 @@ export function DownloadItem({ download }: DownloadItemProps) {
// Type guard: these values are guaranteed to exist after canCopyToClipboard() check
const downloadPath = download.downloadPath
const format = download.format
const format = resolvedExtension
const title = download.title
if (!downloadPath || !format || !title) {
if (!downloadPath || !title) {
toast.error(t('notifications.copyFailed'))
return
}
@@ -246,7 +302,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
if (!isHistory) return
try {
const downloadPath = download.downloadPath || settings.downloadPath
const format = download.format || (download.type === 'audio' ? 'mp3' : 'mp4')
const format = resolvedExtension
const filePaths = generateFilePathCandidates(
downloadPath,
download.title,
@@ -363,11 +419,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
download.selectedFormat?.filesize || download.selectedFormat?.filesize_approx
const inlineFileSize = selectedFormatSize ? formatFileSize(selectedFormatSize) : undefined
const formatLabelValue = download.selectedFormat?.ext
? download.selectedFormat.ext.toUpperCase()
: download.format
? download.format.toUpperCase()
: undefined
const formatLabelValue = getFormatLabel(download)
if (formatLabelValue) {
metadataDetails.push({
@@ -376,14 +428,12 @@ export function DownloadItem({ download }: DownloadItemProps) {
})
}
const qualityValue = download.selectedFormat?.height
? `${download.selectedFormat.height}p${download.selectedFormat.fps === 60 ? '60' : ''}`
: download.quality
const qualityLabel = getQualityLabel(download)
if (qualityValue) {
if (qualityLabel) {
metadataDetails.push({
label: t('download.metadata.quality'),
value: qualityValue
value: qualityLabel
})
}
@@ -394,10 +444,11 @@ export function DownloadItem({ download }: DownloadItemProps) {
})
}
if (download.codec) {
const codecValue = getCodecLabel(download)
if (codecValue) {
metadataDetails.push({
label: t('download.metadata.codec'),
value: download.codec
value: codecValue
})
}
@@ -508,7 +559,7 @@ export function DownloadItem({ download }: DownloadItemProps) {
})
}
if (download.selectedFormat.height && !qualityValue) {
if (download.selectedFormat.height && !qualityLabel) {
metadataDetails.push({
label: t('download.metadata.height'),
value: `${download.selectedFormat.height}px`
@@ -639,11 +690,9 @@ export function DownloadItem({ download }: DownloadItemProps) {
)}
{/* Quality badge */}
{(download.selectedFormat?.height || download.quality) && (
{qualityLabel && (
<Badge variant="outline" className="text-[10px] px-1.5 py-0.5 shrink-0">
{download.selectedFormat?.height
? `${download.selectedFormat.height}p${download.selectedFormat.fps === 60 ? '60' : ''}`
: download.quality}
{qualityLabel}
</Badge>
)}

View File

@@ -28,9 +28,6 @@ const toHistoryRecord = (item: DownloadHistoryItem): DownloadRecord => ({
speed: undefined,
duration: item.duration,
fileSize: item.fileSize,
format: item.format,
quality: item.quality,
codec: item.codec,
createdAt: item.downloadedAt,
startedAt: item.downloadedAt,
completedAt: item.completedAt ?? item.downloadedAt,

View File

@@ -62,9 +62,6 @@ export interface DownloadItem {
// Enhanced video information
duration?: number
fileSize?: number
format?: string
quality?: string
codec?: string
savedFileName?: string
// Timestamps
createdAt: number
@@ -78,7 +75,6 @@ export interface DownloadItem {
tags?: string[]
origin?: 'manual' | 'subscription'
subscriptionId?: string
subscriptionTitle?: string
// Download-specific format info
selectedFormat?: VideoFormat
// Playlist context (optional)
@@ -112,10 +108,6 @@ export interface DownloadHistoryItem {
downloadedAt: number
completedAt?: number
error?: string
// Enhanced video information
format?: string
quality?: string
codec?: string
// Additional metadata
description?: string
channel?: string
@@ -124,7 +116,6 @@ export interface DownloadHistoryItem {
tags?: string[]
origin?: 'manual' | 'subscription'
subscriptionId?: string
subscriptionTitle?: string
// Download-specific format info
selectedFormat?: VideoFormat
// Playlist context (optional)
@@ -149,7 +140,6 @@ export interface DownloadOptions {
tags?: string[]
origin?: 'manual' | 'subscription'
subscriptionId?: string
subscriptionTitle?: string
}
export interface PlaylistEntry {