From 151424fb364599d9f364cfa1b0a321728160fa85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaquim=20St=C3=A4hli?= Date: Thu, 11 Jul 2024 14:09:29 +0200 Subject: [PATCH] Use local MediaComposition for Live urns (#633) --- .../src/test/assets/media-composition.json | 147 ------- .../src/test/assets/media-compositions.json | 363 ++++++++++++++++++ .../CommandersActTrackerIntegrationTest.kt | 54 +-- .../ComScoreTrackerIntegrationTest.kt | 31 +- ...ocalMediaCompositionWithFallbackService.kt | 39 ++ 5 files changed, 433 insertions(+), 201 deletions(-) delete mode 100644 pillarbox-core-business/src/test/assets/media-composition.json create mode 100644 pillarbox-core-business/src/test/assets/media-compositions.json create mode 100644 pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/utils/LocalMediaCompositionWithFallbackService.kt diff --git a/pillarbox-core-business/src/test/assets/media-composition.json b/pillarbox-core-business/src/test/assets/media-composition.json deleted file mode 100644 index b711fd638..000000000 --- a/pillarbox-core-business/src/test/assets/media-composition.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "chapterUrn": "urn:rts:audio:3262363", - "episode": { - "id": "3262367", - "title": "Couleur 3 en direct", - "publishedDate": "2011-07-11T14:20:07+02:00", - "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", - "imageTitle": "Chaîne Couleur 3" - }, - "show": { - "id": "3262370", - "vendor": "RTS", - "transmission": "RADIO", - "urn": "urn:rts:show:radio:3262370", - "title": "Couleur 3 en direct", - "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", - "imageTitle": "Chaîne Couleur 3", - "bannerImageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/3x1", - "posterImageUrl": "https://ws.srf.ch/asset/image/audio/e0322b37-5697-474d-93ac-19a4044a6a24/POSTER.jpg", - "posterImageIsFallbackUrl": true, - "primaryChannelId": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", - "primaryChannelUrn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", - "audioDescriptionAvailable": false, - "subtitlesAvailable": false, - "multiAudioLanguagesAvailable": false, - "allowIndexing": false - }, - "channel": { - "id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", - "vendor": "RTS", - "urn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", - "title": "Couleur 3", - "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", - "imageTitle": "Chaîne Couleur 3", - "transmission": "RADIO" - }, - "chapterList": [ - { - "id": "3262363", - "mediaType": "AUDIO", - "vendor": "RTS", - "urn": "urn:rts:audio:3262363", - "title": "Couleur 3 en direct", - "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", - "imageTitle": "Chaîne Couleur 3", - "type": "LIVESTREAM", - "date": "2011-07-11T14:20:07+02:00", - "duration": 0, - "playableAbroad": true, - "displayable": true, - "position": 0, - "noEmbed": false, - "analyticsMetadata": { - "media_segment": "Livestream", - "media_type": "Audio", - "media_segment_id": "3262363", - "media_episode_length": "0", - "media_segment_length": "0", - "media_number_of_segment_selected": "1", - "media_number_of_segments_total": "1", - "media_duration_category": "infinit.livestream", - "media_is_geoblocked": "false", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_urn": "urn:rts:audio:3262363" - }, - "fullLengthMarkIn": 0, - "fullLengthMarkOut": 0, - "resourceList": [ - { - "url": "http://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8?", - "quality": "HD", - "protocol": "HLS-DVR", - "encoding": "H264", - "mimeType": "application/x-mpegURL", - "presentation": "DEFAULT", - "streaming": "HLS", - "dvr": true, - "live": true, - "mediaContainer": "MPEG2_TS", - "audioCodec": "AAC", - "videoCodec": "NONE", - "tokenType": "NONE", - "analyticsMetadata": { - "media_streaming_quality": "HD", - "media_special_format": "DEFAULT", - "media_url": "http://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8?" - }, - "streamOffset": 55000 - } - ] - } - ], - "analyticsData": { - "srg_pr_id": "3262367", - "srg_plid": "3262370", - "ns_st_pl": "Livestream", - "ns_st_pr": "Couleur 3 en direct", - "ns_st_dt": "2011-07-11", - "ns_st_ddt": "2011-07-11", - "ns_st_tdt": "2011-07-11", - "ns_st_tm": "14:20:07", - "ns_st_tep": "*null", - "ns_st_li": "1", - "ns_st_stc": "0867", - "ns_st_st": "Couleur 3", - "ns_st_tpr": "11562086", - "ns_st_en": "*null", - "ns_st_ge": "*null", - "ns_st_ia": "*null", - "ns_st_ce": "1", - "ns_st_cdm": "to", - "ns_st_cmt": "fc", - "srg_unit": "RTS", - "srg_c1": "live", - "srg_c2": "rts.ch_audio_couleur3", - "srg_c3": "COULEUR 3", - "srg_aod_prid": "3262367" - }, - "analyticsMetadata": { - "media_episode_id": "3262367", - "media_show_id": "11562086", - "media_show": "Oui Mais Non", - "media_episode": "Couleur 3 en direct", - "media_is_livestream": "true", - "media_full_length": "full", - "media_enterprise_units": "RTS", - "media_joker1": "live", - "media_joker2": "rts.ch_audio_couleur3", - "media_joker3": "COULEUR 3", - "media_is_web_only": "false", - "media_production_source": "produced.for.broadcasting", - "media_thumbnail": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9/scale/width/344", - "media_publication_date": "2011-07-11", - "media_publication_time": "14:20:07", - "media_publication_datetime": "2011-07-11T14:20:07+02:00", - "media_tv_date": "2011-07-11", - "media_tv_time": "14:20:07", - "media_tv_datetime": "2011-07-11T14:20:07+02:00", - "media_content_group": "Couleur 3", - "media_channel_id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", - "media_channel_cs": "0867", - "media_channel_name": "Couleur 3", - "media_since_publication_d": "4322", - "media_since_publication_h": "103747" - } -} diff --git a/pillarbox-core-business/src/test/assets/media-compositions.json b/pillarbox-core-business/src/test/assets/media-compositions.json new file mode 100644 index 000000000..ee6e04050 --- /dev/null +++ b/pillarbox-core-business/src/test/assets/media-compositions.json @@ -0,0 +1,363 @@ +[ + { + "chapterUrn": "urn:rts:audio:3262363", + "episode": { + "id": "3262367", + "title": "Couleur 3 en direct", + "publishedDate": "2011-07-11T14:20:07+02:00", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageTitle": "Chaîne Couleur 3" + }, + "show": { + "id": "3262370", + "vendor": "RTS", + "transmission": "RADIO", + "urn": "urn:rts:show:radio:3262370", + "title": "Couleur 3 en direct", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageTitle": "Chaîne Couleur 3", + "bannerImageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/3x1", + "posterImageUrl": "https://ws.srf.ch/asset/image/audio/e0322b37-5697-474d-93ac-19a4044a6a24/POSTER.jpg", + "posterImageIsFallbackUrl": true, + "primaryChannelId": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "primaryChannelUrn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "audioDescriptionAvailable": false, + "subtitlesAvailable": false, + "multiAudioLanguagesAvailable": false, + "allowIndexing": false + }, + "channel": { + "id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "vendor": "RTS", + "urn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "title": "Couleur 3", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageTitle": "Chaîne Couleur 3", + "transmission": "RADIO" + }, + "chapterList": [ + { + "id": "3262363", + "mediaType": "AUDIO", + "vendor": "RTS", + "urn": "urn:rts:audio:3262363", + "title": "Couleur 3 en direct", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageTitle": "Chaîne Couleur 3", + "type": "LIVESTREAM", + "date": "2011-07-11T14:20:07+02:00", + "duration": 0, + "playableAbroad": true, + "displayable": true, + "position": 0, + "noEmbed": false, + "analyticsMetadata": { + "media_segment": "Livestream", + "media_type": "Audio", + "media_segment_id": "3262363", + "media_episode_length": "0", + "media_segment_length": "0", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "infinit.livestream", + "media_is_geoblocked": "false", + "media_is_web_only": "false", + "media_production_source": "produced.for.broadcasting", + "media_urn": "urn:rts:audio:3262363" + }, + "fullLengthMarkIn": 0, + "fullLengthMarkOut": 0, + "resourceList": [ + { + "url": "http://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8?", + "quality": "HD", + "protocol": "HLS-DVR", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": true, + "live": true, + "mediaContainer": "MPEG2_TS", + "audioCodec": "AAC", + "videoCodec": "NONE", + "tokenType": "NONE", + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "http://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8?" + }, + "streamOffset": 55000 + } + ] + } + ], + "analyticsData": { + "srg_pr_id": "3262367", + "srg_plid": "3262370", + "ns_st_pl": "Livestream", + "ns_st_pr": "Couleur 3 en direct", + "ns_st_dt": "2011-07-11", + "ns_st_ddt": "2011-07-11", + "ns_st_tdt": "2011-07-11", + "ns_st_tm": "14:20:07", + "ns_st_tep": "*null", + "ns_st_li": "1", + "ns_st_stc": "0867", + "ns_st_st": "Couleur 3", + "ns_st_tpr": "11562086", + "ns_st_en": "*null", + "ns_st_ge": "*null", + "ns_st_ia": "*null", + "ns_st_ce": "1", + "ns_st_cdm": "to", + "ns_st_cmt": "fc", + "srg_unit": "RTS", + "srg_c1": "live", + "srg_c2": "rts.ch_audio_couleur3", + "srg_c3": "COULEUR 3", + "srg_aod_prid": "3262367" + }, + "analyticsMetadata": { + "media_episode_id": "3262367", + "media_show_id": "11562086", + "media_show": "Oui Mais Non", + "media_episode": "Couleur 3 en direct", + "media_is_livestream": "true", + "media_full_length": "full", + "media_enterprise_units": "RTS", + "media_joker1": "live", + "media_joker2": "rts.ch_audio_couleur3", + "media_joker3": "COULEUR 3", + "media_is_web_only": "false", + "media_production_source": "produced.for.broadcasting", + "media_thumbnail": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9/scale/width/344", + "media_publication_date": "2011-07-11", + "media_publication_time": "14:20:07", + "media_publication_datetime": "2011-07-11T14:20:07+02:00", + "media_tv_date": "2011-07-11", + "media_tv_time": "14:20:07", + "media_tv_datetime": "2011-07-11T14:20:07+02:00", + "media_content_group": "Couleur 3", + "media_channel_id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "media_channel_cs": "0867", + "media_channel_name": "Couleur 3", + "media_since_publication_d": "4322", + "media_since_publication_h": "103747" + } + }, + { + "chapterUrn": "urn:rts:video:8841634", + "episode": { + "id": "8741989", + "title": "Couleur 3 en direct", + "publishedDate": "2017-01-14T15:08:55+01:00", + "imageUrl": "https://www.rts.ch/2023/11/16/13/27/14474730.image/16x9", + "imageTitle": "Studio Couleur 3. [RTS]" + }, + "show": { + "id": "8483936", + "vendor": "RTS", + "transmission": "RADIO", + "urn": "urn:rts:show:radio:8483936", + "title": "Couleur 3 en vidéos", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageTitle": "Chaîne Couleur 3", + "bannerImageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/3x1", + "posterImageUrl": "https://ws.srf.ch/asset/image/audio/e0322b37-5697-474d-93ac-19a4044a6a24/POSTER.jpg", + "posterImageIsFallbackUrl": true, + "primaryChannelId": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "primaryChannelUrn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "audioDescriptionAvailable": false, + "subtitlesAvailable": false, + "multiAudioLanguagesAvailable": false, + "topicList": [ + { + "id": "16208", + "vendor": "RTS", + "transmission": "TV", + "urn": "urn:rts:topic:tv:16208", + "title": "Couleur 3" + } + ], + "allowIndexing": false + }, + "channel": { + "id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "vendor": "RTS", + "urn": "urn:rts:channel:radio:8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "title": "Couleur 3", + "imageUrl": "https://www.rts.ch/2020/05/18/14/20/11333286.image/16x9", + "imageUrlRaw": "https://il.srgssr.ch/image-service/dynamic/a9f904.svg", + "imageTitle": "Chaîne Couleur 3", + "transmission": "RADIO" + }, + "chapterList": [ + { + "id": "8841634", + "mediaType": "VIDEO", + "vendor": "RTS", + "urn": "urn:rts:video:8841634", + "title": "Couleur 3 en direct", + "imageUrl": "https://www.rts.ch/2023/11/16/13/27/14474730.image/16x9", + "imageTitle": "Studio Couleur 3. [RTS]", + "type": "LIVESTREAM", + "date": "2017-01-14T15:08:55+01:00", + "duration": 0, + "playableAbroad": false, + "displayable": true, + "position": 0, + "noEmbed": true, + "analyticsData": { + "ns_st_ep": "Livestream", + "ns_st_ty": "Video", + "ns_st_ci": "8841634", + "ns_st_el": "0", + "ns_st_cl": "0", + "ns_st_sl": "0", + "srg_mgeobl": "true", + "ns_st_tp": "1", + "ns_st_cn": "1", + "ns_st_ct": "vc13", + "ns_st_pn": "1", + "ns_st_cdm": "to", + "ns_st_cmt": "fc" + }, + "analyticsMetadata": { + "media_segment": "Livestream", + "media_type": "Video", + "media_segment_id": "8841634", + "media_episode_length": "0", + "media_segment_length": "0", + "media_number_of_segment_selected": "1", + "media_number_of_segments_total": "1", + "media_duration_category": "infinit.livestream", + "media_is_geoblocked": "true", + "media_is_web_only": "false", + "media_production_source": "produced.for.broadcasting", + "media_urn": "urn:rts:video:8841634", + "media_sub_set_id": "LIVESTREAM", + "media_topic_list": "urn:rts:topic:tv:16208", + "media_signlanguage_on": "false" + }, + "fullLengthMarkIn": 0, + "fullLengthMarkOut": 0, + "resourceList": [ + { + "url": "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?", + "quality": "HD", + "protocol": "HLS-DVR", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": true, + "live": true, + "mediaContainer": "MPEG2_TS", + "audioCodec": "AAC", + "videoCodec": "H264", + "tokenType": "NONE", + "analyticsData": { + "srg_mqual": "HD", + "srg_mpres": "DEFAULT" + }, + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?" + }, + "streamOffset": 30000 + }, + { + "url": "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?dw=0", + "quality": "HD", + "protocol": "HLS", + "encoding": "H264", + "mimeType": "application/x-mpegURL", + "presentation": "DEFAULT", + "streaming": "HLS", + "dvr": false, + "live": true, + "mediaContainer": "MPEG2_TS", + "audioCodec": "AAC", + "videoCodec": "H264", + "tokenType": "NONE", + "analyticsData": { + "srg_mqual": "HD", + "srg_mpres": "DEFAULT" + }, + "analyticsMetadata": { + "media_streaming_quality": "HD", + "media_special_format": "DEFAULT", + "media_url": "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?dw=0" + } + } + ], + "aspectRatio": "16:9" + } + ], + "topicList": [ + { + "id": "16208", + "vendor": "RTS", + "transmission": "TV", + "urn": "urn:rts:topic:tv:16208", + "title": "Couleur 3" + } + ], + "analyticsData": { + "srg_pr_id": "8741989", + "srg_plid": "8483936", + "ns_st_pl": "Livestream", + "ns_st_pr": "Couleur 3 en direct", + "ns_st_dt": "2017-01-14", + "ns_st_ddt": "2017-01-14", + "ns_st_tdt": "2017-01-14", + "ns_st_tm": "15:08", + "ns_st_tep": "*null", + "ns_st_li": "1", + "ns_st_stc": "0867", + "ns_st_st": "Couleur 3", + "ns_st_tpr": "14986950", + "ns_st_en": "*null", + "ns_st_ge": "*null", + "ns_st_ia": "*null", + "ns_st_ce": "1", + "ns_st_cdm": "to", + "ns_st_cmt": "fc", + "srg_unit": "RTS", + "srg_c1": "live", + "srg_c2": "rts.ch_video_couleur3", + "srg_c3": "COULEUR 3", + "srg_tv_id": "3f1e4c4e-0f1e-479b-92b7-16a9f064a2e3" + }, + "analyticsMetadata": { + "media_episode_id": "8741989", + "media_show_id": "14986950", + "media_show": "Tout.e Nu.e", + "media_episode": "Couleur 3 en direct", + "media_is_livestream": "true", + "media_full_length": "full", + "media_enterprise_units": "RTS", + "media_joker1": "live", + "media_joker2": "rts.ch_video_couleur3", + "media_joker3": "COULEUR 3", + "media_is_web_only": "false", + "media_production_source": "produced.for.broadcasting", + "media_thumbnail": "https://www.rts.ch/2023/11/16/13/27/14474730.image/16x9", + "media_publication_date": "2017-01-14", + "media_publication_time": "15:08:55", + "media_publication_datetime": "2017-01-14T15:08:55+01:00", + "media_tv_date": "2017-01-14", + "media_tv_time": "15:08:55", + "media_tv_datetime": "2017-01-14T15:08:55+01:00", + "media_content_group": "Couleur 3", + "media_channel_id": "8ceb28d9b3f1dd876d1df1780f908578cbefc3d7", + "media_channel_cs": "0867", + "media_channel_name": "Couleur 3", + "media_since_publication_d": "2734", + "media_since_publication_h": "65637", + "media_signlanguage_on": "false" + } + } +] diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/commandersact/CommandersActTrackerIntegrationTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/commandersact/CommandersActTrackerIntegrationTest.kt index 7c2af9308..1e033c436 100644 --- a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/commandersact/CommandersActTrackerIntegrationTest.kt +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/commandersact/CommandersActTrackerIntegrationTest.kt @@ -5,7 +5,6 @@ package ch.srgssr.pillarbox.core.business.tracker.commandersact import android.content.Context -import android.net.Uri import android.os.Looper import androidx.media3.common.MediaItem import androidx.media3.common.Player @@ -25,12 +24,9 @@ import ch.srgssr.pillarbox.analytics.commandersact.MediaEventType.Uptime import ch.srgssr.pillarbox.analytics.commandersact.TCMediaEvent import ch.srgssr.pillarbox.core.business.DefaultPillarbox import ch.srgssr.pillarbox.core.business.SRGMediaItemBuilder -import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition -import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultHttpClient -import ch.srgssr.pillarbox.core.business.integrationlayer.service.HttpMediaCompositionService -import ch.srgssr.pillarbox.core.business.integrationlayer.service.MediaCompositionService import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository import ch.srgssr.pillarbox.core.business.tracker.comscore.ComScoreTracker +import ch.srgssr.pillarbox.core.business.utils.LocalMediaCompositionWithFallbackService import ch.srgssr.pillarbox.player.test.utils.TestPillarboxRunHelper import ch.srgssr.pillarbox.player.tracker.MediaItemTrackerRepository import io.mockk.Called @@ -118,7 +114,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared and playing, changing media item`() { val tcMediaEvents = mutableListOf() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -199,7 +195,7 @@ class CommandersActTrackerIntegrationTest { @Test fun `player prepared but not playing`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY) @@ -216,7 +212,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared and playing`() { val tcMediaEventSlot = slot() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -240,7 +236,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared and playing, change playback speed`() { val tcMediaEventSlot = slot() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true player.setPlaybackSpeed(2f) @@ -265,7 +261,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared and playing, change playback speed while playing`() { val tcMediaEventSlot = slot() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -294,7 +290,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared, playing and paused`() { val tcMediaEvents = mutableListOf() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -332,7 +328,7 @@ class CommandersActTrackerIntegrationTest { fun `player prepared, playing, paused, playing again`() { val tcMediaEvents = mutableListOf() - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -669,7 +665,7 @@ class CommandersActTrackerIntegrationTest { @Test fun `player prepared and stopped`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.stop() @@ -688,7 +684,7 @@ class CommandersActTrackerIntegrationTest { CommandersActStreaming.POS_PERIOD = 2.seconds CommandersActStreaming.UPTIME_PERIOD = 4.seconds - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -746,7 +742,7 @@ class CommandersActTrackerIntegrationTest { CommandersActStreaming.POS_PERIOD = 2.seconds CommandersActStreaming.UPTIME_PERIOD = 4.seconds - player.setMediaItem(SRGMediaItemBuilder(URN_DVR).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_AUDIO).build()) player.prepare() player.playWhenReady = true @@ -874,36 +870,12 @@ class CommandersActTrackerIntegrationTest { assertTrue(tcMediaEvents.all { it.sourceId == null }) } - private class LocalMediaCompositionWithFallbackService( - context: Context, - private val fallbackService: MediaCompositionService = HttpMediaCompositionService(), - ) : MediaCompositionService { - private var mediaComposition: MediaComposition? = null - - init { - val json = context.assets.open("media-composition.json").bufferedReader().use { it.readText() } - - mediaComposition = DefaultHttpClient.jsonSerializer.decodeFromString(json) - } - - override suspend fun fetchMediaComposition(uri: Uri): Result { - val urn = uri.lastPathSegment - return if (urn == URN_DVR) { - runCatching { - requireNotNull(mediaComposition) - } - } else { - fallbackService.fetchMediaComposition(uri) - } - } - } - private companion object { private const val URL = "https://rts-vod-amd.akamaized.net/ww/14970442/7510ee63-05a4-3d48-8d26-1f1b3a82f6be/master.m3u8" private const val URN_AUDIO = "urn:rts:audio:13598743" - private const val URN_LIVE_VIDEO = "urn:rts:video:8841634" + private const val URN_LIVE_DVR_VIDEO = LocalMediaCompositionWithFallbackService.URN_LIVE_DVR_VIDEO private const val URN_NOT_LIVE_VIDEO = "urn:rsi:video:15916771" private const val URN_VOD_SHORT = "urn:rts:video:13444428" - private const val URN_DVR = "urn:rts:audio:3262363" + private const val URN_LIVE_DVR_AUDIO = LocalMediaCompositionWithFallbackService.URN_LIVE_DVR_AUDIO } } diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/comscore/ComScoreTrackerIntegrationTest.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/comscore/ComScoreTrackerIntegrationTest.kt index e831cf9be..2386c6612 100644 --- a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/comscore/ComScoreTrackerIntegrationTest.kt +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/tracker/comscore/ComScoreTrackerIntegrationTest.kt @@ -4,6 +4,7 @@ */ package ch.srgssr.pillarbox.core.business.tracker.comscore +import android.content.Context import android.view.SurfaceView import android.view.ViewGroup import androidx.core.view.updateLayoutParams @@ -18,6 +19,7 @@ import ch.srgssr.pillarbox.analytics.BuildConfig import ch.srgssr.pillarbox.core.business.DefaultPillarbox import ch.srgssr.pillarbox.core.business.SRGMediaItemBuilder import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository +import ch.srgssr.pillarbox.core.business.utils.LocalMediaCompositionWithFallbackService import ch.srgssr.pillarbox.player.tracker.MediaItemTrackerRepository import com.comscore.streaming.AssetMetadata import com.comscore.streaming.StreamingAnalytics @@ -55,10 +57,13 @@ class ComScoreTrackerIntegrationTest { mediaItemTrackerRepository.registerFactory(ComScoreTracker::class.java) { ComScoreTracker(streamingAnalytics) } + val context = ApplicationProvider.getApplicationContext() + val mediaCompositionWithFallbackService = LocalMediaCompositionWithFallbackService(context) player = DefaultPillarbox( context = ApplicationProvider.getApplicationContext(), mediaItemTrackerRepository = mediaItemTrackerRepository, + mediaCompositionService = mediaCompositionWithFallbackService, clock = clock, ) } @@ -72,7 +77,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `player prepared and playing, changing media item`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -130,7 +135,7 @@ class ComScoreTrackerIntegrationTest { @Test @Ignore("SurfaceView/SurfaceHolder not implemented in Robolectric") fun `surface size changed`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -186,7 +191,7 @@ class ComScoreTrackerIntegrationTest { // region Live media @Test fun `live - player prepared but not playing`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY) @@ -204,7 +209,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared and playing`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -225,7 +230,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared and playing, change playback speed`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true player.setPlaybackSpeed(2f) @@ -248,7 +253,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared and playing, change playback speed while playing`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -272,7 +277,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared, playing and paused`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -299,7 +304,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared, playing, paused, playing again`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -333,7 +338,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared, playing and stopped`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -360,7 +365,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared, playing and seeking`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.playWhenReady = true @@ -391,7 +396,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared and seek`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.seekTo(3.minutes.inWholeMilliseconds) @@ -410,7 +415,7 @@ class ComScoreTrackerIntegrationTest { @Test fun `live - player prepared and stopped`() { - player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_VIDEO).build()) + player.setMediaItem(SRGMediaItemBuilder(URN_LIVE_DVR_VIDEO).build()) player.prepare() player.stop() @@ -728,7 +733,7 @@ class ComScoreTrackerIntegrationTest { private companion object { private const val URL = "https://rts-vod-amd.akamaized.net/ww/14970442/7510ee63-05a4-3d48-8d26-1f1b3a82f6be/master.m3u8" private const val URN_AUDIO = "urn:rts:audio:13598743" - private const val URN_LIVE_VIDEO = "urn:rts:video:8841634" + private const val URN_LIVE_DVR_VIDEO = LocalMediaCompositionWithFallbackService.URN_LIVE_DVR_VIDEO private const val URN_NOT_LIVE_VIDEO = "urn:rsi:video:15916771" } } diff --git a/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/utils/LocalMediaCompositionWithFallbackService.kt b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/utils/LocalMediaCompositionWithFallbackService.kt new file mode 100644 index 000000000..267c9127a --- /dev/null +++ b/pillarbox-core-business/src/test/java/ch/srgssr/pillarbox/core/business/utils/LocalMediaCompositionWithFallbackService.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) SRG SSR. All rights reserved. + * License information is available from the LICENSE file. + */ +package ch.srgssr.pillarbox.core.business.utils + +import android.content.Context +import android.net.Uri +import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition +import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultHttpClient +import ch.srgssr.pillarbox.core.business.integrationlayer.service.HttpMediaCompositionService +import ch.srgssr.pillarbox.core.business.integrationlayer.service.MediaCompositionService + +internal class LocalMediaCompositionWithFallbackService( + context: Context, + private val fallbackService: MediaCompositionService = HttpMediaCompositionService(), +) : MediaCompositionService { + private var mediaCompositions = mutableListOf() + + init { + val json = context.assets.open("media-compositions.json").bufferedReader().use { it.readText() } + mediaCompositions = DefaultHttpClient.jsonSerializer.decodeFromString(json) + } + + override suspend fun fetchMediaComposition(uri: Uri): Result { + val urn = uri.lastPathSegment + val mediaComposition = mediaCompositions.firstOrNull { it.chapterUrn == urn } + return if (mediaComposition != null) { + runCatching { mediaComposition } + } else { + fallbackService.fetchMediaComposition(uri) + } + } + + companion object { + const val URN_LIVE_DVR_VIDEO = "urn:rts:video:8841634" + const val URN_LIVE_DVR_AUDIO = "urn:rts:audio:3262363" + } +}