This commit is contained in:
Julian Freeman
2026-04-19 09:56:09 -04:00
parent 4d5cac7a46
commit e86bc86793
18 changed files with 685 additions and 500 deletions

45
src/utils/analysis.ts Normal file
View File

@@ -0,0 +1,45 @@
import type { PlaylistMetadata, SelectableVideoMetadata, VideoMetadata } from '../types/media'
export function detectMixUrl(url: string): boolean {
return url.includes('v=') && url.includes('list=')
}
export function stripPlaylistContext(rawUrl: string): string {
try {
const url = new URL(rawUrl)
url.searchParams.delete('list')
url.searchParams.delete('index')
url.searchParams.delete('start_radio')
return url.toString()
} catch {
return rawUrl
.replace(/[?&]list=[^&]+/g, '')
.replace(/[?&]index=[^&]+/g, '')
.replace(/[?&]start_radio=[^&]+/g, '')
.replace('?&', '?')
.replace(/&&+/g, '&')
.replace(/[?&]$/, '')
}
}
export function isLikelyHttpUrl(input: string): boolean {
return input.startsWith('http://') || input.startsWith('https://')
}
export function normalizeBatchLinks(input: string): string[] {
return input
.split('\n')
.map(line => line.trim())
.filter(Boolean)
.filter(isLikelyHttpUrl)
.filter(link => !link.includes('list=') || detectMixUrl(link))
.map(link => detectMixUrl(link) ? stripPlaylistContext(link) : link)
}
export function toSelectableEntries(entries: VideoMetadata[]): SelectableVideoMetadata[] {
return entries.map(entry => ({ ...entry, selected: true }))
}
export function countSelectedEntries(metadata: PlaylistMetadata | null): number {
return metadata?.entries.filter(entry => entry.selected).length ?? 0
}