@saooti/octopus-sdk 40.0.3 → 40.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +31 -31
- package/package.json +1 -1
- package/plateform.conf +1 -1
- package/src/App.vue +9 -3
- package/src/api/classicApi.ts +1 -1
- package/src/components/composable/player/usePlayerDisplayTime.ts +33 -0
- package/src/components/composable/player/usePlayerLive.ts +150 -0
- package/src/components/composable/player/usePlayerLogic.ts +265 -0
- package/src/components/composable/player/usePlayerLogicProgress.ts +135 -0
- package/src/components/composable/player/usePlayerStitching.ts +213 -0
- package/src/components/composable/player/usePlayerTranscript.ts +120 -0
- package/src/components/composable/player/usePlayerVast.ts +207 -0
- package/src/components/composable/podcasts/useCountdown.ts +53 -0
- package/src/components/composable/podcasts/usePodcastView.ts +85 -0
- package/src/components/composable/radio/usefetchRadioData.ts +75 -0
- package/src/components/composable/route/useAdvancedParamInit.ts +165 -0
- package/src/components/composable/route/useRouteUpdateParams.ts +48 -0
- package/src/components/composable/route/useRubriquesFilterComputed.ts +24 -0
- package/src/components/composable/route/useRubriquesFilterParam.ts +32 -0
- package/src/components/composable/route/useSeoTitleUrl.ts +30 -0
- package/src/components/composable/route/useSimplePageParam.ts +50 -0
- package/src/components/composable/useErrorHandler.ts +25 -0
- package/src/components/composable/useImageProxy.ts +28 -0
- package/src/components/composable/useInit.ts +38 -0
- package/src/components/composable/useMetaTitle.ts +19 -0
- package/src/components/composable/useMetaTitleWatch.ts +14 -0
- package/src/components/composable/useOrgaComputed.ts +23 -0
- package/src/components/composable/useOrganisationFilter.ts +65 -0
- package/src/components/composable/useResizePhone.ts +27 -0
- package/src/components/composable/useSelenium.ts +10 -0
- package/src/components/composable/useTagOf.ts +21 -0
- package/src/components/display/accessibility/AccessibilityModal.vue +136 -0
- package/src/components/display/aggregator/RssSection.vue +1 -4
- package/src/components/display/categories/CategoryChooser.vue +1 -1
- package/src/components/display/categories/CategoryFilter.vue +7 -3
- package/src/components/display/categories/CategoryList.vue +5 -2
- package/src/components/display/comments/CommentInput.vue +0 -3
- package/src/components/display/comments/CommentList.vue +6 -2
- package/src/components/display/comments/CommentPlayer.vue +5 -2
- package/src/components/display/comments/CommentSection.vue +0 -2
- package/src/components/display/comments/item/CommentBasicView.vue +4 -4
- package/src/components/display/comments/item/CommentItem.vue +0 -4
- package/src/components/display/comments/item/CommentMoreActions.vue +6 -2
- package/src/components/display/emission/EmissionInlineList.vue +6 -6
- package/src/components/display/emission/EmissionItem.vue +13 -6
- package/src/components/display/emission/EmissionList.vue +5 -2
- package/src/components/display/emission/EmissionPlayerItem.vue +8 -5
- package/src/components/display/emission/EmissionPresentationItem.vue +16 -7
- package/src/components/display/emission/EmissionPresentationList.vue +10 -7
- package/src/components/display/filter/AdvancedSearch.vue +9 -6
- package/src/components/display/filter/CategorySearchFilter.vue +0 -2
- package/src/components/display/filter/ProductorSearch.vue +8 -3
- package/src/components/display/filter/RubriqueFilter.vue +6 -2
- package/src/components/display/list/ListPaginate.vue +9 -6
- package/src/components/display/list/SwiperList.vue +6 -5
- package/src/components/display/live/CountDown.vue +7 -15
- package/src/components/display/live/CountdownOctopus.vue +10 -30
- package/src/components/display/live/LiveItem.vue +0 -2
- package/src/components/display/live/LiveList.vue +9 -4
- package/src/components/display/live/RadioCurrently.vue +9 -5
- package/src/components/display/live/RadioImage.vue +6 -4
- package/src/components/display/live/RadioItem.vue +1 -2
- package/src/components/display/live/RadioList.vue +5 -3
- package/src/components/display/live/RadioPlanning.vue +10 -7
- package/src/components/display/organisation/OrganisationChooser.vue +8 -4
- package/src/components/display/participant/ParticipantInlineList.vue +5 -5
- package/src/components/display/participant/ParticipantItem.vue +13 -5
- package/src/components/display/participant/ParticipantList.vue +6 -3
- package/src/components/display/playlist/PlaylistItem.vue +12 -5
- package/src/components/display/playlist/PlaylistList.vue +6 -3
- package/src/components/display/playlist/PodcastList.vue +8 -4
- package/src/components/display/podcastmaker/PodcastmakerHeader.vue +6 -3
- package/src/components/display/podcasts/DownloadPodcastButton.vue +2 -4
- package/src/components/display/podcasts/PodcastImage.vue +6 -3
- package/src/components/display/podcasts/PodcastInlineListTemplate.vue +7 -4
- package/src/components/display/podcasts/PodcastItem.vue +1 -1
- package/src/components/display/podcasts/PodcastItemInfo.vue +6 -3
- package/src/components/display/podcasts/PodcastList.vue +6 -3
- package/src/components/display/podcasts/PodcastModuleBox.vue +22 -9
- package/src/components/display/podcasts/PodcastPlayBar.vue +1 -3
- package/src/components/display/podcasts/PodcastPlayButton.vue +1 -3
- package/src/components/display/podcasts/PodcastRawTranscript.vue +79 -10
- package/src/components/display/podcasts/PodcastRubriqueList.vue +4 -3
- package/src/components/display/podcasts/TagList.vue +5 -2
- package/src/components/display/podcasts/VideoModuleBox.vue +6 -3
- package/src/components/display/rubriques/RubriqueChooser.vue +0 -2
- package/src/components/display/rubriques/RubriqueList.vue +7 -5
- package/src/components/display/sharing/ShareButtons.vue +4 -2
- package/src/components/display/sharing/ShareDistribution.vue +4 -2
- package/src/components/form/ClassicEmojiPicker.vue +5 -3
- package/src/components/misc/ClassicLazy.vue +2 -2
- package/src/components/misc/FooterGarSection.vue +2 -3
- package/src/components/misc/FooterSection.vue +9 -5
- package/src/components/misc/MobileMenu.vue +5 -3
- package/src/components/misc/TopBar.vue +8 -6
- package/src/components/misc/TopBarMainContent.vue +8 -4
- package/src/components/misc/modal/ClassicModalInBody.vue +2 -3
- package/src/components/misc/modal/ClipboardModal.vue +4 -3
- package/src/components/misc/modal/NewsletterModal.vue +4 -3
- package/src/components/misc/modal/ShareModalPlayer.vue +4 -2
- package/src/components/misc/player/PlayerCompact.vue +30 -41
- package/src/components/misc/player/PlayerComponent.vue +69 -84
- package/src/components/misc/player/PlayerLarge.vue +43 -58
- package/src/components/misc/player/elements/PlayerImage.vue +6 -3
- package/src/components/misc/player/elements/PlayerTitle.vue +6 -2
- package/src/components/misc/player/radio/RadioHistory.vue +2 -4
- package/src/components/misc/player/video/PlayerVideoHls.vue +6 -7
- package/src/components/pages/EmissionPage.vue +19 -7
- package/src/components/pages/EmissionsPage.vue +31 -23
- package/src/components/pages/HomePage.vue +5 -2
- package/src/components/pages/PageLogout.vue +0 -2
- package/src/components/pages/PageNotFound.vue +11 -15
- package/src/components/pages/ParticipantPage.vue +18 -7
- package/src/components/pages/ParticipantsPage.vue +16 -21
- package/src/components/pages/PlaylistPage.vue +18 -7
- package/src/components/pages/PlaylistsPage.vue +20 -29
- package/src/components/pages/PodcastPage.vue +12 -6
- package/src/components/pages/PodcastsPage.vue +46 -48
- package/src/components/pages/RadioPage.vue +9 -6
- package/src/components/pages/RubriquePage.vue +41 -52
- package/src/components/pages/VideoPage.vue +152 -166
- package/src/helper/cookiesHelper.ts +20 -0
- package/src/helper/displayHelper.ts +15 -0
- package/src/helper/downloadHelper.ts +30 -0
- package/src/helper/{fetch.ts → fetchHelper.ts} +0 -1
- package/src/helper/loadScript.ts +22 -0
- package/src/helper/radio/radioHelper.ts +15 -0
- package/src/helper/{string.ts → stringHelper.ts} +5 -0
- package/src/locale/de.ts +4 -0
- package/src/locale/en.ts +4 -0
- package/src/locale/es.ts +4 -0
- package/src/locale/fr.ts +4 -0
- package/src/locale/it.ts +4 -0
- package/src/locale/sl.ts +4 -0
- package/src/stores/AuthStore.ts +1 -2
- package/src/stores/CommentStore.ts +8 -8
- package/src/stores/PlayerStore.ts +1 -1
- package/src/style/general.scss +15 -1
- package/src/components/mixins/cookies.ts +0 -22
- package/src/components/mixins/displayMethods.ts +0 -17
- package/src/components/mixins/download.ts +0 -33
- package/src/components/mixins/fetchParameters.ts +0 -16
- package/src/components/mixins/handle403.ts +0 -22
- package/src/components/mixins/imageProxy.ts +0 -28
- package/src/components/mixins/init.ts +0 -34
- package/src/components/mixins/loadScript.ts +0 -25
- package/src/components/mixins/metaTitle.ts +0 -15
- package/src/components/mixins/metaTitleWatch.ts +0 -26
- package/src/components/mixins/orgaComputed.ts +0 -23
- package/src/components/mixins/organisationFilter.ts +0 -56
- package/src/components/mixins/player/playerDisplayTime.ts +0 -35
- package/src/components/mixins/player/playerLive.ts +0 -144
- package/src/components/mixins/player/playerLogic.ts +0 -275
- package/src/components/mixins/player/playerLogicProgress.ts +0 -135
- package/src/components/mixins/player/playerStitching.ts +0 -202
- package/src/components/mixins/player/playerTranscript.ts +0 -113
- package/src/components/mixins/player/playerVast.ts +0 -198
- package/src/components/mixins/podcast/countdown.ts +0 -45
- package/src/components/mixins/podcast/podcastView.ts +0 -63
- package/src/components/mixins/radio/fetchRadioData.ts +0 -77
- package/src/components/mixins/resizePhone.ts +0 -26
- package/src/components/mixins/routeParam/advancedParamInit.ts +0 -202
- package/src/components/mixins/routeParam/paginateParamInit.ts +0 -43
- package/src/components/mixins/routeParam/routeParams.ts +0 -33
- package/src/components/mixins/routeParam/rubriquesFilterComputed.ts +0 -22
- package/src/components/mixins/routeParam/rubriquesFilterParam.ts +0 -29
- package/src/components/mixins/selenium.ts +0 -7
- package/src/components/mixins/seoTitleUrl.ts +0 -26
- package/src/components/mixins/tagOfMixins.ts +0 -19
- package/src/helper/uuidGenerator.ts +0 -7
- /package/src/{helper → components/composable}/useEventListener.ts +0 -0
- /package/src/{components/mixins/debounce.ts → helper/debounceHelper.ts} +0 -0
- /package/src/helper/{dom.ts → domHelper.ts} +0 -0
- /package/src/helper/{duration.ts → durationHelper.ts} +0 -0
package/index.ts
CHANGED
|
@@ -89,28 +89,28 @@ export const getClassicContentEditable = () => import("./src/components/form/Cla
|
|
|
89
89
|
export const getSwiperList = () => import("./src/components/display/list/SwiperList.vue");
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
import
|
|
95
|
-
import
|
|
96
|
-
import
|
|
97
|
-
import
|
|
98
|
-
import
|
|
99
|
-
import
|
|
100
|
-
import
|
|
101
|
-
import
|
|
102
|
-
import debounce from "./src/components/mixins/debounce.ts";
|
|
103
|
-
import downloadMixins from "./src/components/mixins/download.ts";
|
|
104
|
-
import metaTitle from "./src/components/mixins/metaTitle.ts";
|
|
105
|
-
import metaTitleWatch from "./src/components/mixins/metaTitleWatch.ts";
|
|
92
|
+
//Composable
|
|
93
|
+
import {useResizePhone} from "./src/components/composable/useResizePhone";
|
|
94
|
+
import {useTagOf} from "./src/components/composable/useTagOf.ts";
|
|
95
|
+
import {useSelenium} from "./src/components/composable/useSelenium.ts";
|
|
96
|
+
import {useImageProxy} from "./src/components/composable/useImageProxy.ts";
|
|
97
|
+
import {useMetaTitle} from "./src/components/composable/useMetaTitle.ts";
|
|
98
|
+
import {useMetaTitleWatch} from "./src/components/composable/useMetaTitleWatch.ts";
|
|
99
|
+
import {useOrganisationFilter} from "./src/components/composable/useOrganisationFilter.ts";
|
|
100
|
+
import {useInit} from "./src/components/composable/useInit.ts";
|
|
101
|
+
import {useErrorHandler} from "./src/components/composable/useErrorHandler.ts";
|
|
106
102
|
|
|
107
103
|
|
|
108
|
-
//helper
|
|
109
|
-
import domHelper from "./src/helper/dom.ts";
|
|
110
|
-
import durationHelper from "./src/helper/duration.ts";
|
|
111
|
-
import stringHelper from "./src/helper/string.ts";
|
|
112
|
-
import fetchHelper from "./src/helper/fetch.ts";
|
|
113
104
|
|
|
105
|
+
//helper
|
|
106
|
+
import domHelper from "./src/helper/domHelper.ts";
|
|
107
|
+
import durationHelper from "./src/helper/durationHelper.ts";
|
|
108
|
+
import stringHelper from "./src/helper/stringHelper.ts";
|
|
109
|
+
import fetchHelper from "./src/helper/fetchHelper.ts";
|
|
110
|
+
import cookiesHelper from "./src/helper/cookiesHelper.ts";
|
|
111
|
+
import downloadHelper from "./src/helper/downloadHelper.ts";
|
|
112
|
+
import displayHelper from "./src/helper/displayHelper.ts";
|
|
113
|
+
import debounce from "./src/helper/debounceHelper.ts";
|
|
114
114
|
|
|
115
115
|
//stores
|
|
116
116
|
import {useVastStore} from "./src/stores/VastStore.ts";
|
|
@@ -138,16 +138,16 @@ export const getRadiolineIcon = () => import("./src/components/icons/RadiolineIc
|
|
|
138
138
|
export const getTuninIcon = () => import("./src/components/icons/TuninIcon.vue");
|
|
139
139
|
export const getXIcon = () => import("./src/components/icons/XIcon.vue");
|
|
140
140
|
|
|
141
|
-
|
|
142
141
|
export {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
142
|
+
useResizePhone,
|
|
143
|
+
useTagOf,
|
|
144
|
+
useSelenium,
|
|
145
|
+
useImageProxy,
|
|
146
|
+
useMetaTitle,
|
|
147
|
+
useMetaTitleWatch,
|
|
148
|
+
useOrganisationFilter,
|
|
149
|
+
useInit,
|
|
150
|
+
useErrorHandler,
|
|
151
151
|
debounce,
|
|
152
152
|
useVastStore,
|
|
153
153
|
useSaveFetchStore,
|
|
@@ -164,7 +164,7 @@ export {
|
|
|
164
164
|
getApiUrl,
|
|
165
165
|
ModuleApi,
|
|
166
166
|
classicApi,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
cookiesHelper,
|
|
168
|
+
downloadHelper,
|
|
169
|
+
displayHelper
|
|
170
170
|
};
|
package/package.json
CHANGED
package/plateform.conf
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
preprod.saooti.org
|
package/src/App.vue
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
import TopBar from "@/components/misc/TopBar.vue";
|
|
19
19
|
import PlayerComponent from "@/components/misc/player/PlayerComponent.vue";
|
|
20
20
|
import ClassicLazy from "@/components/misc/ClassicLazy.vue";
|
|
21
|
-
import
|
|
22
|
-
import
|
|
21
|
+
import {useInit} from "./components/composable/useInit";
|
|
22
|
+
import {useMetaTitle} from "./components/composable/useMetaTitle";
|
|
23
|
+
import {useOrganisationFilter} from "./components/composable/useOrganisationFilter";
|
|
23
24
|
import { useAuthStore } from "./stores/AuthStore";
|
|
24
25
|
import { useFilterStore } from "./stores/FilterStore";
|
|
25
26
|
import { useGeneralStore } from "./stores/GeneralStore";
|
|
@@ -42,7 +43,12 @@ export default defineComponent({
|
|
|
42
43
|
ClassicLazy,
|
|
43
44
|
},
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
setup(){
|
|
47
|
+
const { updateMetaTitle } = useMetaTitle();
|
|
48
|
+
const {initSdk} = useInit();
|
|
49
|
+
const {selectOrganisation} = useOrganisationFilter();
|
|
50
|
+
return { updateMetaTitle, initSdk, selectOrganisation }
|
|
51
|
+
},
|
|
46
52
|
|
|
47
53
|
data() {
|
|
48
54
|
return {
|
package/src/api/classicApi.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {getApiUrl, ModuleApi} from "./apiConnection";
|
|
2
|
-
import fetchHelper from "../helper/
|
|
2
|
+
import fetchHelper from "../helper/fetchHelper";
|
|
3
3
|
import axios, { AxiosError } from 'axios';
|
|
4
4
|
import { FetchParam } from "@/stores/class/general/fetchParam";
|
|
5
5
|
import { state } from "../stores/ParamSdkStore";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { usePlayerStore } from "../../../stores/PlayerStore";
|
|
3
|
+
import { useVastStore } from "../../../stores/VastStore";
|
|
4
|
+
import DurationHelper from "../../../helper/durationHelper";
|
|
5
|
+
export const usePlayerDisplayTime = ()=>{
|
|
6
|
+
|
|
7
|
+
const playerStore = usePlayerStore();
|
|
8
|
+
const vastStore = useVastStore();
|
|
9
|
+
|
|
10
|
+
const displayPlayTime = computed(() => {
|
|
11
|
+
if(vastStore.isAdPlaying){
|
|
12
|
+
return DurationHelper.formatDuration(Math.round(vastStore.currentTimeAd));
|
|
13
|
+
}
|
|
14
|
+
return playerStore.playedTime;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const displayTotalTime = computed(() => {
|
|
18
|
+
if(vastStore.isAdPlaying){
|
|
19
|
+
return DurationHelper.formatDuration(Math.round(vastStore.currentDurationAd));
|
|
20
|
+
}
|
|
21
|
+
return playerStore.totalTime;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
displayPlayTime,
|
|
28
|
+
displayTotalTime,
|
|
29
|
+
transcriptText: playerStore.transcriptText,
|
|
30
|
+
radioUrl: playerStore.radioUrl,
|
|
31
|
+
isAdPlaying: vastStore.isAdPlaying,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import stringHelper from "../../../helper/stringHelper";
|
|
2
|
+
import { usePlayerLogicProgress } from "./usePlayerLogicProgress";
|
|
3
|
+
import { Ref, ref } from "vue";
|
|
4
|
+
import { usePlayerStore } from "../../../stores/PlayerStore";
|
|
5
|
+
import { useApiStore } from "../../../stores/ApiStore";
|
|
6
|
+
import dayjs from "dayjs";
|
|
7
|
+
/* eslint-disable*/
|
|
8
|
+
let Hls:any = null;
|
|
9
|
+
/* eslint-enable*/
|
|
10
|
+
const maxMinutesSessionId = 1;
|
|
11
|
+
export const usePlayerLive = ()=>{
|
|
12
|
+
|
|
13
|
+
const { listenTime, initLiveDownloadId, setDownloadId, onTimeUpdateProgress } = usePlayerLogicProgress();
|
|
14
|
+
|
|
15
|
+
const hlsReady= ref(false);
|
|
16
|
+
const audioElement: Ref<HTMLAudioElement | null>= ref(null);
|
|
17
|
+
const hls: Ref<any>= ref(null);
|
|
18
|
+
const hlsRetryTimeout: Ref<ReturnType<typeof setTimeout> | undefined>= ref(undefined);
|
|
19
|
+
const playPromise: Ref<any>= ref(undefined);
|
|
20
|
+
const errorHls= ref(false);
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const playerStore = usePlayerStore();
|
|
24
|
+
const apiStore = useApiStore();
|
|
25
|
+
|
|
26
|
+
function onPlay(): void {
|
|
27
|
+
playerStore.playerChangeStatus("PAUSED"===playerStore.playerStatus);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function playRadio() {
|
|
31
|
+
if (!playerStore.playerRadio) return;
|
|
32
|
+
handleSessionIdRadio();
|
|
33
|
+
playHls(playerStore.playerRadio.url+"?origin=octopus&sessionId="+playerStore.playerRadio.sessionId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function handleSessionIdRadio(){
|
|
37
|
+
if(!playerStore.playerRadio) return;
|
|
38
|
+
if(playerStore.playerRadio.sessionId && dayjs().diff(dayjs(playerStore.playerRadio.dateSessionId), 'm')<maxMinutesSessionId){
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
playerStore.playerRadio.sessionId = stringHelper.uuidv4();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function playLive() {
|
|
45
|
+
if (!playerStore.playerLive) return;
|
|
46
|
+
const hlsStreamUrl = `${apiStore.hlsUrl}live/dev.${playerStore.playerLive.conferenceId}/index.m3u8`;
|
|
47
|
+
playHls(hlsStreamUrl);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function playHls(hlsStreamUrl: string): Promise<void> {
|
|
51
|
+
try {
|
|
52
|
+
if(null===audioElement.value){
|
|
53
|
+
audioElement.value = document.getElementById(
|
|
54
|
+
"audio-player",
|
|
55
|
+
) as HTMLAudioElement;
|
|
56
|
+
}
|
|
57
|
+
if (null === audioElement.value) {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
playHls(hlsStreamUrl);
|
|
60
|
+
}, 1000);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const ua = navigator.userAgent.toLowerCase();
|
|
64
|
+
const isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile");
|
|
65
|
+
if (
|
|
66
|
+
audioElement.value.canPlayType("application/vnd.apple.mpegurl") &&
|
|
67
|
+
!isAndroid
|
|
68
|
+
) {
|
|
69
|
+
audioElement.value.src = hlsStreamUrl;
|
|
70
|
+
await initLiveDownloadId();
|
|
71
|
+
hlsReady.value = true;
|
|
72
|
+
await audioElement.value.play();
|
|
73
|
+
onPlay();
|
|
74
|
+
} else {
|
|
75
|
+
await initHls(hlsStreamUrl);
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
onHlsError(hlsStreamUrl);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function onHlsError(hlsStreamUrl:string){
|
|
83
|
+
if("STOPPED"!==playerStore.playerStatus && undefined===hlsRetryTimeout.value){
|
|
84
|
+
hlsRetryTimeout.value = setTimeout(() => {
|
|
85
|
+
errorHls.value = false;
|
|
86
|
+
playHls(hlsStreamUrl);
|
|
87
|
+
hlsRetryTimeout.value = undefined;
|
|
88
|
+
}, 5000);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function initHls(hlsStreamUrl: string) {
|
|
93
|
+
if (null === Hls) {
|
|
94
|
+
await import("hls.js").then((hlsLibrary) => {
|
|
95
|
+
Hls = hlsLibrary.default;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (!Hls.isSupported()) {
|
|
99
|
+
throw new Error("Hls is not supported ! ");
|
|
100
|
+
}
|
|
101
|
+
hls.value = new Hls();
|
|
102
|
+
hls.value.on(Hls.Events.MANIFEST_PARSED, async () => {
|
|
103
|
+
await initLiveDownloadId();
|
|
104
|
+
hlsReady.value = true;
|
|
105
|
+
if(true===errorHls.value){
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
playPromise.value = (audioElement.value as HTMLAudioElement).play();
|
|
109
|
+
playPromise.value.then(() =>{
|
|
110
|
+
playPromise.value = undefined;
|
|
111
|
+
onPlay();
|
|
112
|
+
}).catch(()=>{
|
|
113
|
+
onHlsError(hlsStreamUrl);
|
|
114
|
+
playPromise.value = undefined;
|
|
115
|
+
})
|
|
116
|
+
});
|
|
117
|
+
hls.value.on(Hls.Events.ERROR, async (e, data:any) => {
|
|
118
|
+
errorHls.value = true;
|
|
119
|
+
if(undefined===playPromise.value && data.fatal){
|
|
120
|
+
onHlsError(hlsStreamUrl);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
hls.value.loadSource(hlsStreamUrl);
|
|
124
|
+
hls.value.attachMedia(audioElement.value as HTMLAudioElement);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function endingLive(): Promise<void> {
|
|
128
|
+
clearTimeout(hlsRetryTimeout.value);
|
|
129
|
+
hlsRetryTimeout.value = undefined;
|
|
130
|
+
audioElement.value = null;
|
|
131
|
+
const audio: HTMLElement | null = document.getElementById("audio-player");
|
|
132
|
+
if (audio && hls.value) {
|
|
133
|
+
hls.value.destroy();
|
|
134
|
+
hls.value = null;
|
|
135
|
+
}else{
|
|
136
|
+
(audio as HTMLAudioElement).pause();
|
|
137
|
+
}
|
|
138
|
+
(audio as HTMLAudioElement).src = "";
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
listenTime,
|
|
143
|
+
setDownloadId,
|
|
144
|
+
onTimeUpdateProgress,
|
|
145
|
+
playLive,
|
|
146
|
+
endingLive,
|
|
147
|
+
playRadio,
|
|
148
|
+
onPlay
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
|
|
2
|
+
import { usePlayerLive } from "./usePlayerLive";
|
|
3
|
+
import { usePlayerStitching } from "./usePlayerStitching";
|
|
4
|
+
import { usePlayerTranscript } from "./usePlayerTranscript";
|
|
5
|
+
import { nextTick, Ref, ref, watch } from "vue";
|
|
6
|
+
import { usePlayerStore } from "../../../stores/PlayerStore";
|
|
7
|
+
import { useAuthStore } from "../../../stores/AuthStore";
|
|
8
|
+
import { useGeneralStore } from "../../../stores/GeneralStore";
|
|
9
|
+
import { useVastStore } from "../../../stores/VastStore";
|
|
10
|
+
import classicApi from "../../../api/classicApi";
|
|
11
|
+
import dayjs from "dayjs";
|
|
12
|
+
import { FetchParam } from "@/stores/class/general/fetchParam";
|
|
13
|
+
export const usePlayerLogic = (forceHide: Ref<boolean, boolean>)=>{
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
listenTime,
|
|
17
|
+
onPlay, setDownloadId, onTimeUpdateProgress, playLive, endingLive, playRadio} = usePlayerLive();
|
|
18
|
+
const { contentEndedAdsLoader } = usePlayerStitching();
|
|
19
|
+
const { getTranscription, onTimeUpdateTranscript, onSeekedTranscript, checkDelaytWithStitching } = usePlayerTranscript();
|
|
20
|
+
|
|
21
|
+
const playerError= ref(false);
|
|
22
|
+
const listenError= ref(false);
|
|
23
|
+
const percentLiveProgress= ref(0);
|
|
24
|
+
const durationLivePosition= ref(0);
|
|
25
|
+
const displayAlertBar= ref(false);
|
|
26
|
+
const hlsReady= ref(false);
|
|
27
|
+
const audioUrlToPlay= ref("");
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const playerStore = usePlayerStore();
|
|
31
|
+
const generalStore = useGeneralStore();
|
|
32
|
+
const vastStore = useVastStore();
|
|
33
|
+
const authStore = useAuthStore();
|
|
34
|
+
|
|
35
|
+
watch(()=>getAudioUrl(), async () => {
|
|
36
|
+
playerError.value = false;
|
|
37
|
+
if (
|
|
38
|
+
playerStore.playerMedia ||
|
|
39
|
+
!playerStore.playerPodcast ||
|
|
40
|
+
playerStore.playerVideo ||
|
|
41
|
+
!playerStore.playerPodcast.availability.visibility ||
|
|
42
|
+
listenError.value
|
|
43
|
+
) {
|
|
44
|
+
audioUrlToPlay.value = getAudioUrl();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const response = await classicApi.fetchData<{
|
|
48
|
+
location: string;
|
|
49
|
+
downloadId: number;
|
|
50
|
+
}>({
|
|
51
|
+
api:0,
|
|
52
|
+
path:"podcast/download/register/"+playerStore.playerPodcast.podcastId + ".mp3",
|
|
53
|
+
parameters:getAudioUrlParameters(),
|
|
54
|
+
headers: {'X-Extra-UA':'Saooti Player'},
|
|
55
|
+
isNotAuth:true
|
|
56
|
+
});
|
|
57
|
+
setDownloadId(response.downloadId.toString());
|
|
58
|
+
audioUrlToPlay.value = response.location;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
watch(()=>playerStore.playerPodcast, async () => {
|
|
62
|
+
reInitPlayer();
|
|
63
|
+
getTranscription();
|
|
64
|
+
}, {deep:true});
|
|
65
|
+
|
|
66
|
+
watch(()=>playerStore.playerLive, async () => {
|
|
67
|
+
if(playerStore.playerVideo){
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
nextTick(async () => {
|
|
71
|
+
hlsReady.value = false;
|
|
72
|
+
reInitPlayer();
|
|
73
|
+
playLive();
|
|
74
|
+
});
|
|
75
|
+
}, {deep:true});
|
|
76
|
+
|
|
77
|
+
watch(()=>playerStore.playerRadio, async () => {
|
|
78
|
+
nextTick(async () => {
|
|
79
|
+
hlsReady.value = false;
|
|
80
|
+
reInitPlayer();
|
|
81
|
+
playRadio();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
watch(()=>playerStore.playerStatus, async () => {
|
|
86
|
+
const audioPlayer: HTMLAudioElement | null =
|
|
87
|
+
document.querySelector("#audio-player");
|
|
88
|
+
if (!audioPlayer) return;
|
|
89
|
+
if (playerStore.playerLive && !hlsReady.value) {
|
|
90
|
+
audioPlayer.pause();
|
|
91
|
+
percentLiveProgress.value = 0;
|
|
92
|
+
durationLivePosition.value = 0;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if ("PAUSED" === playerStore.playerStatus && playerStore.playerRadio) {
|
|
96
|
+
playerStore.playerRadio.dateSessionId = dayjs().toISOString();
|
|
97
|
+
hlsReady.value = false;
|
|
98
|
+
reInitPlayer();
|
|
99
|
+
endingLive();
|
|
100
|
+
} else if ("PAUSED" === playerStore.playerStatus) {
|
|
101
|
+
audioPlayer.pause();
|
|
102
|
+
} else if ("PLAYING" === playerStore.playerStatus && playerStore.playerRadio) {
|
|
103
|
+
if (playerStore.playerRadio.isInit) {
|
|
104
|
+
playRadio();
|
|
105
|
+
} else {
|
|
106
|
+
playerStore.playerRadio.isInit = true;
|
|
107
|
+
}
|
|
108
|
+
} else if ("PLAYING" === playerStore.playerStatus) {
|
|
109
|
+
audioPlayer.play();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
function getAudioUrlParameters(): FetchParam {
|
|
114
|
+
if (!playerStore.playerPodcast) return {};
|
|
115
|
+
const parameters: FetchParam = {
|
|
116
|
+
origin: "octopus",
|
|
117
|
+
accepted: vastStore.useVastPlayerPodcast
|
|
118
|
+
};
|
|
119
|
+
if (authStore.authOrgaId) {
|
|
120
|
+
parameters.distributorId = authStore.authOrgaId;
|
|
121
|
+
}
|
|
122
|
+
if (generalStore.consentTcf) {
|
|
123
|
+
parameters.consent = generalStore.consentTcf;
|
|
124
|
+
}
|
|
125
|
+
if (
|
|
126
|
+
"SECURED" === playerStore.playerPodcast.organisation.privacy &&
|
|
127
|
+
authStore.authParam.accessToken
|
|
128
|
+
) {
|
|
129
|
+
parameters.access_token =authStore.authParam.accessToken;
|
|
130
|
+
}
|
|
131
|
+
return parameters;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function getAudioUrl(): string {
|
|
135
|
+
if (playerStore.playerMedia){
|
|
136
|
+
return playerStore.playerMedia.audioUrl ?? "";
|
|
137
|
+
}
|
|
138
|
+
if (!playerStore.playerPodcast || playerStore.playerVideo) return "";
|
|
139
|
+
if (
|
|
140
|
+
!playerStore.playerPodcast.availability.visibility ||
|
|
141
|
+
"PROCESSING" === playerStore.playerPodcast.processingStatus
|
|
142
|
+
)
|
|
143
|
+
return playerStore.playerPodcast.audioStorageUrl;
|
|
144
|
+
if (listenError.value) return playerStore.playerPodcast.audioStorageUrl;
|
|
145
|
+
return playerStore.playerPodcast.podcastId + ".mp3?"+getAudioUrlParameters().toString();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function reInitPlayer(): void {
|
|
149
|
+
setDownloadId(null);
|
|
150
|
+
listenError.value = false;
|
|
151
|
+
if (playerStore.playerLive || playerStore.playerRadio) {
|
|
152
|
+
endingLive();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function stopPlayer(): void {
|
|
157
|
+
playerStore.playerPlay();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function onError(): void {
|
|
161
|
+
if (
|
|
162
|
+
playerStore.playerPodcast &&
|
|
163
|
+
"" !== audioUrlToPlay.value &&
|
|
164
|
+
!listenError.value
|
|
165
|
+
) {
|
|
166
|
+
listenError.value = true;
|
|
167
|
+
} else if (
|
|
168
|
+
(playerStore.playerPodcast && "" !== audioUrlToPlay.value) ||
|
|
169
|
+
playerStore.playerMedia
|
|
170
|
+
) {
|
|
171
|
+
playerError.value = true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function streamDurationForSafari(mediaTarget: HTMLMediaElement) {
|
|
176
|
+
let streamDuration = mediaTarget.duration;
|
|
177
|
+
if (Infinity === streamDuration) {
|
|
178
|
+
const seekable = mediaTarget.seekable;
|
|
179
|
+
if (seekable) {
|
|
180
|
+
streamDuration = seekable.end(seekable.length - 1);
|
|
181
|
+
} else {
|
|
182
|
+
streamDuration = mediaTarget.currentTime;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return streamDuration;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function onTimeUpdatePodcast(streamDuration: number, currentTime: number) {
|
|
189
|
+
displayAlertBar.value = false;
|
|
190
|
+
percentLiveProgress.value = 0;
|
|
191
|
+
playerStore.playerUpdateElapsed(currentTime / streamDuration, streamDuration);
|
|
192
|
+
onTimeUpdateTranscript(currentTime);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function onTimeUpdateLive(streamDuration: number, currentTime: number) {
|
|
196
|
+
if (!playerStore.playerLive) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const scheduledDuration = playerStore.playerLive.duration / 1000;
|
|
200
|
+
if (scheduledDuration > streamDuration) {
|
|
201
|
+
displayAlertBar.value = false;
|
|
202
|
+
percentLiveProgress.value = (streamDuration / scheduledDuration) * 100;
|
|
203
|
+
playerStore.playerUpdateElapsed(
|
|
204
|
+
currentTime / scheduledDuration,
|
|
205
|
+
scheduledDuration,
|
|
206
|
+
);
|
|
207
|
+
} else {
|
|
208
|
+
percentLiveProgress.value = 100;
|
|
209
|
+
displayAlertBar.value = true;
|
|
210
|
+
durationLivePosition.value = (scheduledDuration / streamDuration) * 100;
|
|
211
|
+
playerStore.playerUpdateElapsed(currentTime / streamDuration, streamDuration);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function onTimeUpdate(event: Event): void {
|
|
216
|
+
if (playerStore.playerRadio) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const mediaTarget = event.currentTarget as HTMLMediaElement;
|
|
220
|
+
if (playerStore.playerPodcast || playerStore.playerLive) {
|
|
221
|
+
onTimeUpdateProgress(mediaTarget.currentTime);
|
|
222
|
+
}
|
|
223
|
+
const streamDuration = streamDurationForSafari(mediaTarget);
|
|
224
|
+
if (!streamDuration) return;
|
|
225
|
+
if (!mediaTarget.currentTime) return;
|
|
226
|
+
if (!playerStore.playerLive) {
|
|
227
|
+
onTimeUpdatePodcast(streamDuration, mediaTarget.currentTime);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
onTimeUpdateLive(streamDuration, mediaTarget.currentTime);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function onSeeked(event: Event): void {
|
|
234
|
+
const mediaTarget = event.currentTarget as HTMLMediaElement;
|
|
235
|
+
const currentTime = mediaTarget.currentTime;
|
|
236
|
+
onSeekedTranscript(currentTime);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function onFinished(): void {
|
|
240
|
+
setDownloadId(null);
|
|
241
|
+
contentEndedAdsLoader();
|
|
242
|
+
if (playerStore.playerLive) {
|
|
243
|
+
endingLive();
|
|
244
|
+
}
|
|
245
|
+
forceHide.value = true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
audioUrlToPlay,
|
|
251
|
+
listenTime,
|
|
252
|
+
playerError,
|
|
253
|
+
percentLiveProgress,
|
|
254
|
+
durationLivePosition,
|
|
255
|
+
displayAlertBar,
|
|
256
|
+
hlsReady,
|
|
257
|
+
checkDelaytWithStitching,
|
|
258
|
+
stopPlayer,
|
|
259
|
+
onError,
|
|
260
|
+
onTimeUpdate,
|
|
261
|
+
onSeeked,
|
|
262
|
+
onFinished,
|
|
263
|
+
onPlay
|
|
264
|
+
}
|
|
265
|
+
}
|