mirror of
https://github.com/iptv-org/epg
synced 2026-05-10 19:37:00 -04:00
this change builds one massive freeview TV guide for the entire uk, as it merges the guide for every region/transmitter group into one single guide, i have tried my best to remove duplicate channels from the guide, but, specifically with the bbc shifting some of their IDs for some regions, and 'that's tv' owning nearly all the local tv licences in the UK, it is impossible to remove all duplicates
96 lines
3.1 KiB
JavaScript
96 lines
3.1 KiB
JavaScript
const axios = require('axios')
|
|
const dayjs = require('dayjs')
|
|
const utc = require('dayjs/plugin/utc')
|
|
const parseDuration = require('parse-duration').default
|
|
|
|
dayjs.extend(utc)
|
|
|
|
module.exports = {
|
|
site: 'freeview.co.uk',
|
|
days: 2,
|
|
url({ date, channel }) {
|
|
const [networkId] = channel.site_id.split('#')
|
|
const startTimestamp = date.startOf('d').unix()
|
|
|
|
return `https://www.freeview.co.uk/api/tv-guide?nid=${networkId}&start=${startTimestamp}`
|
|
},
|
|
async parser({ content, channel }) {
|
|
let programs = []
|
|
let items = parseItems(content, channel)
|
|
for (const item of items) {
|
|
const start = parseStart(item)
|
|
const duration = parseDuration(item.duration)
|
|
const stop = start.add(duration, 'ms')
|
|
const details = await loadProgramDetails(item)
|
|
const synopsis = details?.synopsis
|
|
programs.push({
|
|
title: item.main_title,
|
|
subtitle: item.secondary_title,
|
|
description: synopsis?.long || synopsis?.medium || synopsis?.short || null,
|
|
image: parseImage(item),
|
|
start,
|
|
stop
|
|
})
|
|
}
|
|
|
|
return programs
|
|
},
|
|
async channels() {
|
|
const startTimestamp = dayjs.utc().startOf('d').unix()
|
|
let channels = []
|
|
for (let networkId = 64257; networkId <= 64425; networkId++) { // loop through all valid networkIds starting from 64257 (Greater London) to 64425 (Belfast) to ensure we can get all the channels available on freeview
|
|
console.log(networkId)
|
|
const data = await axios
|
|
.get(`https://www.freeview.co.uk/api/tv-guide?nid=${networkId}&start=${startTimestamp}`)
|
|
.then(r => r.data)
|
|
.catch(console.log)
|
|
|
|
channels = channels.concat(data.data.programs.map(item => ({
|
|
lang: 'en',
|
|
site_id: `${networkId}#${item.service_id}`,
|
|
name: item.title
|
|
})))
|
|
}
|
|
const uniqueServiceIds = Array.from(new Set(channels.map(c => c.site_id.split('#')[1])))
|
|
return uniqueServiceIds.map(serviceId => {
|
|
return channels.find(c => c.site_id.split('#')[1] === serviceId)
|
|
})
|
|
}
|
|
}
|
|
|
|
function parseImage(item) {
|
|
return item.image_url ? `${item.image_url}?w=800` : null
|
|
}
|
|
|
|
function parseStart(item) {
|
|
return dayjs(item.start_time)
|
|
}
|
|
|
|
function parseItems(content, channel) {
|
|
try {
|
|
const data = JSON.parse(content)
|
|
const programs = data?.data?.programs
|
|
if (!Array.isArray(programs)) return []
|
|
const [, channelId] = channel.site_id.split('#')
|
|
const channelData = programs.find(p => p.service_id === channelId)
|
|
const channelPrograms = channelData?.events
|
|
if (!Array.isArray(channelPrograms)) return []
|
|
|
|
return channelPrograms
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
async function loadProgramDetails(item) {
|
|
const url = `https://www.freeview.co.uk/api/program?pid=${item.program_id}&start_time=${item.start_time}&duration=${item.duration}`
|
|
const data = await axios
|
|
.get(url)
|
|
.then(r => {
|
|
const programs = r?.data?.data?.programs
|
|
return Array.isArray(programs) && programs.length > 0 ? programs[0] : {}
|
|
})
|
|
.catch(console.log)
|
|
return data || {}
|
|
}
|