Files
epg/sites/freeview.co.uk/freeview.co.uk.config.js
._______166 cf1f841d5b Freeview: Pull all channels from every region
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
2026-04-22 23:21:59 +01:00

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 || {}
}