From fdfa3cc86458548a9373096bb54baec3c680becf Mon Sep 17 00:00:00 2001 From: amtins Date: Mon, 26 Feb 2024 11:54:08 +0100 Subject: [PATCH] refactor: wip --- index.html | 39 + src/dataProvider/model/MediaComposition.js | 3 + src/middleware/srgssr.js | 182 ++- test/__mocks__/srcMediaObj.json | 394 ++++++ .../urn:rts:video:10313496-credits.json | 1208 ++++++----------- test/middleware/srgssr.spec.js | 232 ++-- 6 files changed, 1100 insertions(+), 958 deletions(-) create mode 100644 test/__mocks__/srcMediaObj.json diff --git a/index.html b/index.html index 3b05d5e..e6dbd40 100644 --- a/index.html +++ b/index.html @@ -46,6 +46,16 @@ src: 'urn:rts:video:14683290', type: 'srgssr/urn' }, + _endDate: { + label: 'Block reason end date', + src: 'urn:rts:video:10894367', + type: 'srgssr/urn' + }, + _externalSubtitles: { + label: 'Remote text tracks', + src: 'urn:swi:video:48864812', + type: 'srgssr/urn' + }, }; // Expose Pillarbox and player in the window object for debugging @@ -83,6 +93,35 @@ src: urn, type: "srgssr/urn", }); + + player.on('loadeddata', () => { + player?.textTracks()?.getTrackById('srgssr-chapters')?.addEventListener("cuechange", () => { + const [cue] = Array.from(player?.textTracks()?.getTrackById('srgssr-chapters')?.activeCues); + if (!cue) return; + + console.log('%cChapter', 'background-color: blue', JSON.parse(cue.text).title); + + const chapter = JSON.parse(cue.text); + player.titleBar.update({ + title: chapter.title, + description: chapter.description + }); + }); + + player?.textTracks()?.getTrackById('srgssr-blocked-segments')?.addEventListener("cuechange", () => { + const [cue] = Array.from(player?.textTracks()?.getTrackById('srgssr-blocked-segments')?.activeCues); + if (!cue) return; + + console.log('%cBlock reason', 'background-color: red', JSON.parse(cue.text).blockReason); + }); + + player?.textTracks()?.getTrackById('srgssr-intervals')?.addEventListener("cuechange", () => { + const [cue] = Array.from(player?.textTracks()?.getTrackById('srgssr-intervals')?.activeCues); + if (!cue) return; + + console.log('%cInterval', 'background-color: green', JSON.parse(cue.text).type); + }); + }); diff --git a/src/dataProvider/model/MediaComposition.js b/src/dataProvider/model/MediaComposition.js index dc04716..2b7e3f1 100644 --- a/src/dataProvider/model/MediaComposition.js +++ b/src/dataProvider/model/MediaComposition.js @@ -183,6 +183,7 @@ class MediaComposition { * * @returns {Array} array of sources */ + /* eslint-disable max-lines-per-function */ getMainResources() { const resourceList = this.getResourceList(); @@ -198,6 +199,7 @@ class MediaComposition { blockReason: this.getMainChapter().blockReason, blockedSegments: this.getMainBlockedSegments(), chapters: this.getChapters(), + chapterImageUrl: this.getMainChapterImageUrl(), vendor: this.getMainChapter().vendor, drmList: resource.drmList, dvr: resource.dvr, @@ -212,6 +214,7 @@ class MediaComposition { streaming: resource.streaming, streamOffset: resource.streamOffset, subtitles: this.getFilteredExternalSubtitles(), + title: this.getMainChapter().title, intervals: this.getMainTimeIntervals(), tokenType: resource.tokenType, url: resource.url, diff --git a/src/middleware/srgssr.js b/src/middleware/srgssr.js index 1f16443..75aa7ac 100644 --- a/src/middleware/srgssr.js +++ b/src/middleware/srgssr.js @@ -166,15 +166,18 @@ class SrgSsr { * * @returns {undefined|Boolean} */ - static blockingReason(player, blockReason, srcMediaObj) { - if (!blockReason) return; + static blockingReason(player, srcMediaObj) { + if (!srcMediaObj.mediaData.blockReason) return; - const message = player.localize(blockReason); + const message = player.localize(srcMediaObj.mediaData.blockReason); SrgSsr.error(player, { code: MediaError.MEDIA_ERR_ABORTED, message, - metadata: { errorType: blockReason, src: srcMediaObj }, + metadata: { + errorType: srcMediaObj.mediaData.blockReason, + src: srcMediaObj + }, }); return true; @@ -416,6 +419,110 @@ class SrgSsr { return resource || resources[0]; } + /** + * Get the source media object. + * + * @param {import('video.js/dist/types/player').default} player + * @param {Object} srcObj + * + * @returns {Promise} - The composed source media data. + */ + static async getSrcMediaObj(player, srcObj) { + const { src: urn, ...srcOptions } = srcObj; + const { mediaComposition } = await SrgSsr.getMediaComposition( + urn, + SrgSsr.dataProvider(player) + ); + const mainResources = await SrgSsr.composeMainResources( + mediaComposition + ); + const mediaData = SrgSsr.getMediaData(mainResources); + + return SrgSsr.composeSrcMediaData(srcOptions, mediaData); + } + + /** + * Handles the middleware's current time function. + * - If the current time is between the start and end of a blocked segment, + * the blocked portion will be skipped. + * + * _Note_: This function should disappear as soon as this behavior is + * supported on the packaging side. + * + * @param {import('video.js/dist/types/player').default} player + * @param {number} currentTime + * + * @returns {number} + */ + static handleCurrentTime(player, currentTime) { + const blockedSegmentEndTime = SrgSsr + .getBlockedSegmentEndTime(player, currentTime); + + if (Number.isFinite(blockedSegmentEndTime)) { + player.currentTime(blockedSegmentEndTime); + + return blockedSegmentEndTime; + } + + return currentTime; + } + + /** + * Handles the middleware's set current time function. + * - Modify the current time if the value is between the start and end of a + * blocked segment. + * + * _Note_: This function should disappear as soon as this behavior is + * supported on the packaging side. + * + * @param {import('video.js/dist/types/player').default} player + * @param {number} currentTime + * + * @returns {number} + */ + static handleSetCurrentTime(player, currentTime) { + const blockedSegmentEndTime = SrgSsr + .getBlockedSegmentEndTime(player, currentTime); + + return Number + .isFinite(blockedSegmentEndTime) ? blockedSegmentEndTime : currentTime; + } + + /** + * Handles the middleware's set set source function. + * + * This function allows to: + * - resolve a URN into media that can be played by the player + * - initialize media playback tracking + * - update the title bar + * - handle blocking reasons + * - add remote subtitles + * + * @param {import('video.js/dist/types/player').default} player + * @param {number} currentTime + * + * @returns {number} + */ + static async handleSetSource(player, srcObj, next) { + try { + const srcMediaObj = await SrgSsr.getSrcMediaObj(player, srcObj); + + SrgSsr.srgAnalytics(player); + SrgSsr.updateTitleBar(player, srcMediaObj); + SrgSsr.updatePoster(player, srcMediaObj); + + if (SrgSsr.blockingReason(player, srcMediaObj)) return; + + SrgSsr.addTextTracks(player, srcMediaObj); + + return next(null, srcMediaObj); + } catch (error) { + if (SrgSsr.dataProviderError(player, error)) return; + + return next(error); + } + } + /** * SRG SSR analytics singleton. * @@ -447,10 +554,10 @@ class SrgSsr { * @param {import('../dataProvider/model/MediaComposition.js').default} mediaComposition * @param {Image} imageService */ - static updatePoster(player, mediaComposition, imageService = Image) { + static updatePoster(player, { mediaData }, imageService = Image) { player.poster( imageService.scale({ - url: mediaComposition.getMainChapterImageUrl(), + url: mediaData.chapterImageUrl, }) ); } @@ -461,12 +568,12 @@ class SrgSsr { * @param {import('video.js/dist/types/player').default} player * @param {import('../dataProvider/model/MediaComposition.js').default} mediaComposition */ - static updateTitleBar(player, mediaComposition) { + static updateTitleBar(player, { mediaData }) { if (!player.titleBar) return; player.titleBar.update({ - title: mediaComposition.getMainChapter().vendor, - description: mediaComposition.getMainChapter().title, + title: mediaData.vendor, + description: mediaData.title, }); } @@ -474,60 +581,17 @@ class SrgSsr { * Middleware to resolve SRG SSR URNs into playable media. * * @param {import('video.js/dist/types/player').default} player - * @param {Image} imageService * * @returns {Object} */ - /* eslint-disable max-lines-per-function */ - static middleware(player, imageService = Image) { + static middleware(player) { return { - currentTime: (currentTime) => { - const blockedSegmentEndTime = SrgSsr - .getBlockedSegmentEndTime(player, currentTime); - - if (Number.isFinite(blockedSegmentEndTime)) { - player.currentTime(blockedSegmentEndTime); - } - - return blockedSegmentEndTime ?? currentTime; - }, - setCurrentTime: (currentTime) => { - return SrgSsr - .getBlockedSegmentEndTime(player, currentTime) ?? currentTime; - }, - /* eslint max-statements: ["error", 20]*/ - setSource: async (srcObj, next) => { - try { - const { src: urn, ...srcOptions } = srcObj; - const { mediaComposition } = await SrgSsr.getMediaComposition( - urn, - SrgSsr.dataProvider(player) - ); - const mainResources = await SrgSsr.composeMainResources( - mediaComposition - ); - const mediaData = SrgSsr.getMediaData(mainResources); - const srcMediaObj = SrgSsr.composeSrcMediaData(srcOptions, mediaData); - - SrgSsr.srgAnalytics(player); - SrgSsr.updateTitleBar(player, mediaComposition); - SrgSsr.updatePoster(player, mediaComposition, imageService); - - if (SrgSsr.blockingReason(player, mediaData.blockReason, srcMediaObj)) - return; - - SrgSsr.addRemoteTextTracks(player, mediaData.subtitles); - SrgSsr.addChapters(player, mediaData.urn, mediaData.chapters); - SrgSsr.addBlockedSegments(player, mediaData.blockedSegments); - SrgSsr.addIntervals(player, mediaData.intervals); - - return next(null, srcMediaObj); - } catch (error) { - if (SrgSsr.dataProviderError(player, error)) return; - - return next(error); - } - }, + currentTime: (currentTime) => + SrgSsr.handleCurrentTime(player, currentTime), + setCurrentTime: (currentTime) => + SrgSsr.handleSetCurrentTime(player, currentTime), + setSource: async (srcObj, next) => + SrgSsr.handleSetSource(player, srcObj, next), }; } } diff --git a/test/__mocks__/srcMediaObj.json b/test/__mocks__/srcMediaObj.json new file mode 100644 index 0000000..4c02405 --- /dev/null +++ b/test/__mocks__/srcMediaObj.json @@ -0,0 +1,394 @@ +{ + "src": "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8", + "type": "application/x-mpegURL", + "keySystems": {}, + "mediaData": { + "analyticsData": { + "srg_pr_id": "10313468", + "srg_plid": "9931005", + "ns_st_pl": "Les beaux parleurs", + "ns_st_pr": "Les beaux parleurs du 24.03.2019", + "ns_st_dt": "2019-03-24", + "ns_st_ddt": "2019-03-24", + "ns_st_tdt": "*null", + "ns_st_tm": "*null", + "ns_st_tep": "500087771", + "ns_st_li": "0", + "ns_st_stc": "0867", + "ns_st_st": "RTS Online", + "ns_st_tpr": "9931005", + "ns_st_en": "*null", + "ns_st_ge": "*null", + "ns_st_ia": "*null", + "ns_st_ce": "1", + "ns_st_cdm": "eo", + "ns_st_cmt": "ec", + "srg_unit": "RTS", + "srg_c1": "full", + "srg_c2": "video_la-1ere_les-beaux-parleurs", + "srg_c3": "RTS.ch", + "srg_tv_id": "500087771", + "srg_aod_prid": "10313468", + "ns_st_ep": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "ns_st_ty": "Video", + "ns_st_ci": "10313496", + "ns_st_el": "4827120", + "ns_st_cl": "4827120", + "ns_st_sl": "4827120", + "srg_mgeobl": "false", + "ns_st_tp": "1", + "ns_st_cn": "1", + "ns_st_ct": "vc12", + "ns_st_pn": "1", + "srg_mqual": "HD", + "srg_mpres": "DEFAULT" + }, + "analyticsMetadata": { + "media_episode_id": "10313468", + "media_show_id": "9931005", + "media_show": "Les beaux parleurs", + "media_episode": "Les beaux parleurs du 24.03.2019", + "media_is_livestream": "false", + "media_full_length": "full", + "media_enterprise_units": "RTS", + "media_joker1": "full", + "media_joker2": "video_la-1ere_les-beaux-parleurs", + "media_joker3": "RTS.ch", + "media_is_web_only": "true", + "media_production_source": "produced.for.web", + "media_tv_id": "500087771", + "media_thumbnail": "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9/scale/width/344", + "media_publication_date": "2019-03-24", + "media_publication_time": "11:04:00", + "media_publication_datetime": "2019-03-24T11:04:00+01:00", + "media_content_group": "Les beaux parleurs,La 1ère", + "media_since_publication_d": "1796", + "media_since_publication_h": "43109", + "media_segment": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "media_type": "Video", + "media_segment_id": "10313496", + "media_episode_length": "4827", + "media_segment_length": "4827", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "long", + "media_is_geoblocked": "false", + "media_urn": "urn:rts:video:10313496", + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8" + }, + "chapters": [ + { + "id": "10313496", + "mediaType": "VIDEO", + "vendor": "RTS", + "urn": "urn:rts:video:10313496", + "title": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "description": "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", + "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9", + "imageTitle": "Les beaux parleurs - Y'a pas de fumée sans feu [RTS]", + "type": "EPISODE", + "date": "2019-03-24T11:04:00+01:00", + "duration": 4827120, + "validFrom": "2019-03-24T11:04:00+01:00", + "playableAbroad": true, + "socialCountList": [ + { "key": "srgView", "value": 812 }, + { "key": "srgLike", "value": 0 }, + { "key": "fbShare", "value": 0 }, + { "key": "twitterShare", "value": 0 }, + { "key": "googleShare", "value": 0 }, + { "key": "whatsAppShare", "value": 0 } + ], + "displayable": true, + "position": 0, + "noEmbed": false, + "analyticsData": { + "ns_st_ep": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "ns_st_ty": "Video", + "ns_st_ci": "10313496", + "ns_st_el": "4827120", + "ns_st_cl": "4827120", + "ns_st_sl": "4827120", + "srg_mgeobl": "false", + "ns_st_tp": "1", + "ns_st_cn": "1", + "ns_st_ct": "vc12", + "ns_st_pn": "1", + "ns_st_cdm": "eo", + "ns_st_cmt": "ec" + }, + "analyticsMetadata": { + "media_segment": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "media_type": "Video", + "media_segment_id": "10313496", + "media_episode_length": "4827", + "media_segment_length": "4827", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "long", + "media_is_geoblocked": "false", + "media_is_web_only": "true", + "media_production_source": "produced.for.web", + "media_urn": "urn:rts:video:10313496" + }, + "eventData": "$9db05194d7854399$80484ccbcc3b0481db9c5ee344196397e72e218449a7cf769782062d650c6363ec5787f4fa538e7bcbc2f7ccfaf9f70f5fdc50bde3986541b04285c7125bc0a93731c18e6afea7b0154f874accaf319abb738541e8634ce09c91a499df2faf6d0281e66c6e3ab9f5c77f9c75cfff9297caab58c1894c70551ddbf7f1aa591d5e52a928cfb1055181d9ed6f339fd713abc5f4eae42c299d3411ead600cec4dd927e4b8b8493c0ab1ab67106c12918636b5d4dd0206de8f465b754390ea5c90a1cb3c47228f3421c8152fe9aef74599aca84c2082b2dee4475423e9543b89d0310720ed491f3c5a73ae688c285a4e37fed9fdffe1beb6a33ad94f37ddf48cb3f469d0f43d0df290cd7bac18e66479aa7e23319efa7345f41adc9e8a3c4bb595a0342ebed072b2358abb1d2844889fe37be04b52a072532b95d4378ee5a1ccec3ad", + "resourceList": [ + { + "url": "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8", + "quality": "HD", + "protocol": "HLS", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": false, + "live": false, + "mediaContainer": "FMP4", + "audioCodec": "AAC", + "videoCodec": "H264", + "tokenType": "NONE", + "audioTrackList": [ + { "locale": "fr", "language": "Français", "source": "HLS" } + ], + "analyticsData": { "srg_mqual": "HD", "srg_mpres": "DEFAULT" }, + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8" + } + } + ], + "aspectRatio": "16:9" + }, + { + "id": "10313478", + "mediaType": "VIDEO", + "vendor": "RTS", + "urn": "urn:rts:video:10313478", + "title": "La chronique de Benjamin Décosterd - Les élections vaudoises", + "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313469.image/16x9", + "imageTitle": "La chronique de Benjamin Décosterd - Les élections vaudoises [RTS]", + "type": "CLIP", + "date": "2019-03-24T14:03:03+01:00", + "duration": 294720, + "validFrom": "2019-03-24T11:04:00+01:00", + "playableAbroad": true, + "displayable": true, + "fullLengthUrn": "urn:rts:video:10313496", + "position": 1, + "noEmbed": false, + "analyticsData": { + "ns_st_ep": "La chronique de Benjamin Décosterd - Les élections vaudoises", + "ns_st_ty": "Video", + "ns_st_ci": "10313478", + "ns_st_el": "294720", + "ns_st_cl": "294720", + "ns_st_sl": "294720", + "srg_mgeobl": "false", + "ns_st_tp": "1", + "ns_st_cn": "1", + "ns_st_ct": "vc11", + "ns_st_pn": "1", + "ns_st_cdm": "eo", + "ns_st_cmt": "ec" + }, + "analyticsMetadata": { + "media_segment": "La chronique de Benjamin Décosterd - Les élections vaudoises", + "media_type": "Video", + "media_segment_id": "10313478", + "media_episode_length": "295", + "media_segment_length": "295", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "short", + "media_is_geoblocked": "false", + "media_is_web_only": "true", + "media_production_source": "produced.for.web", + "media_urn": "urn:rts:video:10313478" + }, + "eventData": "$1ca8de52767edc7c$b53972610b30bdea9d4359fc4a078387badc1f3d8426d8636ed83e5a91122627e958e4d483a567a26623211ca61da22316e61b18e967af9f0f1387153dc42f76dc023d7a09693ee942bd7ab35c5b8e39e4bc1b120264b4829887d57906cf629a2d9b52f9628f20f491bd8d2c3a089af78e0358223b383f4af1b98ee4c805956f59ce413194e7784f8bb76f30bbd1890bf35bccfc921b3e9548ce6d6b800ce201ab5aebc7cb30a15eb348d5fbed49d227fc7e9c56918d1ed20e865dedd396cc3c9d61ec96e2053c8363410706218f846aed42f0db7bee0265ad65a95bbac9c3b71bc92b7825db754d00276493337cc316d3bf638d6c79760731a158a4d17d0d54b64cae3c04ee433db2d93c0fce82a9da8c41a4f5970a7baf46cbfd5af903dc7049f1bc1890b4dff524b6dffef34fbfda", + "fullLengthMarkIn": 105000, + "fullLengthMarkOut": 399720, + "resourceList": [ + { + "url": "https://rts-vod-amd.akamaized.net/ww/10313478/7c9449de-245a-3021-bfd8-104ec65dfb5d/master.m3u8", + "quality": "HD", + "protocol": "HLS", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": false, + "live": false, + "mediaContainer": "FMP4", + "audioCodec": "AAC", + "videoCodec": "H264", + "tokenType": "NONE", + "audioTrackList": [ + { "locale": "fr", "language": "Français", "source": "HLS" } + ], + "analyticsData": { "srg_mqual": "HD", "srg_mpres": "DEFAULT" }, + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rts-vod-amd.akamaized.net/ww/10313478/7c9449de-245a-3021-bfd8-104ec65dfb5d/master.m3u8" + } + } + ], + "aspectRatio": "16:9" + }, + { + "id": "10313492", + "mediaType": "VIDEO", + "vendor": "RTS", + "urn": "urn:rts:video:10313492", + "title": "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "description": "Le portrait de Sophie Swaton est brossé avec humour par Claude-Inga Barbey à travers l'un de ses personnages.", + "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313491.image/16x9", + "imageTitle": "Le portrait de Sophie Swaton par Claude-Inga Barbey [RTS]", + "type": "CLIP", + "date": "2019-03-24T14:03:10+01:00", + "duration": 314480, + "validFrom": "2019-03-24T11:04:00+01:00", + "playableAbroad": true, + "displayable": true, + "fullLengthUrn": "urn:rts:video:10313496", + "position": 2, + "noEmbed": false, + "analyticsData": { + "ns_st_ep": "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "ns_st_ty": "Video", + "ns_st_ci": "10313492", + "ns_st_el": "314480", + "ns_st_cl": "314480", + "ns_st_sl": "314480", + "srg_mgeobl": "false", + "ns_st_tp": "1", + "ns_st_cn": "1", + "ns_st_ct": "vc11", + "ns_st_pn": "1", + "ns_st_cdm": "eo", + "ns_st_cmt": "ec" + }, + "analyticsMetadata": { + "media_segment": "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "media_type": "Video", + "media_segment_id": "10313492", + "media_episode_length": "314", + "media_segment_length": "314", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "short", + "media_is_geoblocked": "false", + "media_is_web_only": "true", + "media_production_source": "produced.for.web", + "media_urn": "urn:rts:video:10313492" + }, + "eventData": "$6eabc1a0debc4468$58f6fe4a463bdfaed3002421b89d621bfdf317941437ea4938085440bc69ad0bf903374a872acd6b43150231479dc804e8e2ab8ac8542ddee99cbee06683a2f262175c5e4464a0dfaaa6d9d0b2154ebcce3ccf5962b1fea46b274d551b88d568f9be511e91b78511726ad1043c49fed7c636630191c24a70ff8e78c122e717021cf8dc2fa018352e32a5aa5e7946cef535eef7f9b8edb5824bab1e595ae896948ab6b21366eb5cff04f4e41131279eb26efbf6a7b653400531a1248f6ff5d73527c24d25fab839373fc6bc74dce8fddc83ab23f9498a06c94aa86885c18b0c72d86f4b463d4146a3fa27a1c8136ab124546e0690c24a9a6a0d61b427cdf0a1704e30be95955dfb06e089a5caa3a80a2abfc5864d2b0b12a05c1d5481a4200ef0f15b2cef1996592112ac84656af6f3d6", + "fullLengthMarkIn": 3336120, + "fullLengthMarkOut": 3650600, + "resourceList": [ + { + "url": "https://rts-vod-amd.akamaized.net/ww/10313492/372ad0c8-912c-3218-9bda-d9fff5d977f9/master.m3u8", + "quality": "HD", + "protocol": "HLS", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": false, + "live": false, + "mediaContainer": "FMP4", + "audioCodec": "AAC", + "videoCodec": "H264", + "tokenType": "NONE", + "audioTrackList": [ + { "locale": "fr", "language": "Français", "source": "HLS" } + ], + "analyticsData": { "srg_mqual": "HD", "srg_mpres": "DEFAULT" }, + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rts-vod-amd.akamaized.net/ww/10313492/372ad0c8-912c-3218-9bda-d9fff5d977f9/master.m3u8" + } + } + ], + "aspectRatio": "16:9" + }, + { + "id": "10277526", + "mediaType": "AUDIO", + "vendor": "RTS", + "urn": "urn:rts:audio:10277526", + "title": "Les beaux parleurs - Y'a pas de fumée sans feu (audio)", + "description": "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", + "imageUrl": "https://www.rts.ch/2019/03/24/16/10/10313604.image/16x9", + "imageTitle": "Les beaux parleurs. [Julien Audemars/Philippe Christin - RTS]", + "imageCopyright": "Julien Audemars/Philippe Christin - RTS", + "type": "CLIP", + "date": "2019-03-24T11:03:50+01:00", + "duration": 5170000, + "podcastHdUrl": "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3", + "playableAbroad": true, + "displayable": true, + "fullLengthUrn": "urn:rts:video:10313496", + "position": 3, + "noEmbed": false, + "analyticsMetadata": { + "media_segment": "Les beaux parleurs - Y'a pas de fumée sans feu (audio)", + "media_type": "Audio", + "media_segment_id": "10277526", + "media_episode_length": "5170", + "media_segment_length": "5170", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "long", + "media_is_geoblocked": "false", + "media_is_web_only": "false", + "media_production_source": "produced.for.broadcasting", + "media_urn": "urn:rts:audio:10277526" + }, + "eventData": "$8448618a46137271$2345a49d01fecfd8e365920836847642fdbb344395c09cb03ba124bc565a7db127fa2590dcf518fa2c5005c6fe8f8dc080e5089ddecf442fb6861ba4d6c5c5c0576f7e800badd46fff89abadebbc5a20c602b00e5030b8e75275c67a8dfa3babce94b173aba9b8cbd93764e08b2a3fcf70a29f4942c8021518752c4773b148a87f60c17750a75d775e5769d26986bdad1e3dee33a2c30c0969a0250f18e84d818052b80e63bea28d285b35ffe5fafc402d67f61da8c1e666c5e82451de3b09c244f1fdd0fb30d985e1c6e78dc696ee959d866f618e965d76328320fd1ff9dd57b08941fc4545b9598107de3d36ee5fcc1e1e848a433579befffc9e8aba70187b12c8bc481dadd046b54a8614b0e1cf6f9408aa5a19c1941f0e65b10e14faeb4dc96f7d1b120420ed4d515523cf9c5d1c", + "fullLengthMarkIn": 0, + "fullLengthMarkOut": 0, + "resourceList": [ + { + "url": "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3", + "quality": "HQ", + "protocol": "HTTPS", + "encoding": "MP3", + "mimeType": "audio/mpeg", + "presentation": "DEFAULT", + "streaming": "PROGRESSIVE", + "dvr": false, + "live": false, + "mediaContainer": "NONE", + "audioCodec": "MP3", + "videoCodec": "NONE", + "tokenType": "NONE", + "analyticsMetadata": { + "media_streaming_quality": "HQ", + "media_special_format": "DEFAULT", + "media_url": "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3" + } + } + ] + } + ], + "vendor": "RTS", + "dvr": false, + "eventData": "$9db05194d7854399$80484ccbcc3b0481db9c5ee344196397e72e218449a7cf769782062d650c6363ec5787f4fa538e7bcbc2f7ccfaf9f70f5fdc50bde3986541b04285c7125bc0a93731c18e6afea7b0154f874accaf319abb738541e8634ce09c91a499df2faf6d0281e66c6e3ab9f5c77f9c75cfff9297caab58c1894c70551ddbf7f1aa591d5e52a928cfb1055181d9ed6f339fd713abc5f4eae42c299d3411ead600cec4dd927e4b8b8493c0ab1ab67106c12918636b5d4dd0206de8f465b754390ea5c90a1cb3c47228f3421c8152fe9aef74599aca84c2082b2dee4475423e9543b89d0310720ed491f3c5a73ae688c285a4e37fed9fdffe1beb6a33ad94f37ddf48cb3f469d0f43d0df290cd7bac18e66479aa7e23319efa7345f41adc9e8a3c4bb595a0342ebed072b2358abb1d2844889fe37be04b52a072532b95d4378ee5a1ccec3ad", + "id": "10313496", + "live": false, + "mediaType": "VIDEO", + "presentation": "DEFAULT", + "quality": "HD", + "streaming": "HLS", + "subtitles": [], + "intervals": [], + "tokenType": "NONE", + "urn": "urn:rts:video:10313496" + } +} diff --git a/test/__mocks__/urn:rts:video:10313496-credits.json b/test/__mocks__/urn:rts:video:10313496-credits.json index f18f6d4..e50183a 100644 --- a/test/__mocks__/urn:rts:video:10313496-credits.json +++ b/test/__mocks__/urn:rts:video:10313496-credits.json @@ -1,814 +1,426 @@ { - "chapterUrn": "urn:rts:video:10313496", - "episode": { - "id": "10313468", - "title": "Les beaux parleurs", - "publishedDate": "2019-03-24T11:04:00+01:00", - "imageUrl": "https://www.rts.ch/2019/02/08/16/10/7392823.image/16x9" + "chapterUrn" : "urn:rts:video:10313496", + "episode" : { + "id" : "10313468", + "title" : "Les beaux parleurs", + "publishedDate" : "2019-03-24T11:04:00+01:00", + "imageUrl" : "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9", + "imageTitle" : "Les beaux parleurs - Y'a pas de fumée sans feu [RTS]" }, - "show": { - "id": "9931005", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:show:tv:9931005", - "title": "Les beaux parleurs (vidéo)", - "imageUrl": "https://www.rts.ch/2019/02/08/16/10/7392823.image/16x9", - "imageTitle": "Logo Les beaux parleurs [RTS]", - "topicList": [ - { - "id": "55665", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:55665", - "title": "Les beaux parleurs" - }, - { - "id": "16202", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:16202", - "title": "La 1ère" - }, + "show" : { + "id" : "9931005", + "vendor" : "RTS", + "transmission" : "TV", + "urn" : "urn:rts:show:tv:9931005", + "title" : "Les beaux parleurs", + "lead" : "Talk show présenté par Jonas Schneiter.", + "description" : "L'émission est un talk show, spectacle de paroles: trois chroniqueurs et un humoriste revisitent l'actualité de la semaine écoulée sur le ton d'une dispute intelligente et spirituelle. Un invité les rejoint en cours d’émission pour être à son tour, interpellé sur son actualité. Au terme de l’émission, les \"beaux parleurs\" distinguent des \"perles de la semaine\" attribuées à la déclaration la plus grotesque, la plus ridicule, la plus absurde pêchée sur les ondes radio, télé ou dans la presse écrite. Une émission de Jonas Schneiter.", + "imageUrl" : "https://www.rts.ch/2024/02/22/14/23/10721867.image/16x9", + "imageTitle" : "Les beaux parleurs. [RTS]", + "posterImageUrl" : "https://ws.srf.ch/asset/image/audio/e0322b37-5697-474d-93ac-19a4044a6a24/POSTER.jpg", + "posterImageIsFallbackUrl" : true, + "audioDescriptionAvailable" : false, + "subtitlesAvailable" : false, + "multiAudioLanguagesAvailable" : false, + "topicList" : [ { + "id" : "55665", + "vendor" : "RTS", + "transmission" : "TV", + "urn" : "urn:rts:topic:tv:55665", + "title" : "Les beaux parleurs" + }, { + "id" : "16202", + "vendor" : "RTS", + "transmission" : "TV", + "urn" : "urn:rts:topic:tv:16202", + "title" : "La 1ère" + } ], + "allowIndexing" : true + }, + "chapterList" : [ { + "id" : "10313496", + "mediaType" : "VIDEO", + "vendor" : "RTS", + "urn" : "urn:rts:video:10313496", + "title" : "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "description" : "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", + "imageUrl" : "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9", + "imageTitle" : "Les beaux parleurs - Y'a pas de fumée sans feu [RTS]", + "type" : "EPISODE", + "date" : "2019-03-24T11:04:00+01:00", + "duration" : 4827120, + "validFrom" : "2019-03-24T11:04:00+01:00", + "playableAbroad" : true, + "timeIntervalList": [ { - "id": "653", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:653", - "title": "Play" + "type": "OPENING_CREDITS", + "markIn": 0, + "markOut": 12000 }, { - "id": "622", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:622", - "title": "rts.ch" + "type": "CLOSING_CREDITS", + "markIn": 1836000, + "markOut": 1906000 } - ] - }, - "chapterList": [ - { - "id": "10313496", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313496", - "title": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", - "description": "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9", - "imageTitle": "Les beaux parleurs - Y'a pas de fumée sans feu [RTS]", - "type": "EPISODE", - "date": "2019-03-24T11:04:00+01:00", - "duration": 4827120, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "timeIntervalList": [ - { - "type": "OPENING_CREDITS", - "markIn": 0, - "markOut": 12000 + ], + "socialCountList" : [ { + "key" : "srgView", + "value" : 812 + }, { + "key" : "srgLike", + "value" : 0 + }, { + "key" : "fbShare", + "value" : 0 + }, { + "key" : "twitterShare", + "value" : 0 + }, { + "key" : "googleShare", + "value" : 0 + }, { + "key" : "whatsAppShare", + "value" : 0 + } ], + "displayable" : true, + "position" : 0, + "noEmbed" : false, + "analyticsData" : { + "ns_st_ep" : "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "ns_st_ty" : "Video", + "ns_st_ci" : "10313496", + "ns_st_el" : "4827120", + "ns_st_cl" : "4827120", + "ns_st_sl" : "4827120", + "srg_mgeobl" : "false", + "ns_st_tp" : "1", + "ns_st_cn" : "1", + "ns_st_ct" : "vc12", + "ns_st_pn" : "1", + "ns_st_cdm" : "eo", + "ns_st_cmt" : "ec" + }, + "analyticsMetadata" : { + "media_segment" : "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", + "media_type" : "Video", + "media_segment_id" : "10313496", + "media_episode_length" : "4827", + "media_segment_length" : "4827", + "media_number_of_segment_selected" : "1", + "media_number_of_segments_total" : "1", + "media_duration_category" : "long", + "media_is_geoblocked" : "false", + "media_is_web_only" : "true", + "media_production_source" : "produced.for.web", + "media_urn" : "urn:rts:video:10313496" + }, + "eventData" : "$9db05194d7854399$80484ccbcc3b0481db9c5ee344196397e72e218449a7cf769782062d650c6363ec5787f4fa538e7bcbc2f7ccfaf9f70f5fdc50bde3986541b04285c7125bc0a93731c18e6afea7b0154f874accaf319abb738541e8634ce09c91a499df2faf6d0281e66c6e3ab9f5c77f9c75cfff9297caab58c1894c70551ddbf7f1aa591d5e52a928cfb1055181d9ed6f339fd713abc5f4eae42c299d3411ead600cec4dd927e4b8b8493c0ab1ab67106c12918636b5d4dd0206de8f465b754390ea5c90a1cb3c47228f3421c8152fe9aef74599aca84c2082b2dee4475423e9543b89d0310720ed491f3c5a73ae688c285a4e37fed9fdffe1beb6a33ad94f37ddf48cb3f469d0f43d0df290cd7bac18e66479aa7e23319efa7345f41adc9e8a3c4bb595a0342ebed072b2358abb1d2844889fe37be04b52a072532b95d4378ee5a1ccec3ad", + "resourceList" : [ { + "url" : "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8", + "quality" : "HD", + "protocol" : "HLS", + "encoding" : "H264", + "mimeType" : "application/x-mpegURL", + "presentation" : "DEFAULT", + "streaming" : "HLS", + "dvr" : false, + "live" : false, + "mediaContainer" : "FMP4", + "audioCodec" : "AAC", + "videoCodec" : "H264", + "tokenType" : "NONE", + "audioTrackList" : [ { + "locale" : "fr", + "language" : "Français", + "source" : "HLS" + } ], + "analyticsData" : { + "srg_mqual" : "HD", + "srg_mpres" : "DEFAULT" }, - { - "type": "CLOSING_CREDITS", - "markIn": 1836000, - "markOut": 1906000 + "analyticsMetadata" : { + "media_streaming_quality" : "HD", + "media_special_format" : "DEFAULT", + "media_url" : "https://rts-vod-amd.akamaized.net/ww/10313496/264fac24-70a6-34bc-a37e-751493d10e20/master.m3u8" } - ], - "socialCountList": [ - { - "key": "srgView", - "value": 704 + } ], + "aspectRatio" : "16:9" + }, { + "id" : "10313478", + "mediaType" : "VIDEO", + "vendor" : "RTS", + "urn" : "urn:rts:video:10313478", + "title" : "La chronique de Benjamin Décosterd - Les élections vaudoises", + "imageUrl" : "https://www.rts.ch/2019/03/24/14/03/10313469.image/16x9", + "imageTitle" : "La chronique de Benjamin Décosterd - Les élections vaudoises [RTS]", + "type" : "CLIP", + "date" : "2019-03-24T14:03:03+01:00", + "duration" : 294720, + "validFrom" : "2019-03-24T11:04:00+01:00", + "playableAbroad" : true, + "displayable" : true, + "fullLengthUrn" : "urn:rts:video:10313496", + "position" : 1, + "noEmbed" : false, + "analyticsData" : { + "ns_st_ep" : "La chronique de Benjamin Décosterd - Les élections vaudoises", + "ns_st_ty" : "Video", + "ns_st_ci" : "10313478", + "ns_st_el" : "294720", + "ns_st_cl" : "294720", + "ns_st_sl" : "294720", + "srg_mgeobl" : "false", + "ns_st_tp" : "1", + "ns_st_cn" : "1", + "ns_st_ct" : "vc11", + "ns_st_pn" : "1", + "ns_st_cdm" : "eo", + "ns_st_cmt" : "ec" + }, + "analyticsMetadata" : { + "media_segment" : "La chronique de Benjamin Décosterd - Les élections vaudoises", + "media_type" : "Video", + "media_segment_id" : "10313478", + "media_episode_length" : "295", + "media_segment_length" : "295", + "media_number_of_segment_selected" : "1", + "media_number_of_segments_total" : "1", + "media_duration_category" : "short", + "media_is_geoblocked" : "false", + "media_is_web_only" : "true", + "media_production_source" : "produced.for.web", + "media_urn" : "urn:rts:video:10313478" + }, + "eventData" : "$1ca8de52767edc7c$b53972610b30bdea9d4359fc4a078387badc1f3d8426d8636ed83e5a91122627e958e4d483a567a26623211ca61da22316e61b18e967af9f0f1387153dc42f76dc023d7a09693ee942bd7ab35c5b8e39e4bc1b120264b4829887d57906cf629a2d9b52f9628f20f491bd8d2c3a089af78e0358223b383f4af1b98ee4c805956f59ce413194e7784f8bb76f30bbd1890bf35bccfc921b3e9548ce6d6b800ce201ab5aebc7cb30a15eb348d5fbed49d227fc7e9c56918d1ed20e865dedd396cc3c9d61ec96e2053c8363410706218f846aed42f0db7bee0265ad65a95bbac9c3b71bc92b7825db754d00276493337cc316d3bf638d6c79760731a158a4d17d0d54b64cae3c04ee433db2d93c0fce82a9da8c41a4f5970a7baf46cbfd5af903dc7049f1bc1890b4dff524b6dffef34fbfda", + "fullLengthMarkIn" : 105000, + "fullLengthMarkOut" : 399720, + "resourceList" : [ { + "url" : "https://rts-vod-amd.akamaized.net/ww/10313478/7c9449de-245a-3021-bfd8-104ec65dfb5d/master.m3u8", + "quality" : "HD", + "protocol" : "HLS", + "encoding" : "H264", + "mimeType" : "application/x-mpegURL", + "presentation" : "DEFAULT", + "streaming" : "HLS", + "dvr" : false, + "live" : false, + "mediaContainer" : "FMP4", + "audioCodec" : "AAC", + "videoCodec" : "H264", + "tokenType" : "NONE", + "audioTrackList" : [ { + "locale" : "fr", + "language" : "Français", + "source" : "HLS" + } ], + "analyticsData" : { + "srg_mqual" : "HD", + "srg_mpres" : "DEFAULT" }, - { - "key": "srgLike", - "value": 0 - }, - { - "key": "fbShare", - "value": 0 - }, - { - "key": "twitterShare", - "value": 0 - }, - { - "key": "googleShare", - "value": 0 - }, - { - "key": "whatsAppShare", - "value": 0 + "analyticsMetadata" : { + "media_streaming_quality" : "HD", + "media_special_format" : "DEFAULT", + "media_url" : "https://rts-vod-amd.akamaized.net/ww/10313478/7c9449de-245a-3021-bfd8-104ec65dfb5d/master.m3u8" } - ], - "displayable": true, - "position": 0, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", - "ns_st_ty": "Video", - "ns_st_ci": "10313496", - "ns_st_el": "4827120", - "ns_st_cl": "4827120", - "ns_st_sl": "4827120", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "1", - "ns_st_cdm": "eo", - "ns_st_cmt": "ec" - }, - "analyticsMetadata": { - "media_segment": "Les beaux parleurs - Y'a pas de fumée sans feu (vidéo)", - "media_type": "Video", - "media_segment_id": "10313496", - "media_episode_length": "4827", - "media_segment_length": "4827", - "media_number_of_segment_selected": "1", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "true", - "media_production_source": "produced.for.web", - "media_urn": "urn:rts:video:10313496" - }, - "eventData": "$3ada28b5cd418c36$e6e7ab4d94dfea293b487828ae193acc4c804f7c3d9f10ee70c83d283acb443f9ca016efbd6e2cc2d51073099d646d7f67290704426c431a9729058e7f2f3ab577026b3261b7ae17a5398cd09020c0e5a1e91249326b52906a6860a8076fe3584c22f64f5c0af8c6cccc9a675b5983b529d7c88bf982c1e548ce9e05acb25cbb2ba6972f5cfb90a3710b522134ffc2a330aab4a942334f9d074134135cbf4d2e207b9fb8769f6e6b3aaf1f821c424e85a36deba26a977b01081571b6d782f2839eb13658259d7f86283277f6b88cf69f8113e8faddd25c6e587ab0ccc04a27e6a19ab26d2e0ded67f266f72e3c5db415478d78507b7d1e1ca6c95602aaa4bdf6", - "resourceList": [ - { - "url": "https://rtsvodww-vh.akamaihd.net/i/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,1201k,2001k,3501k,6001k,.mp4.csmil/master.m3u8", - "quality": "HD", - "protocol": "HLS", - "encoding": "H264", - "mimeType": "application/x-mpegURL", - "presentation": "DEFAULT", - "streaming": "HLS", - "dvr": false, - "live": false, - "mediaContainer": "MP4", - "audioCodec": "MP3", - "videoCodec": "H264", - "tokenType": "NONE", - "analyticsData": { - "srg_mqual": "HD", - "srg_mpres": "DEFAULT" - }, - "analyticsMetadata": { - "media_streaming_quality": "HD", - "media_special_format": "DEFAULT", - "media_url": "https://rtsvodww-vh.akamaihd.net/i/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,1201k,2001k,3501k,6001k,.mp4.csmil/master.m3u8" - } + } ], + "aspectRatio" : "16:9" + }, { + "id" : "10313492", + "mediaType" : "VIDEO", + "vendor" : "RTS", + "urn" : "urn:rts:video:10313492", + "title" : "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "description" : "Le portrait de Sophie Swaton est brossé avec humour par Claude-Inga Barbey à travers l'un de ses personnages.", + "imageUrl" : "https://www.rts.ch/2019/03/24/14/03/10313491.image/16x9", + "imageTitle" : "Le portrait de Sophie Swaton par Claude-Inga Barbey [RTS]", + "type" : "CLIP", + "date" : "2019-03-24T14:03:10+01:00", + "duration" : 314480, + "validFrom" : "2019-03-24T11:04:00+01:00", + "playableAbroad" : true, + "displayable" : true, + "fullLengthUrn" : "urn:rts:video:10313496", + "position" : 2, + "noEmbed" : false, + "analyticsData" : { + "ns_st_ep" : "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "ns_st_ty" : "Video", + "ns_st_ci" : "10313492", + "ns_st_el" : "314480", + "ns_st_cl" : "314480", + "ns_st_sl" : "314480", + "srg_mgeobl" : "false", + "ns_st_tp" : "1", + "ns_st_cn" : "1", + "ns_st_ct" : "vc11", + "ns_st_pn" : "1", + "ns_st_cdm" : "eo", + "ns_st_cmt" : "ec" + }, + "analyticsMetadata" : { + "media_segment" : "Le portrait de Sophie Swaton par Claude-Inga Barbey", + "media_type" : "Video", + "media_segment_id" : "10313492", + "media_episode_length" : "314", + "media_segment_length" : "314", + "media_number_of_segment_selected" : "1", + "media_number_of_segments_total" : "1", + "media_duration_category" : "short", + "media_is_geoblocked" : "false", + "media_is_web_only" : "true", + "media_production_source" : "produced.for.web", + "media_urn" : "urn:rts:video:10313492" + }, + "eventData" : "$6eabc1a0debc4468$58f6fe4a463bdfaed3002421b89d621bfdf317941437ea4938085440bc69ad0bf903374a872acd6b43150231479dc804e8e2ab8ac8542ddee99cbee06683a2f262175c5e4464a0dfaaa6d9d0b2154ebcce3ccf5962b1fea46b274d551b88d568f9be511e91b78511726ad1043c49fed7c636630191c24a70ff8e78c122e717021cf8dc2fa018352e32a5aa5e7946cef535eef7f9b8edb5824bab1e595ae896948ab6b21366eb5cff04f4e41131279eb26efbf6a7b653400531a1248f6ff5d73527c24d25fab839373fc6bc74dce8fddc83ab23f9498a06c94aa86885c18b0c72d86f4b463d4146a3fa27a1c8136ab124546e0690c24a9a6a0d61b427cdf0a1704e30be95955dfb06e089a5caa3a80a2abfc5864d2b0b12a05c1d5481a4200ef0f15b2cef1996592112ac84656af6f3d6", + "fullLengthMarkIn" : 3336120, + "fullLengthMarkOut" : 3650600, + "resourceList" : [ { + "url" : "https://rts-vod-amd.akamaized.net/ww/10313492/372ad0c8-912c-3218-9bda-d9fff5d977f9/master.m3u8", + "quality" : "HD", + "protocol" : "HLS", + "encoding" : "H264", + "mimeType" : "application/x-mpegURL", + "presentation" : "DEFAULT", + "streaming" : "HLS", + "dvr" : false, + "live" : false, + "mediaContainer" : "FMP4", + "audioCodec" : "AAC", + "videoCodec" : "H264", + "tokenType" : "NONE", + "audioTrackList" : [ { + "locale" : "fr", + "language" : "Français", + "source" : "HLS" + } ], + "analyticsData" : { + "srg_mqual" : "HD", + "srg_mpres" : "DEFAULT" }, - { - "url": "https://rtsvodww-vh.akamaihd.net/i/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,.mp4.csmil/master.m3u8", - "quality": "SD", - "protocol": "HLS", - "encoding": "H264", - "mimeType": "application/x-mpegURL", - "presentation": "DEFAULT", - "streaming": "HLS", - "dvr": false, - "live": false, - "mediaContainer": "MP4", - "audioCodec": "MP3", - "videoCodec": "H264", - "tokenType": "NONE", - "analyticsData": { - "srg_mqual": "SD", - "srg_mpres": "DEFAULT" - }, - "analyticsMetadata": { - "media_streaming_quality": "SD", - "media_special_format": "DEFAULT", - "media_url": "https://rtsvodww-vh.akamaihd.net/i/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,.mp4.csmil/master.m3u8" - } - }, - { - "url": "http://rtsvodww-vh.akamaihd.net/z/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,1201k,2001k,3501k,6001k,.mp4.csmil/manifest.f4m", - "quality": "HD", - "protocol": "HDS", - "encoding": "H264", - "mimeType": "application/adobe-f4m", - "presentation": "DEFAULT", - "streaming": "HDS", - "dvr": false, - "live": false, - "mediaContainer": "MP4", - "audioCodec": "MP3", - "videoCodec": "H264", - "tokenType": "NONE", - "analyticsData": { - "srg_mqual": "HD", - "srg_mpres": "DEFAULT" - }, - "analyticsMetadata": { - "media_streaming_quality": "HD", - "media_special_format": "DEFAULT", - "media_url": "http://rtsvodww-vh.akamaihd.net/z/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,1201k,2001k,3501k,6001k,.mp4.csmil/manifest.f4m" - } - }, - { - "url": "http://rtsvodww-vh.akamaihd.net/z/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,.mp4.csmil/manifest.f4m", - "quality": "SD", - "protocol": "HDS", - "encoding": "H264", - "mimeType": "application/adobe-f4m", - "presentation": "DEFAULT", - "streaming": "HDS", - "dvr": false, - "live": false, - "mediaContainer": "MP4", - "audioCodec": "MP3", - "videoCodec": "H264", - "tokenType": "NONE", - "analyticsData": { - "srg_mqual": "SD", - "srg_mpres": "DEFAULT" - }, - "analyticsMetadata": { - "media_streaming_quality": "SD", - "media_special_format": "DEFAULT", - "media_url": "http://rtsvodww-vh.akamaihd.net/z/beapa/2019/beapa_20190324_full_03e3fef2-92e8-4728-b40b-5350564b84e7-,301k,101k,701k,.mp4.csmil/manifest.f4m" - } + "analyticsMetadata" : { + "media_streaming_quality" : "HD", + "media_special_format" : "DEFAULT", + "media_url" : "https://rts-vod-amd.akamaized.net/ww/10313492/372ad0c8-912c-3218-9bda-d9fff5d977f9/master.m3u8" } - ], - "segmentList": [ - { - "id": "10313478", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313478", - "title": "La chronique de Benjamin Décosterd - Les élections vaudoises", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313469.image/16x9", - "imageTitle": "La chronique de Benjamin Décosterd - Les élections vaudoises [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:03+01:00", - "duration": 294720, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 1, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "La chronique de Benjamin Décosterd - Les élections vaudoises", - "ns_st_ty": "Video", - "ns_st_ci": "10313478", - "ns_st_el": "4827120", - "ns_st_cl": "294720", - "ns_st_sl": "294720", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc11", - "ns_st_pn": "1", - "ns_st_cdm": "eo", - "ns_st_cmt": "ec" - }, - "analyticsMetadata": { - "media_segment": "La chronique de Benjamin Décosterd - Les élections vaudoises", - "media_type": "Video", - "media_segment_id": "10313478", - "media_episode_length": "4827", - "media_segment_length": "295", - "media_number_of_segment_selected": "1", - "media_number_of_segments_total": "10", - "media_duration_category": "short", - "media_is_geoblocked": "false", - "media_is_web_only": "true", - "media_production_source": "produced.for.web", - "media_urn": "urn:rts:video:10313478" - }, - "eventData": "$27235f9852f15b55$176b350311cc432bf62919501847723349b7dd6b98c8f7cd19ffd0883eca13dd2191e5d1697c8faa59831643d0f297aa3291ec394016b071fd0fcb9adc21ce47b47d37a5d3036eafa941ea7a0171e58ee50a9804ab2fab9968c6b21ebe3f7b556e5fe932c45623844af88dd61a5dd378132a7d7f22429f3b8475128b988c2fef670648259ea31671b5cf20f1d3332b6e3e3531cc496457db44b699673bb25344f4dd20e56e706747da7f1edad8422bca1ebc69bceaf5dc851e38f7ae159a23937ad071c64e74eeef037d650828580bf4c46819bdc93caa89287f38feee739586b02ed767556d2b233dcd97733449963240372b7b9ad03e8b2217a9d2d981c13e", - "markIn": 105000, - "markOut": 399720 - }, - { - "id": "10313480", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313480", - "title": "Dispute - Le cannabis fortement dosé augmente le taux de psychose", - "description": "Cʹest désormais prouvé scientifiquement, le cannabis fortement dosé augmente le taux de psychose dans la population. Faut-il faire marche arrière sur la tendance mondiale à la légalisation?", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313479.image/16x9", - "imageTitle": "Dispute - Le cannabis fortement dosé augmente le taux de psychose [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:04+01:00", - "duration": 755280, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 2, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Dispute - Le cannabis fortement dosé augmente le taux de psychose", - "ns_st_ty": "Video", - "ns_st_ci": "10313480", - "ns_st_el": "4827120", - "ns_st_cl": "755280", - "ns_st_sl": "755280", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "2", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Dispute - Le cannabis fortement dosé augmente le taux de psychose", - "media_type": "Video", - "media_segment_id": "10313480", - "media_episode_length": "4827", - "media_segment_length": "755", - "media_number_of_segment_selected": "2", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313480" - }, - "eventData": "$36d1652597326068$3a3ee21c4ab32ff459d44f01e4c09d7418db5728521da402278ed68f8ebc6410a61080cf616739efd7d3a1e55d13be2484a386d55c0bfe4142602beecaefa14932cca2da5f5a15e5052dcbbb828daafb315eebc3a0f67e9ab11bb9704344d287f302213b70f1feac39485d2534c849a94c291b790f0942d6d8a35765897ef9c8e198f84dda48dd9409028d75a6daa406efc1d67e4bfe509cd860f49eb357e4e1f5b6630a6500ec17a71beae805d40656f3e3eb6b0f42b65953c130d34e8cfa62b099861e363fcd318dc81482c0d8d96f04af288d1812228424e8312dfbcf076932f01686313130c02d83dfdee44b541ec2d1f695e823d45fd9ec6470350691b1", - "markIn": 407960, - "markOut": 1163240 - }, - { - "id": "10313482", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313482", - "title": "Le billet de Michel Audétat - Michael Jackson", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313481.image/16x9", - "imageTitle": "Le billet de Michel Audétat - Michael Jackson [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:05+01:00", - "duration": 136120, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 3, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Le billet de Michel Audétat - Michael Jackson", - "ns_st_ty": "Video", - "ns_st_ci": "10313482", - "ns_st_el": "4827120", - "ns_st_cl": "136120", - "ns_st_sl": "136120", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc11", - "ns_st_pn": "3", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Le billet de Michel Audétat - Michael Jackson", - "media_type": "Video", - "media_segment_id": "10313482", - "media_episode_length": "4827", - "media_segment_length": "136", - "media_number_of_segment_selected": "3", - "media_number_of_segments_total": "10", - "media_duration_category": "short", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313482" - }, - "eventData": "$ddb204580797b0f8$23114aac64b2d2262ead98e3b0cfc3bcdaac5dbe00dc3212ab43e0734f9c3fbfbd8516e378732d2de078449a0a2cc1f2313b002d7b6968807990557bf8e2e73d9218ce17d46406268aec8dad016fe745050c777175d140abf8720cfc68d35132ed47970f56497c396ab0117aad3f163c634e0cb1a6f37ca60843da3b44bbfcb30e160e000155c8f138b610eccb81f3a924e5a5da8023c55eeb23e9724282e688591fdeeb42d53c7ad9a8c40759f42f570269524dcdbb6c1171f94c6f7236a2464d4a400633174417236b30912801f49599ccb19b33a0a0704014c102dd9db98bde4400329e60fdca4c1a2c23b89afb0e167319dac7e84a3e3cadf5888f558905", - "markIn": 1186920, - "markOut": 1323040 - }, - { - "id": "10313484", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313484", - "title": "Dispute - L'argent stresse plus la population Suisse que la santé ou l'emploi", - "description": "Selon une enquête publiée cette semaine, l'argent stresse davantage les Suisses que la santé ou l'emploi.", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313483.image/16x9", - "imageTitle": "Dispute - L'argent stresse plus la population Suisse que la santé ou l'emploi [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:06+01:00", - "duration": 668640, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 4, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Dispute - L'argent stresse plus la population Suisse que la santé ou l'emploi", - "ns_st_ty": "Video", - "ns_st_ci": "10313484", - "ns_st_el": "4827120", - "ns_st_cl": "668640", - "ns_st_sl": "668640", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "4", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Dispute - L'argent stresse plus la population Suisse que la santé ou l'emploi", - "media_type": "Video", - "media_segment_id": "10313484", - "media_episode_length": "4827", - "media_segment_length": "669", - "media_number_of_segment_selected": "4", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313484" - }, - "eventData": "$482265f6c75b8068$06dc6ec1f2df82d4b08280ac7b9ceb8ee01ca830f5838c8555358ebd7c93ce5c43c3747326630b886bd7c96aa487989c096a466235bac4bd9e9d94c858090fad54b51a746f6af832b548180813d90300009ff34efa476cd4ef141c39363632424af9a4e6823575bd8ead92ccadc7dd9e33e9e5ada8aae97adeec461f364c727f9076a751bdb9673366b3ff70ed665f814e7c8b340bf15630c769d9d77d9784404db08efdab938b9160959719c3e55e5578b8dab95d37069a377ff9a72153c2f235ff988d6873380578127f69abad65116ec2de481039e2446f1cb58b0915d1bb920a93463c6d8ed3186868ea3972ba2ee661003e3347dcf9dd4de5f37738b61a", - "markIn": 1332160, - "markOut": 2000800 - }, - { - "id": "10313486", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313486", - "title": "Dispute - Le refroidissement entre la Russie et les Etats-Unis menace-t-il les droit de l'homme?", - "description": "La session du Conseil des droits de l’homme a eu lieu cette semaine à Genève. La Russie et les Etats-Unis s’y sont affrontés. Ce nouveau refroidissement est-il dangereux pour la situation des droits de l’homme dans le monde?", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313485.image/16x9", - "imageTitle": "Dispute - Le refroidissement entre la Russie et les Etats-Unis menace-t-il les droit de l'homme? [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:07+01:00", - "duration": 747400, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 5, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Dispute - Le refroidissement entre la Russie et les Etats-Unis menace-t-il les droit de l'homme?", - "ns_st_ty": "Video", - "ns_st_ci": "10313486", - "ns_st_el": "4827120", - "ns_st_cl": "747400", - "ns_st_sl": "747400", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "5", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Dispute - Le refroidissement entre la Russie et les Etats-Unis menace-t-il les droit de l'homme?", - "media_type": "Video", - "media_segment_id": "10313486", - "media_episode_length": "4827", - "media_segment_length": "747", - "media_number_of_segment_selected": "5", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313486" - }, - "eventData": "$3f12c531f60d334f$5f247d4dc5f4a8fd62ec8b879f3fe606ef4724e648c4dedb88a474963da4dc2d556d35c154f80f778f11cd2ddb1949b8b442b3f9d5dd419cedfdb2ecb7dcee0c8df4853be27f44f3b6c61372d4bf010df320ceaf736689a3f5a45d2752f12590a7e625f938985c4daf1f685d3d08e330b420e2d2d752077e26ee699c2211c8b20c78f2e949b880efcc042812dfd85b902e26e20bf58378753d7e34a3a026a17c649202abbb541786e7b648bfe4803a2ec6ce304ab5d287fcf0fdbefeb5822371267b8bc1f82bd4a9af7aa507c08252d85277dc3538981f2bc1dadcf0ae6d97ef25c915b571e76a9595923ddad2792bf656378b9d561ca144c5338946a8420403", - "markIn": 2241120, - "markOut": 2988520 - }, - { - "id": "10313488", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313488", - "title": "Le billet de Coline de Senarclens - Le génocide Yezidis", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313487.image/16x9", - "imageTitle": "Le billet de Coline de Senarclens - Le génocide Yezidis [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:08+01:00", - "duration": 177200, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 6, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Le billet de Coline de Senarclens - Le génocide Yezidis", - "ns_st_ty": "Video", - "ns_st_ci": "10313488", - "ns_st_el": "4827120", - "ns_st_cl": "177200", - "ns_st_sl": "177200", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc11", - "ns_st_pn": "6", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Le billet de Coline de Senarclens - Le génocide Yezidis", - "media_type": "Video", - "media_segment_id": "10313488", - "media_episode_length": "4827", - "media_segment_length": "177", - "media_number_of_segment_selected": "6", - "media_number_of_segments_total": "10", - "media_duration_category": "short", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313488" - }, - "eventData": "$76cc956378c65e1a$03db02fcb403661638379bb8d1a9ca0177ba50edf530a54ac7dd57c4ca59e844b0f61893930ad63bf87a304efbf7b52baee71636be8afcf890f55515110fe295d6b1e59a3ff733a8746561a0f89746e0d596b0002741f36b516950f6aa70992039cec860eb2b63807a5b21b9f28eb02145fd88fde4be1a881c8ccb7b321742c3363d3611b593be76f19bdbf7e3f1f26dbc8469d6cb0a8d0f94afc45b433f262616cf3a5db4087f897bc79b5f64432770780a95c24ede11abbe47bfa0c3fbf3852b11b4588e8dd9922de0668ec14e6288edb4362d65d850d116e2accf3b7a649070b0dcff6b6ed65557f8c7050a9957d24a27a604f1d578b3ea6970f9f5189fb8", - "markIn": 3014680, - "markOut": 3191880 - }, - { - "id": "10313490", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313490", - "title": "Les perles des beaux parleurs", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313489.image/16x9", - "imageTitle": "Les perles des beaux parleurs [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:09+01:00", - "duration": 100400, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 7, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Les perles des beaux parleurs", - "ns_st_ty": "Video", - "ns_st_ci": "10313490", - "ns_st_el": "4827120", - "ns_st_cl": "100400", - "ns_st_sl": "100400", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc11", - "ns_st_pn": "7", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Les perles des beaux parleurs", - "media_type": "Video", - "media_segment_id": "10313490", - "media_episode_length": "4827", - "media_segment_length": "100", - "media_number_of_segment_selected": "7", - "media_number_of_segments_total": "10", - "media_duration_category": "short", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313490" - }, - "eventData": "$4d14bfc85e2125d5$6a7598d35a41cd3a43f29478b4a2656dcb5d57c0284498a4625bfe9a4f2f65753b10971dcb698a2c8c85ff960c4f187f1b5b7fb12cd3f1cbdf9260b23ee67c76b5b83d11bf0d18b27d26e2a98bf6b14911f740231fe033b3ffd83fc8b404aec5f05495ecf4fbd4dbc3889427c92bb2555a149c70e91064d0c0f408ee2a3a1665945baab81f32bb63f9358879de2df6cd69dbffb0dc885790f43bfe4727a8ab5eb3aa5069b66c55c8c4144184bc138789c91998900ebc831af473c3afdf493559948b96f167575bc9576ff443a15078bec0501a5efef1dd1c41a1c6d0c99d49a78c4a5f56056289b22cd589d99ea86e3756867812f911ca9ca3db966b9d643ce6", - "markIn": 3193560, - "markOut": 3293960 - }, - { - "id": "10313492", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313492", - "title": "Le portrait de Sophie Swaton par Claude-Inga Barbey", - "description": "Le portrait de Sophie Swaton est brossé avec humour par Claude-Inga Barbey à travers l'un de ses personnages.", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313491.image/16x9", - "imageTitle": "Le portrait de Sophie Swaton par Claude-Inga Barbey [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:10+01:00", - "duration": 314480, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 8, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Le portrait de Sophie Swaton par Claude-Inga Barbey", - "ns_st_ty": "Video", - "ns_st_ci": "10313492", - "ns_st_el": "4827120", - "ns_st_cl": "314480", - "ns_st_sl": "314480", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc11", - "ns_st_pn": "8", - "ns_st_cdm": "eo", - "ns_st_cmt": "ec" - }, - "analyticsMetadata": { - "media_segment": "Le portrait de Sophie Swaton par Claude-Inga Barbey", - "media_type": "Video", - "media_segment_id": "10313492", - "media_episode_length": "4827", - "media_segment_length": "314", - "media_number_of_segment_selected": "8", - "media_number_of_segments_total": "10", - "media_duration_category": "short", - "media_is_geoblocked": "false", - "media_is_web_only": "true", - "media_production_source": "produced.for.web", - "media_urn": "urn:rts:video:10313492" - }, - "eventData": "$99bec3f277c483c2$b2c6769e1d83860ddd000affb3465f346106b84b931920747f8e785f246c113a9cb46d1c0818556c1bcea4edf73988e6d94943c24e118963e3af899360f4b5a2745e1285f2ff8382d7afefd5adaddf7466f1d7774e49b20dbf8df3c427bfe3ca54164192ae857fad35a03d76ffaf9645de3f61aed3a28911d2f651e9d89dc7ecadaaa52a7867282cdba2d76620989121149b1180b33f35c5038d4922e127e95a2299fa15b222a19eb85b499e3bc4b0b183303ebd57111f89b8fed80f2b18e4cf1f612b7e7550c2506db0e9234b0c0729e3589e96b7f99451c68d7dd483d59729255202f11acc2a494556825678c0e97afea6ff7bec027bdcb9f5aaa6dffb5e55", - "markIn": 3336120, - "markOut": 3650600 - }, - { - "id": "10313494", - "mediaType": "VIDEO", - "vendor": "RTS", - "urn": "urn:rts:video:10313494", - "title": "L'invitée - Sophie Swaton, philosophe et économiste", - "description": "Sophie Swaton est philosophe, économiste et professeure à l'Institut de géographie et durabilité de l'Université de Lausanne. Elle a créé la Fondation Zoein et fait partie des figures qui ont le vent en poupe depuis le début de ces marches pour le climat.", - "imageUrl": "https://www.rts.ch/2019/03/24/14/03/10313493.image/16x9", - "imageTitle": "L'invitée - Sophie Swaton, philosophe et économiste [RTS]", - "type": "CLIP", - "date": "2019-03-24T14:03:11+01:00", - "duration": 1157040, - "validFrom": "2019-03-24T11:04:00+01:00", - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 9, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "L'invitée - Sophie Swaton, philosophe et économiste", - "ns_st_ty": "Video", - "ns_st_ci": "10313494", - "ns_st_el": "4827120", - "ns_st_cl": "1157040", - "ns_st_sl": "1157040", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "9", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "L'invitée - Sophie Swaton, philosophe et économiste", - "media_type": "Video", - "media_segment_id": "10313494", - "media_episode_length": "4827", - "media_segment_length": "1157", - "media_number_of_segment_selected": "9", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:video:10313494" - }, - "eventData": "$1195add5816a0f44$1a84af10e3e1df4d202c35b5fabd039a4acf6541c674aced07f29e9287fbebea4d7012a3d52801806f08a76ade2569a210ddc5e41c8c612b52c27c7f93969b670e2f41ef3be90e3173a8575139def35cb75dd5c5e2971b28fc9f901a31fd54eb70c693f8152822c9f1057407d7c521a138ad9923d67b8462706635269398ced94fbf86102c4074ab8a9fa5aa7c63767e7a0e836623a0f31b9ccfc7a750badc5470fe95ef7790c8642da4868b6dbfa22a3c872fca5c0bb0cf7da43dd3782c4fc101e109f1ac04acfb6c0f9eac115ee94da068f16ad45b7de1760dcf3c923466db8700e108c2a70c67046608a6677bd5872ab64cc5a07223828da9cc567fe972c2", - "markIn": 3650600, - "markOut": 4807640 - }, - { - "id": "10277526", - "mediaType": "AUDIO", - "vendor": "RTS", - "urn": "urn:rts:audio:10277526", - "title": "Y'a pas de fumée sans feu (audio)", - "description": "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", - "imageUrl": "https://www.rts.ch/2019/03/24/16/10/10313604.image/16x9", - "imageTitle": "Les beaux parleurs. [Julien Audemars/Philippe Christin - RTS]", - "imageCopyright": "Julien Audemars/Philippe Christin - RTS", - "type": "CLIP", - "date": "2019-03-24T11:03:50+01:00", - "duration": 5170000, - "playableAbroad": true, - "displayable": true, - "fullLengthUrn": "urn:rts:video:10313496", - "position": 10, - "noEmbed": false, - "analyticsData": { - "ns_st_ep": "Y'a pas de fumée sans feu (audio)", - "ns_st_ty": "Audio", - "ns_st_ci": "10277526", - "ns_st_el": "4827120", - "ns_st_cl": "5170000", - "ns_st_sl": "5170000", - "srg_mgeobl": "false", - "ns_st_tp": "10", - "ns_st_cn": "1", - "ns_st_ct": "vc12", - "ns_st_pn": "10", - "ns_st_cdm": "to", - "ns_st_cmt": "fc" - }, - "analyticsMetadata": { - "media_segment": "Y'a pas de fumée sans feu (audio)", - "media_type": "Audio", - "media_segment_id": "10277526", - "media_episode_length": "4827", - "media_segment_length": "5170", - "media_number_of_segment_selected": "10", - "media_number_of_segments_total": "10", - "media_duration_category": "long", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:audio:10277526" - }, - "eventData": "$87c2a7787d1b4287$d2e804db3722995385e8d0069ac5d7353de8b2791ef6a2edadd447aa92e5c00a0c708c9cc6dbb0325e5725e2695ff478e284039b10c6793cc733d98681536a1f984871263d3d06499440babfb8b004d292cfc4519bb780bb13b08164bc7288fc97a1fa0d3cb046f6e9ef7f51b7d4526970237680b4ed0047108c408d6de5976b6f9868b003423fc655ed327d5eb430f35f07e438f4ff50a1ef7eb95fdcd5d5189f592a9b56506db80e65ac1fd3e0215714c9745af3fd8afcd305454e2e9c0edbb4d38b56960452b71d15e37ade3b7a73871547b89125f48aff6b071a262fa280c7347371b7758ae1ccf969f6cd611dca6652c4aa36eee22112db949dd5f6b85c", - "markIn": 0, - "markOut": 0 + } ], + "aspectRatio" : "16:9" + }, { + "id" : "10277526", + "mediaType" : "AUDIO", + "vendor" : "RTS", + "urn" : "urn:rts:audio:10277526", + "title" : "Les beaux parleurs - Y'a pas de fumée sans feu (audio)", + "description" : "Jonas Schneiter est entouré pour cette émission de Coline de Senarclens, Micheline Calmy-Rey, Michel Audétat, et de l'humoriste Benjamin Décosterd. L'équipe débat sur la tendance mondiale à la légalisation du cannabis, parle du rapport des Suisses à l'argent et fait le point sur la dernière session du Conseil des droits de l'homme à Genève. En deuxième partie d'émission, Claude-Inga Barbey nous présente à sa manière la philosophe et économiste, Sophie Swaton.", + "imageUrl" : "https://www.rts.ch/2019/03/24/16/10/10313604.image/16x9", + "imageTitle" : "Les beaux parleurs. [Julien Audemars/Philippe Christin - RTS]", + "imageCopyright" : "Julien Audemars/Philippe Christin - RTS", + "type" : "CLIP", + "date" : "2019-03-24T11:03:50+01:00", + "duration" : 5170000, + "podcastHdUrl" : "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3", + "playableAbroad" : true, + "displayable" : true, + "fullLengthUrn" : "urn:rts:video:10313496", + "position" : 3, + "noEmbed" : false, + "analyticsMetadata" : { + "media_segment" : "Les beaux parleurs - Y'a pas de fumée sans feu (audio)", + "media_type" : "Audio", + "media_segment_id" : "10277526", + "media_episode_length" : "5170", + "media_segment_length" : "5170", + "media_number_of_segment_selected" : "1", + "media_number_of_segments_total" : "1", + "media_duration_category" : "long", + "media_is_geoblocked" : "false", + "media_is_web_only" : "false", + "media_production_source" : "produced.for.broadcasting", + "media_urn" : "urn:rts:audio:10277526" + }, + "eventData" : "$8448618a46137271$2345a49d01fecfd8e365920836847642fdbb344395c09cb03ba124bc565a7db127fa2590dcf518fa2c5005c6fe8f8dc080e5089ddecf442fb6861ba4d6c5c5c0576f7e800badd46fff89abadebbc5a20c602b00e5030b8e75275c67a8dfa3babce94b173aba9b8cbd93764e08b2a3fcf70a29f4942c8021518752c4773b148a87f60c17750a75d775e5769d26986bdad1e3dee33a2c30c0969a0250f18e84d818052b80e63bea28d285b35ffe5fafc402d67f61da8c1e666c5e82451de3b09c244f1fdd0fb30d985e1c6e78dc696ee959d866f618e965d76328320fd1ff9dd57b08941fc4545b9598107de3d36ee5fcc1e1e848a433579befffc9e8aba70187b12c8bc481dadd046b54a8614b0e1cf6f9408aa5a19c1941f0e65b10e14faeb4dc96f7d1b120420ed4d515523cf9c5d1c", + "fullLengthMarkIn" : 0, + "fullLengthMarkOut" : 0, + "resourceList" : [ { + "url" : "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3", + "quality" : "HQ", + "protocol" : "HTTPS", + "encoding" : "MP3", + "mimeType" : "audio/mpeg", + "presentation" : "DEFAULT", + "streaming" : "PROGRESSIVE", + "dvr" : false, + "live" : false, + "mediaContainer" : "NONE", + "audioCodec" : "MP3", + "videoCodec" : "NONE", + "tokenType" : "NONE", + "analyticsMetadata" : { + "media_streaming_quality" : "HQ", + "media_special_format" : "DEFAULT", + "media_url" : "https://rts-aod-dd.akamaized.net/ww/10277526/dba37188-f708-326d-803a-c2cfe229bb82.mp3" } - ] - } - ], - "topicList": [ - { - "id": "55665", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:55665", - "title": "Les beaux parleurs" - }, - { - "id": "16202", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:16202", - "title": "La 1ère" - }, - { - "id": "653", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:653", - "title": "Play" - }, - { - "id": "622", - "vendor": "RTS", - "transmission": "TV", - "urn": "urn:rts:topic:tv:622", - "title": "rts.ch" - } - ], - "analyticsData": { - "srg_pr_id": "10313468", - "srg_plid": "9931005", - "ns_st_pl": "Les beaux parleurs (vidéo)", - "ns_st_pr": "Les beaux parleurs (vidéo) du 24.03.2019", - "ns_st_dt": "2019-03-24", - "ns_st_ddt": "2019-03-24", - "ns_st_tep": "500087771", - "ns_st_li": "0", - "ns_st_stc": "*null", - "ns_st_en": "10313468", - "ns_st_ce": "1", - "ns_st_cdm": "eo", - "ns_st_cmt": "ec", - "srg_unit": "RTS", - "srg_c1": "full", - "srg_c2": "video_la-1ere_les-beaux-parleurs", - "srg_c3": "RTS.ch", - "srg_tv_id": "500087771" + } ] + } ], + "topicList" : [ { + "id" : "55665", + "vendor" : "RTS", + "transmission" : "TV", + "urn" : "urn:rts:topic:tv:55665", + "title" : "Les beaux parleurs" + }, { + "id" : "16202", + "vendor" : "RTS", + "transmission" : "TV", + "urn" : "urn:rts:topic:tv:16202", + "title" : "La 1ère" + } ], + "analyticsData" : { + "srg_pr_id" : "10313468", + "srg_plid" : "9931005", + "ns_st_pl" : "Les beaux parleurs", + "ns_st_pr" : "Les beaux parleurs du 24.03.2019", + "ns_st_dt" : "2019-03-24", + "ns_st_ddt" : "2019-03-24", + "ns_st_tdt" : "*null", + "ns_st_tm" : "*null", + "ns_st_tep" : "500087771", + "ns_st_li" : "0", + "ns_st_stc" : "0867", + "ns_st_st" : "RTS Online", + "ns_st_tpr" : "9931005", + "ns_st_en" : "*null", + "ns_st_ge" : "*null", + "ns_st_ia" : "*null", + "ns_st_ce" : "1", + "ns_st_cdm" : "eo", + "ns_st_cmt" : "ec", + "srg_unit" : "RTS", + "srg_c1" : "full", + "srg_c2" : "video_la-1ere_les-beaux-parleurs", + "srg_c3" : "RTS.ch", + "srg_tv_id" : "500087771", + "srg_aod_prid" : "10313468" }, - "analyticsMetadata": { - "media_episode_id": "10313468", - "media_show_id": "9931005", - "media_show": "Les beaux parleurs (vidéo)", - "media_episode": "Les beaux parleurs (vidéo) du 24.03.2019", - "media_is_livestream": "false", - "media_full_length": "full", - "media_enterprise_units": "RTS", - "media_joker1": "full", - "media_joker2": "video_la-1ere_les-beaux-parleurs", - "media_joker3": "RTS.ch", - "media_is_web_only": "true", - "media_production_source": "produced.for.web", - "media_tv_id": "500087771", - "media_thumbnail": "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9/scale/width/344", - "media_publication_date": "2019-03-24", - "media_publication_time": "11:04:00", - "media_publication_datetime": "2019-03-24T11:04:00+01:00", - "media_content_group": "Les beaux parleurs,La 1ère,Play,rts.ch", - "media_since_publication_d": "12", - "media_since_publication_h": "294" + "analyticsMetadata" : { + "media_episode_id" : "10313468", + "media_show_id" : "9931005", + "media_show" : "Les beaux parleurs", + "media_episode" : "Les beaux parleurs du 24.03.2019", + "media_is_livestream" : "false", + "media_full_length" : "full", + "media_enterprise_units" : "RTS", + "media_joker1" : "full", + "media_joker2" : "video_la-1ere_les-beaux-parleurs", + "media_joker3" : "RTS.ch", + "media_is_web_only" : "true", + "media_production_source" : "produced.for.web", + "media_tv_id" : "500087771", + "media_thumbnail" : "https://www.rts.ch/2019/03/24/14/03/10313495.image/16x9/scale/width/344", + "media_publication_date" : "2019-03-24", + "media_publication_time" : "11:04:00", + "media_publication_datetime" : "2019-03-24T11:04:00+01:00", + "media_content_group" : "Les beaux parleurs,La 1ère", + "media_since_publication_d" : "1796", + "media_since_publication_h" : "43109" } } diff --git a/test/middleware/srgssr.spec.js b/test/middleware/srgssr.spec.js index 94e88c3..bc50b46 100644 --- a/test/middleware/srgssr.spec.js +++ b/test/middleware/srgssr.spec.js @@ -4,6 +4,7 @@ import Image from '../../src/utils/Image.js'; import MediaComposition from '../../src/dataProvider/model/MediaComposition.js'; import urnCredits from '../__mocks__/urn:rts:video:10313496-credits.json'; import urnRtsAudio from '../__mocks__/urn:rts:audio:3262320.json'; +import srcMediaObj from '../__mocks__/srcMediaObj.json'; import Pillarbox from '../../src/pillarbox.js'; import AkamaiTokenService from '../../src/utils/AkamaiTokenService.js'; @@ -305,7 +306,7 @@ describe('SrgSsr', () => { it('should return undefined if the block reason is undefined', async () => { const spyOnLocalize = jest.spyOn(player, 'localize'); - expect(SrgSsr.blockingReason(player, undefined, {})).toBeUndefined(); + expect(SrgSsr.blockingReason(player, { mediaData: {}})).toBeUndefined(); expect(spyOnLocalize).not.toHaveBeenCalled(); }); @@ -314,12 +315,12 @@ describe('SrgSsr', () => { const spyOnPlayerError = jest.spyOn(player, 'error'); const spyOnError = jest.spyOn(SrgSsr, 'error'); - expect(SrgSsr.blockingReason(player, 'STARTDATE', {})).toBe(true); + expect(SrgSsr.blockingReason(player, { mediaData: { blockReason: 'STARTDATE' }})).toBe(true); expect(spyOnLocalize).toHaveBeenCalled(); expect(spyOnError).toHaveBeenCalledWith(player, expect.any(Object)); expect(spyOnPlayerError.mock.calls[1]).toEqual( expect.arrayContaining([ - expect.objectContaining({ metadata: { errorType: 'STARTDATE', src: {}}}) + expect.objectContaining({ metadata: { errorType: 'STARTDATE', src: expect.any(Object) }}) ]) ); }); @@ -473,6 +474,31 @@ describe('SrgSsr', () => { }); }); + /** + ***************************************************************************** + * dataProvider ************************************************************** + ***************************************************************************** + */ + describe('dataProvider', () => { + it('should return the dataProvider if the property is not undefined', () => { + player.options().srgOptions = { + dataProvider: Function + }; + + const dataProvider = SrgSsr.dataProvider(player); + + expect(dataProvider).toBe(Function); + + player.options().srgOptions = {}; + }); + + it('should instantiate the dataProvider if it is undefined', () => { + SrgSsr.dataProvider(player); + + expect(DataProvider).toHaveBeenCalledTimes(1); + }); + }); + /** ***************************************************************************** * dataProviderError ********************************************************* @@ -675,6 +701,18 @@ describe('SrgSsr', () => { }); }); + /** + ***************************************************************************** + * getSrcMediaObj ************************************************************ + ***************************************************************************** + */ + describe('getSrcMediaObj', () => { + it('should do something', async () => { + const result = await SrgSsr.getSrcMediaObj(player, { src: 'urn:fake' }); + + expect(result).toEqual(expect.any(Object)); + }); + }); /** ***************************************************************************** * error ************************************************************* @@ -728,6 +766,34 @@ describe('SrgSsr', () => { }); }); + /** + ***************************************************************************** + * srgAnalytics ************************************************************** + ***************************************************************************** + */ + describe('srgAnalytics', () => { + it('should not initialize the srgAnalytics', () => { + player.options().trackers.srgAnalytics = false; + + const spyOnOptions = jest.spyOn(player, 'options'); + + SrgSsr.srgAnalytics(player); + + expect(player.options().trackers.srgAnalytics).toBe(false); + expect(spyOnOptions).not.toHaveBeenLastCalledWith(expect.objectContaining({ trackers: { srgAnalytics: expect.any(Object) }})); + }); + + it('should initialize the srgAnalytics', () => { + player.options().trackers.srgAnalytics = undefined; + + const spyOnOptions = jest.spyOn(player, 'options'); + + SrgSsr.srgAnalytics(player); + + expect(spyOnOptions).toHaveBeenLastCalledWith(expect.objectContaining({ trackers: { srgAnalytics: expect.any(Object) }})); + }); + }); + /** ***************************************************************************** * updatePoster ************************************************************** @@ -735,16 +801,17 @@ describe('SrgSsr', () => { */ describe('updatePoster', () => { it('should use the default Image class', async () => { - const mockDataProvider = new DataProvider(); - const { mediaComposition } = - await mockDataProvider.getMediaCompositionByUrn('urn:fake'); - const imageUrl = mediaComposition.getMainChapterImageUrl(); + const imageUrl = 'https://image.to.scale.ch/chapter.jpg'; const imageUrlResult = `https://mock-scale.ch/${imageUrl}`; const spyOnScale = jest.spyOn(Image, 'scale'); const spyOnPoster = jest.spyOn(player, 'poster'); - SrgSsr.updatePoster(player, mediaComposition); + SrgSsr.updatePoster(player, { + mediaData: { + chapterImageUrl: imageUrl + } + }); // Image expect(spyOnScale).toHaveBeenCalledWith({ url: imageUrl }); @@ -756,16 +823,17 @@ describe('SrgSsr', () => { }); it('should update the player\'s poster', async () => { - const mockDataProvider = new DataProvider(); - const { mediaComposition } = - await mockDataProvider.getMediaCompositionByUrn('urn:fake'); - const imageUrl = mediaComposition.getMainChapterImageUrl(); + const imageUrl = 'https://image.to.scale.ch/chapter.jpg'; const imageUrlResult = `https://mock-scale.ch/${imageUrl}`; const spyOnScale = jest.spyOn(Image, 'scale'); const spyOnPoster = jest.spyOn(player, 'poster'); - SrgSsr.updatePoster(player, mediaComposition, Image); + SrgSsr.updatePoster(player, { + mediaData: { + chapterImageUrl: imageUrl + } + }, Image); // Image expect(spyOnScale).toHaveBeenCalledWith({ url: imageUrl }); @@ -783,19 +851,38 @@ describe('SrgSsr', () => { ***************************************************************************** */ describe('updateTitleBar', () => { - it('should update the player\'s title bar', async () => { - const mockDataProvider = new DataProvider(); - const { mediaComposition } = - await mockDataProvider.getMediaCompositionByUrn('urn:fake'); + it('should do nothing if titleBar is undefined', async () => { + const srcObj = { + mediaData: { + vendor: 'BU', + title: 'Media Title' + } + }; + const cacheTitleBar = player.titleBar; - const spyOnUpate = jest.spyOn(player.titleBar, 'update'); + delete player.titleBar; + + SrgSsr.updateTitleBar(player, srcObj); + + expect(player).not.toHaveProperty('titleBar'); - SrgSsr.updateTitleBar(player, mediaComposition); + player.titleBar = cacheTitleBar; + }); + it('should update the player\'s title bar', async () => { + const srcObj = { + mediaData: { + vendor: 'BU', + title: 'Media Title' + } + }; const result = { - title: mediaComposition.getMainChapter().vendor, - description: mediaComposition.getMainChapter().title, + title: srcObj.mediaData.vendor, + description: srcObj.mediaData.title }; + const spyOnUpate = jest.spyOn(player.titleBar, 'update'); + + SrgSsr.updateTitleBar(player, srcObj); expect(spyOnUpate).toHaveBeenCalledWith(result); expect(spyOnUpate.mock.results[0].value).toMatchObject(result); @@ -859,69 +946,32 @@ describe('SrgSsr', () => { }); describe('setSource', () => { - it('Should use the default Image class', async () => { - const spyOnComposeAkamaiResources = jest.spyOn( + it('Should call handle set source', async () => { + const spyOnHandleSetSource = jest.spyOn( SrgSsr, - 'composeAkamaiResources' + 'handleSetSource' ); - const spyOnComposeKeySystemsResources = jest.spyOn( - SrgSsr, - 'composeKeySystemsResources' - ); - const spyOnGetMediaComposition = jest.spyOn( - SrgSsr, - 'getMediaComposition' - ); - const spyOnGetMediaData = jest.spyOn(SrgSsr, 'getMediaData'); - const spyOnComposeSrcMediaData = jest.spyOn( + + jest.spyOn( SrgSsr, - 'composeSrcMediaData' - ); - const spyOnSrgAnalytics = jest.spyOn(SrgSsr, 'srgAnalytics'); - const spyOnUpdateTitleBar = jest.spyOn(SrgSsr, 'updateTitleBar'); - const spyOnUpdatePoster = jest.spyOn(SrgSsr, 'updatePoster'); + 'getSrcMediaObj' + ).mockResolvedValueOnce(srcMediaObj); const middleware = SrgSsr.middleware(player); + const srcObj = { src: 'urn:fake' }; + const next = async (_err, _srcObj) => { }; - await middleware.setSource({ src: 'urn:fake' }, async (err, srcObj) => { - expect(err).toBeNull(); - expect(srcObj).toEqual(expect.any(Object)); - }); + await middleware.setSource({ src: 'urn:fake' }, next); - expect(middleware).toMatchObject({ - setSource: expect.any(Function), - }); - expect(spyOnGetMediaComposition).toHaveBeenCalled(); - expect(spyOnComposeKeySystemsResources).toHaveBeenCalled(); - expect(spyOnComposeAkamaiResources).toHaveBeenCalled(); - expect(spyOnGetMediaData).toHaveBeenCalled(); - expect(spyOnComposeSrcMediaData).toHaveBeenCalled(); - expect(spyOnSrgAnalytics).toHaveBeenCalled(); - expect(spyOnUpdateTitleBar).toHaveBeenCalled(); - expect(spyOnUpdatePoster).toHaveBeenCalled(); + expect(spyOnHandleSetSource).toHaveBeenCalledWith(player, srcObj, next); }); it('Should call the next middleware without error', async () => { - const spyOnComposeAkamaiResources = jest.spyOn( - SrgSsr, - 'composeAkamaiResources' - ); - const spyOnComposeKeySystemsResources = jest.spyOn( + jest.spyOn( SrgSsr, - 'composeKeySystemsResources' - ); - const spyOnGetMediaComposition = jest.spyOn( - SrgSsr, - 'getMediaComposition' - ); - const spyOnGetMediaData = jest.spyOn(SrgSsr, 'getMediaData'); - const spyOnComposeSrcMediaData = jest.spyOn( - SrgSsr, - 'composeSrcMediaData' - ); - const spyOnSrgAnalytics = jest.spyOn(SrgSsr, 'srgAnalytics'); - const spyOnUpdateTitleBar = jest.spyOn(SrgSsr, 'updateTitleBar'); - const spyOnUpdatePoster = jest.spyOn(SrgSsr, 'updatePoster'); - const middleware = SrgSsr.middleware(player, Image); + 'getSrcMediaObj' + ).mockResolvedValueOnce(srcMediaObj); + + const middleware = SrgSsr.middleware(player); await middleware.setSource({ src: 'urn:fake' }, async (err, srcObj) => { expect(err).toBeNull(); @@ -931,14 +981,6 @@ describe('SrgSsr', () => { expect(middleware).toMatchObject({ setSource: expect.any(Function), }); - expect(spyOnGetMediaComposition).toHaveBeenCalled(); - expect(spyOnComposeKeySystemsResources).toHaveBeenCalled(); - expect(spyOnComposeAkamaiResources).toHaveBeenCalled(); - expect(spyOnGetMediaData).toHaveBeenCalled(); - expect(spyOnComposeSrcMediaData).toHaveBeenCalled(); - expect(spyOnSrgAnalytics).toHaveBeenCalled(); - expect(spyOnUpdateTitleBar).toHaveBeenCalled(); - expect(spyOnUpdatePoster).toHaveBeenCalled(); }); it('Should catch and error if the source is not defined', async () => { @@ -980,23 +1022,12 @@ describe('SrgSsr', () => { }); it('Should return undefined and generate an error if the media has a block reason', async () => { - jest.spyOn(SrgSsr, 'getMediaData').mockReturnValueOnce({ - analyticsData: {}, - analyticsMetadata: {}, - blockReason: 'STARTDATE', - vendor: 'SRF', - dvr: true, - eventData: '', - id: '', - imageCopyright: '', - live: true, - mediaType: 'VIDEO', - mimeType: 'application/x-mpegURL', - presentation: '', - quality: '', - streaming: '', - url: 'https://fake.stream.url.ch/', - }); + srcMediaObj.mediaData.blockReason = 'STARTDATE'; + + jest.spyOn( + SrgSsr, + 'getSrcMediaObj' + ).mockResolvedValueOnce(srcMediaObj); const spyOnBlockingReason = jest.spyOn(SrgSsr, 'blockingReason'); const result = await SrgSsr.middleware(player).setSource( @@ -1007,8 +1038,7 @@ describe('SrgSsr', () => { expect(result).toBeUndefined(); expect(spyOnBlockingReason).toHaveBeenCalledWith( player, - 'STARTDATE', - expect.any(Object) + srcMediaObj ); });