UK & US TV for Ex-pats

X-Pat TV 1 was the first of XP TV Global’s TV stations, and is primarily a music channel.

Given our central aim of providing an English-speaking global service, most of the music and musicians we feature are from the UK & US.

CLICK HERE TO WATCH

Vintage TV and Movies. The best of UK & US comedy, drama, and documentaries from the 40’s to the 90’s.

Remember the good old days when you could watch one channel all night and still catch all your favourites? That was the brief for XPTV2 – A good old fashioned TV station with all the best classic TV in one place, like BBC, ITV, ABC, and CBS used to be.

Featuring classic old TV like Benny Hill, The Flintstones, The Addams Family, with evenings full of great sitcom and drama, and The Dukes Of Hazzard every afternoon.

CLICK HERE TO WATCH

A “binge watch” channel full of the very best of US TV drama and comedy 24/7

On this channel we play full seasons of some of the best US TV series back-to-back.

From great adventure shows like Charlie’s Angels and The A-Team, to classic sitcoms like Cheers! and Happy Days.

Now Playing: Diagnosis Murder

CLICK HERE TO WATCH

A tribute to all the best British comedy including The Two Ronnies, Morecambe & Wise, Black Adder, The Vicar Of Dibley, and lots more.

And don’t forget all your favourite Carry On movies back-to-back every Saturday.

CLICK HERE TO WATCH

A brand new music channel, playing anthems for all, 24/7.

Party in the day ,or dance the night away. Pop World TV is based on popular music artists from around the globe.

Whether you fancy a little Madonna, a touch of Jessie J, or anything from High School Musical to the Cha Cha Slide then we have you covered.

CLICK HERE TO WATCH

Main Server URL

