Files
iptv/scripts/utils.ts

59 lines
1.7 KiB
TypeScript
Raw Normal View History

2026-03-23 17:13:15 +03:00
import { MasterPlaylist, MediaPlaylist, Variant } from 'hls-parser/types'
import { parse as parsePlaylist } from 'hls-parser'
import { TESTING } from './constants.js'
2025-10-08 21:25:22 +03:00
import normalizeUrl from 'normalize-url'
2026-03-23 17:13:15 +03:00
import { orderBy } from 'es-toolkit'
import axios from 'axios'
2025-10-08 21:25:22 +03:00
export function isURI(string: string): boolean {
try {
2026-03-11 07:08:24 +03:00
const url = new URL(string)
return /^(http:|https:|mmsh:|rtsp:|rtmp:)/.test(url.protocol)
2025-10-08 21:25:22 +03:00
} catch {
return false
}
}
export function normalizeURL(url: string): string {
const normalized = normalizeUrl(url, { stripWWW: false })
return decodeURIComponent(normalized).replace(/\s/g, '+').toString()
}
export function truncate(string: string, limit: number = 100) {
if (!string) return string
if (string.length < limit) return string
return string.slice(0, limit - 3) + '...'
}
2026-03-23 17:13:15 +03:00
export async function getStreamInfo(
url: string,
options: { httpUserAgent: string | null; httpReferrer: string | null }
): Promise<Variant | undefined> {
let playlist: MasterPlaylist | MediaPlaylist | undefined
if (TESTING) {
playlist = (await import('../tests/__data__/input/playlist_update/playlist.mjs'))
.default as unknown as MasterPlaylist
} else {
try {
const response = await axios(url, {
signal: AbortSignal.timeout(30000),
headers: {
'User-Agent': options.httpUserAgent || 'Mozilla/5.0',
Referer: options.httpReferrer
}
})
playlist = parsePlaylist(response.data)
} catch {}
}
if (playlist && playlist.isMasterPlaylist && playlist.variants.length) {
return orderBy(playlist.variants, ['bandwidth'], ['desc'])[0]
}
return undefined
}