2023-01-11 04:54:25 -05:00
|
|
|
export const stringFormatter = () => {
|
2023-11-16 09:45:46 -05:00
|
|
|
function fileSize(bytes: number | undefined, dp = 2) {
|
2023-11-16 06:44:12 -05:00
|
|
|
if (!bytes) {
|
|
|
|
return 0.0
|
|
|
|
}
|
|
|
|
|
2023-11-16 09:45:46 -05:00
|
|
|
const thresh = 1024
|
2023-11-16 06:44:12 -05:00
|
|
|
|
|
|
|
if (Math.abs(bytes) < thresh) {
|
2023-11-16 09:45:46 -05:00
|
|
|
return bytes + ' B'
|
2023-11-16 06:44:12 -05:00
|
|
|
}
|
|
|
|
|
2023-11-16 09:45:46 -05:00
|
|
|
const units = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
|
|
|
|
let u = -1
|
|
|
|
const r = 10 ** dp
|
2023-11-16 06:44:12 -05:00
|
|
|
|
|
|
|
do {
|
2023-11-16 09:45:46 -05:00
|
|
|
bytes /= thresh
|
|
|
|
++u
|
|
|
|
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1)
|
2023-11-16 06:44:12 -05:00
|
|
|
|
2023-11-16 09:45:46 -05:00
|
|
|
return bytes.toFixed(dp) + ' ' + units[u]
|
2023-11-16 06:44:12 -05:00
|
|
|
}
|
|
|
|
|
2024-06-25 11:12:08 -04:00
|
|
|
function formatLog(text: string): string {
|
2023-11-16 09:45:46 -05:00
|
|
|
return text
|
2024-06-25 11:12:08 -04:00
|
|
|
.replace(/<yellow>(.*?)<\/>/g, '<span class="log-number">$1</span>')
|
|
|
|
.replace(/<b><magenta>(.*?)<\/><\/b>/g, '<span class="log-addr">$1</span>')
|
|
|
|
.replace(/<bright-blue>(.*?)<\/>/g, '<span class="log-cmd">$1</span>')
|
2023-11-16 09:45:46 -05:00
|
|
|
.replace(/\x1B\[90m(.*?)\x1B\[0m/g, '<span class="log-debug">$1</span>')
|
|
|
|
.replace(/(\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.[\d]+\])/g, '<span class="log-time">$1</span>')
|
|
|
|
.replace(/\[ INFO\]/g, '<span class="log-info">[ INFO]</span>')
|
|
|
|
.replace(/\[ WARN\]/g, '<span class="log-warning">[ WARN]</span>')
|
|
|
|
.replace(/\[ERROR\]/g, '<span class="log-error">[ERROR]</span>')
|
|
|
|
.replace(/\[DEBUG\]/g, '<span class="log-debug">[DEBUG]</span>')
|
|
|
|
.replace(/\[Decoder\]/g, '<span class="log-decoder">[Decoder]</span>')
|
|
|
|
.replace(/\[Encoder\]/g, '<span class="log-encoder">[Encoder]</span>')
|
|
|
|
.replace(/\[Server\]/g, '<span class="log-server">[Server]</span>')
|
|
|
|
.replace(/\[Validator\]/g, '<span class="log-server">[Validator]</span>')
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function timeToSeconds(time: string): number {
|
2023-01-11 04:54:25 -05:00
|
|
|
const t = time.split(':')
|
|
|
|
return parseInt(t[0]) * 3600 + parseInt(t[1]) * 60 + parseInt(t[2])
|
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function secToHMS(sec: number): string {
|
2024-04-30 03:11:26 -04:00
|
|
|
const sign = Math.sign(sec)
|
|
|
|
sec = Math.abs(sec)
|
|
|
|
|
2024-04-16 08:07:50 -04:00
|
|
|
const hours = Math.floor(sec / 3600)
|
2023-01-11 04:54:25 -05:00
|
|
|
sec %= 3600
|
2024-04-16 08:07:50 -04:00
|
|
|
const minutes = Math.floor(sec / 60)
|
|
|
|
const seconds = Math.round(sec % 60)
|
2023-01-11 04:54:25 -05:00
|
|
|
|
|
|
|
const m = String(minutes).padStart(2, '0')
|
|
|
|
const h = String(hours).padStart(2, '0')
|
|
|
|
const s = String(seconds).padStart(2, '0')
|
2024-04-30 03:11:26 -04:00
|
|
|
|
|
|
|
const hString = (sign === -1 ? '-' : '') + h
|
|
|
|
|
|
|
|
return `${hString}:${m}:${s}`
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function numberToHex(num: number): string {
|
2023-01-11 04:54:25 -05:00
|
|
|
return '0x' + Math.round(num * 255).toString(16)
|
|
|
|
}
|
|
|
|
|
|
|
|
function hexToNumber(num: string): number {
|
|
|
|
return parseFloat((parseFloat(parseInt(num, 16).toString()) / 255).toFixed(2))
|
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function filename(path: string): string {
|
2023-01-11 04:54:25 -05:00
|
|
|
if (path) {
|
|
|
|
const pathArr = path.split('/')
|
2023-06-26 02:26:03 -04:00
|
|
|
const name = pathArr[pathArr.length - 1]
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
return name
|
|
|
|
} else {
|
|
|
|
return path
|
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
} else {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function parent(path: string): string {
|
2024-04-07 17:27:52 -04:00
|
|
|
if (path) {
|
|
|
|
const pathArr = path.split('/')
|
|
|
|
pathArr.pop()
|
|
|
|
|
|
|
|
if (pathArr.length > 0) {
|
|
|
|
return pathArr.join('/')
|
|
|
|
} else {
|
|
|
|
return '/'
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function toMin(sec: number): string {
|
2023-01-11 04:54:25 -05:00
|
|
|
if (sec) {
|
|
|
|
const minutes = Math.floor(sec / 60)
|
|
|
|
const seconds = Math.round(sec - minutes * 60)
|
|
|
|
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')} min`
|
|
|
|
} else {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function secondsToTime(sec: number) {
|
2024-05-15 02:53:25 -04:00
|
|
|
return new Date(sec * 1000 || 0).toISOString().substring(11, 19)
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
2023-02-02 03:53:26 -05:00
|
|
|
function mediaType(path: string) {
|
2023-12-07 16:00:05 -05:00
|
|
|
const liveType = ['m3u8']
|
2023-11-16 09:45:46 -05:00
|
|
|
const videoType = [
|
|
|
|
'avi',
|
|
|
|
'flv',
|
|
|
|
'm2v',
|
|
|
|
'm4v',
|
|
|
|
'mkv',
|
|
|
|
'mov',
|
|
|
|
'mp4',
|
|
|
|
'mpeg',
|
|
|
|
'mpg',
|
|
|
|
'mts',
|
|
|
|
'mxf',
|
|
|
|
'ts',
|
|
|
|
'vob',
|
|
|
|
'ogv',
|
|
|
|
'webm',
|
|
|
|
'wmv',
|
|
|
|
]
|
2023-02-02 03:53:26 -05:00
|
|
|
const audioType = ['aac', 'aiff', 'flac', 'm4a', 'mp2', 'mp3', 'ogg', 'opus', 'wav', 'wma']
|
2023-11-16 09:45:46 -05:00
|
|
|
const imageType = [
|
|
|
|
'apng',
|
|
|
|
'avif',
|
|
|
|
'bmp',
|
|
|
|
'exr',
|
|
|
|
'gif',
|
|
|
|
'jpeg',
|
|
|
|
'jpg',
|
|
|
|
'png',
|
|
|
|
'psd',
|
|
|
|
'tga',
|
|
|
|
'tif',
|
|
|
|
'tiff',
|
|
|
|
'webp',
|
|
|
|
]
|
2023-02-02 03:53:26 -05:00
|
|
|
const ext = path.split('.').pop()
|
|
|
|
|
|
|
|
if (ext) {
|
2024-05-15 02:53:25 -04:00
|
|
|
if (liveType.includes(ext.toLowerCase())) {
|
2023-12-07 16:00:05 -05:00
|
|
|
return 'live'
|
2024-05-15 02:53:25 -04:00
|
|
|
} else if (videoType.includes(ext.toLowerCase())) {
|
2023-02-02 03:53:26 -05:00
|
|
|
return 'video'
|
2024-05-15 02:53:25 -04:00
|
|
|
} else if (audioType.includes(ext.toLowerCase())) {
|
2023-02-02 03:53:26 -05:00
|
|
|
return 'audio'
|
2024-05-15 02:53:25 -04:00
|
|
|
} else if (imageType.includes(ext.toLowerCase())) {
|
2023-02-02 03:53:26 -05:00
|
|
|
return 'image'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
2024-10-02 04:26:50 -04:00
|
|
|
function dir_file(path: string): {dir: string, file: string} {
|
|
|
|
const index = path.lastIndexOf('/')
|
|
|
|
const dir = path.substring(0, index + 1) || '/'
|
|
|
|
const file = path.substring(index + 1)
|
|
|
|
|
|
|
|
return {dir, file}
|
|
|
|
}
|
|
|
|
|
2023-11-16 09:45:46 -05:00
|
|
|
return {
|
|
|
|
fileSize,
|
|
|
|
formatLog,
|
|
|
|
timeToSeconds,
|
|
|
|
secToHMS,
|
|
|
|
numberToHex,
|
|
|
|
hexToNumber,
|
|
|
|
filename,
|
2024-04-07 17:27:52 -04:00
|
|
|
parent,
|
2023-11-16 09:45:46 -05:00
|
|
|
toMin,
|
|
|
|
secondsToTime,
|
|
|
|
mediaType,
|
2024-10-02 04:26:50 -04:00
|
|
|
dir_file,
|
2023-11-16 09:45:46 -05:00
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
export const playlistOperations = () => {
|
|
|
|
function genUID() {
|
2023-11-16 09:45:46 -05:00
|
|
|
return String(Date.now().toString(32) + Math.random().toString(16)).replace(/\./g, '')
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
2024-04-17 03:55:57 -04:00
|
|
|
function processPlaylist(date: string, list: PlaylistItem[], forSave: boolean) {
|
|
|
|
const configStore = useConfig()
|
|
|
|
|
|
|
|
let begin = configStore.playout.playlist.startInSec
|
2023-01-11 04:54:25 -05:00
|
|
|
|
|
|
|
const newList = []
|
|
|
|
|
|
|
|
for (const item of list) {
|
2024-04-17 03:55:57 -04:00
|
|
|
if (configStore.playout.playlist.startInSec === begin) {
|
2024-04-19 04:59:17 -04:00
|
|
|
item.date = date
|
2024-04-17 03:55:57 -04:00
|
|
|
}
|
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (forSave) {
|
|
|
|
delete item.date
|
2023-01-11 04:54:25 -05:00
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (!item.audio) {
|
|
|
|
delete item.audio
|
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (!item.category) {
|
|
|
|
delete item.category
|
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (!item.custom_filter) {
|
|
|
|
delete item.custom_filter
|
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
|
2024-05-05 15:46:22 -04:00
|
|
|
if (!item.title) {
|
|
|
|
delete item.title
|
|
|
|
}
|
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (
|
|
|
|
begin + (item.out - item.in) >
|
|
|
|
configStore.playout.playlist.startInSec + configStore.playout.playlist.lengthInSec
|
|
|
|
) {
|
|
|
|
item.out =
|
|
|
|
configStore.playout.playlist.startInSec + configStore.playout.playlist.lengthInSec - begin
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!item.uid) {
|
|
|
|
item.uid = genUID()
|
|
|
|
}
|
2023-01-11 04:54:25 -05:00
|
|
|
|
2024-04-19 04:59:17 -04:00
|
|
|
if (
|
|
|
|
begin >= configStore.playout.playlist.startInSec + configStore.playout.playlist.lengthInSec &&
|
|
|
|
!configStore.playout.playlist.infinit
|
|
|
|
) {
|
2024-04-17 03:55:57 -04:00
|
|
|
item.overtime = true
|
2024-05-12 15:00:26 -04:00
|
|
|
} else if (item.overtime) {
|
|
|
|
delete item.overtime
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
2024-04-19 04:59:17 -04:00
|
|
|
|
|
|
|
item.begin = begin
|
2023-01-11 04:54:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
newList.push(item)
|
|
|
|
|
|
|
|
begin += item.out - item.in
|
|
|
|
}
|
|
|
|
|
|
|
|
return newList
|
|
|
|
}
|
|
|
|
|
|
|
|
return { processPlaylist, genUID }
|
|
|
|
}
|