; let programmes = []; let currentTimezone = 'Europe/London'; let scrollPosition = 0; function fetchData() { $.ajax({ url: 'https://d1e7iy84y3j6f2.cloudfront.net/xptvglobal.xml', dataType: 'xml', success: function(data) { channels = []; $(data).find('channel').each(function() { channels.push({ id: $(this).attr('id'), name: $(this).find('display-name').text(), logo: $(this).find('icon').attr('src') }); }); programmes = []; $(data).find('programme').each(function() { programmes.push({ channel: $(this).attr('channel'), start: moment.tz($(this).attr('start'), 'YYYYMMDDHHmmss Z', currentTimezone), stop: moment.tz($(this).attr('stop'), 'YYYYMMDDHHmmss Z', currentTimezone), title: $(this).find('title').text() }); }); renderGrid(); updateTimeRuler(); }, error: function() { console.error('Error fetching XML data'); } }); } function renderGrid() { const gridContainer = $('#grid'); gridContainer.empty(); const start = moment(currentDate).tz(currentTimezone); const end = moment(currentDate).add(12, 'hours').tz(currentTimezone); const visibleProgrammes = programmes.filter(p => p.start.isBefore(end) && p.stop.isAfter(start)); const groupedProgrammes = groupProgrammesByChannel(visibleProgrammes); channels.forEach(channel => { const channelRow = $('
'); const channelElement = $(`
${channel.name} logo
`); channelRow.append(channelElement); const programmesWrapper = $('
'); const programmesElement = $('
'); const rowContent = $('
'); const channelProgrammes = groupedProgrammes[channel.id] || []; for (let i = 0; i < 12; i++) { const cellStart = moment(currentDate).add(i, 'hours').tz(currentTimezone); const cellEnd = moment(cellStart).add(1, 'hour'); const cellProgrammes = channelProgrammes.filter(p => p.start.isBefore(cellEnd) && p.stop.isAfter(cellStart)); if (cellProgrammes.length > 0) { cellProgrammes.forEach(prog => { const startTime = prog.start.tz(currentTimezone).format('h:mm A'); const endTime = prog.stop.tz(currentTimezone).format('h:mm A'); const start = moment.max(prog.start.tz(currentTimezone), cellStart); const stop = moment.min(prog.stop.tz(currentTimezone), cellEnd); const width = stop.diff(start, 'minutes') / 60 * HOUR_WIDTH; rowContent.append(`
${prog.title}
${startTime} - ${endTime}
`); }); } else { rowContent.append(`
No Programme
`); } } programmesElement.append(rowContent); programmesWrapper.append(programmesElement); channelRow.append(programmesWrapper); gridContainer.append(channelRow); }); updateCurrentTimeLine(); updateScrollPosition(); updateTimeRuler(); } function groupProgrammesByChannel(programmes) { return programmes.reduce((acc, prog) => { if (!acc[prog.channel]) acc[prog.channel] = []; acc[prog.channel].push(prog); return acc; }, {}); } function updateTimeRuler() { const ruler = $('#timeRuler'); ruler.empty(); const programmesWrapper = $('.programmes-wrapper'); const programmesOffset = programmesWrapper.offset().left; const start = moment(currentDate).tz(currentTimezone); const end = moment(currentDate).add(12, 'hours').tz(currentTimezone); ruler.css('left', `${programmesOffset}px`); for (let i = 0; i < 12; i++) { const time = moment(start).add(i, 'hours'); ruler.append(`
${time.format('h A')}
`); } } function updateCurrentTimeLine() { $('.current-time').remove(); const now = moment().tz(currentTimezone); const start = moment(currentDate).tz(currentTimezone); const end = moment(currentDate).add(12, 'hours').tz(currentTimezone); if (now.isBetween(start, end)) { const left = (now.diff(start, 'minutes') / 60) * HOUR_WIDTH; $('.programmes').append(`
`); } } function updateScrollPosition() { $('.time-ruler').css('transform', `translateX(-${scrollPosition}px)`); $('.programmes').css('transform', `translateX(-${scrollPosition}px)`); } let popupTimeout; function showPopup(program, x, y) { clearTimeout(popupTimeout); popupTimeout = setTimeout(() => { const startTime = moment(program.data('start')).tz(currentTimezone); const endTime = moment(program.data('end')).tz(currentTimezone); const popupContent = `

${program.find('.programme-title').text()}

Start: ${startTime.format('h:mm A')}
End: ${endTime.format('h:mm A')}
Date: ${startTime.format('ddd MMM D, YYYY')}
`; $('#popup-content').html(popupContent); const popup = $('#popup'); popup.css({ display: 'block', left: `${Math.min(x + 10, window.innerWidth - popup.outerWidth())}px`, top: `${Math.min(y + 10, window.innerHeight - popup.outerHeight())}px` }); setTimeout(() => popup.addClass('show'), 10); }, 1000); } function hidePopup() { clearTimeout(popupTimeout); const popup = $('#popup'); popup.removeClass('show'); setTimeout(() => popup.css('display', 'none'), 300); } function updateDateDisplay() { const dateDisplay = $('#date-display'); dateDisplay.text(moment(currentDate).format('ddd MMM D, YYYY')); } function openChannelLink(channelId) { let url; switch (channelId.toLowerCase()) { case 'xptv1': url = `https://xptv.live/?channel=xptv1`; break; case 'xptv2': url = `https://xptv.live/?channel=xptv2`; break; case 'xptvus': url = `https://xptv.live/?channel=xptvUS`; break; case 'xptvuk': url = `https://xptv.live/?channel=xptvUK`; break; case 'popworld': url = `https://xptv.live/?channel=popworld`; break; case 'xpr1': url = 'https://xpradioone.com'; break; case 'xpr2': url = 'https://xpradiotwo.com'; break; default: console.error('Unknown channel:', channelId); return; } window.open(url, '_blank'); } $('.grid').on('mouseenter', '.programme', function(event) { showPopup($(this), event.pageX, event.pageY); }).on('mouseleave', '.programme', function() { hidePopup(); }).on('click', '.programme', function() { const channelId = $(this).closest('.channel-row').find('.channel').data('channel-id'); openChannelLink(channelId); }); $('#popup-close').on('click', hidePopup); $('#earlier').on('click', function() { currentDate.subtract(8, 'hours'); renderGrid(); scrollPosition = 0; updateScrollPosition(); updateDateDisplay(); }); $('#later').on('click', function() { currentDate.add(8, 'hours'); renderGrid(); scrollPosition = 0; updateScrollPosition(); updateDateDisplay(); }); $(document).ready(function() { const savedTimezone = localStorage.getItem('selectedTimezone'); if (savedTimezone) { currentTimezone = savedTimezone; } else { currentTimezone = moment.tz.guess(); } $('#timezone-select').val(currentTimezone); fetchData(); setInterval(updateCurrentTimeLine, 60000); updateDateDisplay(); }); $('#timezone-select').on('change', function() { currentTimezone = $(this).val(); localStorage.setItem('selectedTimezone', currentTimezone); currentDate = moment.tz(currentDate, currentTimezone); renderGrid(); scrollPosition = 0; updateScrollPosition(); updateDateDisplay(); }); moment.tz.names().forEach(function(tz) { $('#timezone-select').append($('
error: Content is protected !!