Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Play live tv audio on homepage & arabic live tv on the On Demand TV page 😰 #12242

Closed
wants to merge 14 commits into from
Closed
78 changes: 78 additions & 0 deletions data/arabic/bbc_arabic_tv/livetv.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"data": {
"metadata": {
"type": "Live TV",
"atiAnalytics": {
"pageIdentifier": "arabic.bbc_arabic_tv.livetv.page",
"contentType": "player-episode",
"pageTitle": "مباشر: تلفزيون بي بي سي عربي",
"contentId": "urn:bbc:pips:sid:bbc_arabic_tv"
}
},
"language": "ar",
"brandTitle": "مباشر: تلفزيون بي بي سي عربي",
"episodeTitle": "يقدم لكم تلفزيون بي بي سي العربي الأخبار والأخبار العاجلة والتحليلات والحوارات والبرامج الوثائقية، على مدى 24 ساعة كل يوم.",
"headline": "",
"shortSynopsis": "ويمكنكم التقاط القناة عبر الأطباق اللاقطة",
"mediumSynopsis": "ويمكنكم التقاط القناة عبر الأطباق اللاقطة",
"id": "urn:bbc:ares:ws_media:brand:bbc_arabic_tv",
"brandId": "bbc_arabic_tv",
"episodeId": "bbc_arabic_tv",
"masterBrand": "bbc_arabic_tv",
"releaseDateTimeStamp": null,
"imageUrl": "ichef.bbc.co.uk/images/ic/$recipe/p08b23t4.png",
"imageAltText": null,
"promoBrandTitle": "مباشر: تلفزيون بي بي سي عربي",
"durationISO8601": "PT0S",
"thumbnailImageUrl": "https://ichef.bbc.co.uk/images/ic/$recipe/p08b23t4.png",
"episodeAvailability": "available",
"recentEpisodes": [],
"mediaBlocks": [
{
"type": "tv",
"model": {
"id": "bbc_arabic_tv",
"subType": "episode",
"format": "Video",
"title": "مباشر: تلفزيون بي بي سي عربي",
"synopses": {
"short": "ويمكنكم التقاط القناة عبر الأطباق اللاقطة.",
"medium": "ويمكنكم التقاط القناة عبر الأطباق اللاقطة."
},
"imageUrl": "ichef.bbc.co.uk/images/ic/$recipe/p08b23t4.png",
"embedding": false,
"advertising": false,
"versions": [
{
"versionId": "bbc_arabic_tv",
"types": ["Original"],
"duration": null,
"durationISO8601": "PT0S",
"warnings": {},
"availableTerritories": {
"uk": true,
"nonUk": true,
"world": false
},
"availableFrom": "2023-04-16T04:30:00.000Z",
"availabilityStatus": "available",
"availableUntil": null
}
],
"availability": "available",
"smpKind": "programme",
"episodeTitle": "",
"type": "media"
}
},
{
"type": "mediaOverrides",
"model": {
"language": "ar",
"pageIdentifierOverride": "arabic.bbc_arabic_tv.livetv.page"
}
}
]
},
"contentType": "application/json; charset=utf-8"
}
78 changes: 78 additions & 0 deletions data/persian/bbc_persian_tv/livetv.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"data": {
"metadata": {
"type": "Live TV",
"atiAnalytics": {
"pageIdentifier": "persian.bbc_persian_tv.livetv.page",
"contentType": "player-episode",
"pageTitle": "تلویزیون فارسی بی‌بی‌سی: پخش زنده اینترنتی",
"contentId": "urn:bbc:pips:sid:bbc_persian_tv"
}
},
"language": "fa",
"brandTitle": "تلویزیون فارسی بی‌بی‌سی: پخش زنده اینترنتی",
"episodeTitle": "برنامه تصویری چشم انداز بامدادی رادیو بی‌بی‌سی",
"headline": "برنامه تصویری چشم انداز بامدادی رادیو بی‌بی‌سی",
"shortSynopsis": "",
"mediumSynopsis": "اگر برای تماشای ویدیو در این صفحه به مشکلی برخوردید، می‌توانید پخش زنده را از کانال یوتیوب ما دنبال کنید. برنامه‌های تلویزیون فارسی، هر روز به طور مستقیم و زنده از وبسایت فارسی بی‌بی‌سی هم پخش می شوند. با این حال، امکان تماشای بخشی از این برنامه‌ها به دلیل نداشتن حق پخش آن از طریق وبسایت، در پخش زنده از وبسایت وجود ندارد. پس از اتمام این برنامه‌ها، پخش زنده برنامه‌های تلویزیونی از طریق وبسایت ادامه پیدا خواهد کرد. آدرس پست الکترونیک بخش فارسی بی‌بی‌سی: [email protected]",
"id": "urn:bbc:ares:ws_media:brand:bbc_persian_tv",
"brandId": "bbc_persian_tv",
"episodeId": "bbc_persian_tv",
"masterBrand": "bbc_persian_tv",
"releaseDateTimeStamp": null,
"imageUrl": "ichef.bbc.co.uk/images/ic/$recipe/p08b21g3.png",
"imageAltText": null,
"promoBrandTitle": "تلویزیون فارسی بی‌بی‌سی: پخش زنده اینترنتی",
"durationISO8601": "PT1H",
"thumbnailImageUrl": "https://ichef.bbc.co.uk/images/ic/$recipe/p08b21g3.png",
"episodeAvailability": "available",
"recentEpisodes": [],
"mediaBlocks": [
{
"type": "tv",
"model": {
"id": "bbc_persian_tv",
"subType": "episode",
"format": "Video",
"title": "برنامه تصویری چشم انداز بامدادی رادیو بی‌بی‌سی",
"synopses": {
"short": "مجله خبری رادیو بی‌بی‌سی فارسی، شامل تازه‌ترین خبرها، گزارش، گفتگو، تحلیل و تفسیر درباره رویدادهای ایران و جهان.",
"medium": "مجله خبری رادیو بی‌بی‌سی فارسی، شامل تازه‌ترین خبرها، گزارش، گفتگو، تحلیل و تفسیر درباره رویدادهای ایران و جهان."
},
"imageUrl": "ichef.bbc.co.uk/images/ic/$recipe/p08b21g3.png",
"embedding": false,
"advertising": false,
"versions": [
{
"versionId": "bbc_persian_tv",
"types": ["Original"],
"duration": null,
"durationISO8601": "PT0S",
"warnings": {},
"availableTerritories": {
"uk": true,
"nonUk": true,
"world": false
},
"availableFrom": "2023-04-16T04:30:00.000Z",
"availabilityStatus": "available",
"availableUntil": null
}
],
"availability": "available",
"smpKind": "programme",
"episodeTitle": "برنامه تصویری چشم انداز بامدادی رادیو بی‌بی‌سی",
"type": "media"
}
},
{
"type": "mediaOverrides",
"model": {
"language": "fa",
"pageIdentifierOverride": "persian.bbc_persian_tv.tv.w172z7t6cyj651g.page"
}
}
]
},
"contentType": "application/json; charset=utf-8"
}
2 changes: 1 addition & 1 deletion src/app/components/MediaLoader/configs/liveRadio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default ({
return {
playerConfig: {
...basePlayerConfig,
autoplay: false,
autoplay: true,
playlistObject: {
title: headingBlock?.text ?? '',
items: [
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/MediaLoader/configs/tv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default ({
}: ConfigBuilderProps): ConfigBuilderReturnProps => {
const { model: tvMediaBlock } = filterForBlockType(blocks, 'tv');
const video = tvMediaBlock?.versions?.[0] || {};
const holdingImageURL = `https://${tvMediaBlock.imageUrl}`;
const holdingImageURL = `https://${tvMediaBlock.imageUrl.replace('$recipe', '1024x576')}`;

const placeholderConfig = buildPlaceholderConfig({
title: tvMediaBlock.episodeTitle,
Expand Down
16 changes: 16 additions & 0 deletions src/app/pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import React, { useContext } from 'react';
import { jsx } from '@emotion/react';
import VisuallyHiddenText from '#app/components/VisuallyHiddenText';
import MediaLoader from '#app/components/MediaLoader';
import arabicLiveRadio from '#data/arabic/bbc_arabic_radio/liveradio.json';
import { MediaBlock } from '#app/components/MediaLoader/types';
import ATIAnalytics from '../../components/ATIAnalytics';
import {
Curation,
Expand Down Expand Up @@ -43,6 +46,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
frontPageTitle,
lang,
brandName,
service,
} = useContext(ServiceContext);
const { topStoriesTitle, home } = translations;
const {
Expand All @@ -52,6 +56,11 @@ const HomePage = ({ pageData }: HomePageProps) => {
metadata: { atiAnalytics },
} = pageData;
const itemList = getItemList({ curations, name: brandName });

if (service === 'arabic') {
arabicLiveRadio.data.mediaBlock[0].model[2].externalId = 'bbc_arabic_tv';
}

return (
<>
<ChartbeatAnalytics title={title} />
Expand All @@ -70,6 +79,13 @@ const HomePage = ({ pageData }: HomePageProps) => {
/>
<Ad slotType="leaderboard" />
<main role="main" css={styles.main}>
{service === 'arabic' && (
<div css={styles.mediaPlayer}>
<MediaLoader
blocks={arabicLiveRadio.data.mediaBlock as MediaBlock[]}
/>
</div>
)}
<ATIAnalytics atiData={atiAnalytics} />
<VisuallyHiddenText id="content" tabIndex={-1} as="h1">
{/* eslint-disable-next-line jsx-a11y/aria-role */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const styles = {
margin: `${spacings.QUINTUPLE}rem 0`,
},
}),
mediaPlayer: () =>
css({
display: 'none',
}),
};

export default styles;
1 change: 0 additions & 1 deletion src/app/pages/OnDemandTvPage/OnDemandTvPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export interface OnDemandTVProps {
recentEpisodes?: string[];
episodeTitle: string;
mediumSynopsis?: string;
contentType: ContentType;
};
mediaIsAvailable?: boolean;
MediaError: React.Component;
Expand Down
35 changes: 28 additions & 7 deletions src/app/routes/onDemandTV/getInitialData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@ import { FetchError } from '#app/models/types/fetch';
import { TV_PAGE } from '#app/routes/utils/pageTypes';
import isTest from '#app/lib/utilities/isTest';
import overrideRendererOnTest from '#app/routes/utils/overrideRendererOnTest';
import arabicLiveTV from '#data/arabic/bbc_arabic_tv/livetv.json';
import persianLiveTV from '#data/persian/bbc_persian_tv/livetv.json';
import { Services } from '#app/models/types/global';

const logger = nodeLogger(__filename);

const liveTVMappings: Record<
Extract<Services, 'arabic' | 'persian'>,
object
> = {
arabic: arabicLiveTV,
persian: persianLiveTV,
};

export default async ({
service,
variant,
Expand All @@ -18,13 +29,23 @@ export default async ({
toggles,
}: InitialDataProps) => {
try {
const { status, json } = await fetchDataFromBFF({
pathname: isTest() ? overrideRendererOnTest(pathname) : pathname,
service,
variant,
pageType: TV_PAGE,
getAgent,
});
let status;
let json;

// @ts-expect-error only arabic & persian TV supported
const liveTVData = liveTVMappings[service];
if (pathname.includes('/livetv') && liveTVData) {
status = 200;
json = liveTVData;
} else {
({ status, json } = await fetchDataFromBFF({
pathname: isTest() ? overrideRendererOnTest(pathname) : pathname,
service,
variant,
pageType: TV_PAGE,
getAgent,
}));
}

if (!json?.data) {
throw handleError('On Demand TV data is malformed', 500);
Expand Down
4 changes: 2 additions & 2 deletions src/app/routes/onDemandTV/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { OnDemandTvPage } from '#pages';
import { onDemandTvPath } from '#app/routes/utils/regex';
import { liveTVPath, onDemandTvPath } from '#app/routes/utils/regex';
import { TV_PAGE } from '#app/routes/utils/pageTypes';
import getInitialData from './getInitialData';

export default {
path: onDemandTvPath,
path: [onDemandTvPath, liveTVPath],
exact: true,
component: OnDemandTvPage,
getInitialData,
Expand Down
4 changes: 4 additions & 0 deletions src/app/routes/utils/regex/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
getSecondaryColumnDataRegex,
getRecommendationsDataRegex,
getAfricaEyeTVPageRegex,
getLiveTVRegex,
} from './utils';

const allServices = Object.keys(services);
Expand All @@ -47,6 +48,9 @@ export const homePageDataPath = `${homePagePath}.json`;
export const cpsAssetPagePath = getCpsAssetRegex(allServices);
export const cpsAssetPageDataPath = `${cpsAssetPagePath}.json`;

export const liveTVPath = getLiveTVRegex(allServices);
export const liveTVDataPath = `${liveTVPath}.json`;

export const liveRadioPath = getLiveRadioRegex(allServices);
export const liveRadioDataPath = `${liveRadioPath}.json`;

Expand Down
5 changes: 5 additions & 0 deletions src/app/routes/utils/regex/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ export const getLiveRadioRegex = services => {
return `/:service(${serviceRegex})/:masterBrand(${radioMasterBrandRegex})/:mediaId(liveRadio):lite(${liteRegex})?`;
};

export const getLiveTVRegex = services => {
const serviceRegex = getServiceRegex(services);
return `/:service(${serviceRegex})/:masterBrand(${tvMasterBrandRegex})/:mediaId(livetv):lite(${liteRegex})?`;
};

export const getPodcastEpisodeRegex = services => {
const serviceRegex = getServiceRegex(services);
return `/:service(${serviceRegex}):variant(${variantRegex})?/podcasts/:brandId(${mediaIdRegex})/:mediaId(${mediaIdRegex}):lite(${liteRegex})?`;
Expand Down
8 changes: 8 additions & 0 deletions src/server/local/constructDataFilePath/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ export default ({
masterBrand,
'liveradio.json',
);
case 'liveTV':
return path.join(
process.cwd(),
'data',
service,
masterBrand,
'livetv.json',
);
default:
dataPath = `${id}${variant}.json`;
}
Expand Down
12 changes: 12 additions & 0 deletions src/server/local/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
liveRadioDataPath,
podcastEpisodeDataPath,
podcastBrandDataPath,
liveTVDataPath,
} from '#app/routes/utils/regex';
import { LOCAL_SENDFILE_ERROR } from '#lib/logger.const';
import nodeLogger from '#lib/logger.node';
Expand Down Expand Up @@ -112,6 +113,17 @@ export default server => {

sendDataFile(res, dataFilePath, next);
})
.get(liveTVDataPath, async ({ params }, res, next) => {
const { service, masterBrand } = params;

const dataFilePath = constructDataFilePath({
pageType: 'liveTV',
service,
masterBrand,
});

sendDataFile(res, dataFilePath, next);
})
.get(podcastEpisodeDataPath, async ({ params }, res, next) => {
const { service, brandId, mediaId } = params;

Expand Down
Loading