@saooti/octopus-sdk 39.0.4 → 39.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saooti/octopus-sdk",
3
- "version": "39.0.4",
3
+ "version": "39.0.6",
4
4
  "private": false,
5
5
  "description": "Javascript SDK for using octopus",
6
6
  "author": "Saooti",
package/src/App.vue CHANGED
@@ -1,14 +1,15 @@
1
1
  <template>
2
- <!-- v-if="isInit" -->
3
- <div :key="reload" class="d-flex flex-column h-100 octopus-app">
4
- <TopBar :is-education="false" />
5
- <CategoryFilter v-if="firstDisplayCategoryFilter" />
6
- <div v-else class="category-filter-no-filter" />
7
- <router-view />
8
- <ClassicLazy v-if="pageFullyLoad" :min-height="125">
9
- <FooterOctopus />
10
- </ClassicLazy>
11
- <PlayerComponent />
2
+ <div class="d-flex flex-column h-100 octopus-app">
3
+ <template v-if="pageFullyLoad">
4
+ <TopBar :is-education="false" />
5
+ <CategoryFilter v-if="firstDisplayCategoryFilter" />
6
+ <div v-else class="category-filter-no-filter" />
7
+ <router-view />
8
+ <ClassicLazy :min-height="125">
9
+ <FooterOctopus />
10
+ </ClassicLazy>
11
+ <PlayerComponent />
12
+ </template>
12
13
  </div>
13
14
  </template>
14
15
 
@@ -48,7 +49,6 @@ export default defineComponent({
48
49
  data() {
49
50
  return {
50
51
  reload: false as boolean,
51
- isInit: false as boolean,
52
52
  pageFullyLoad: false as boolean,
53
53
  firstDisplayCategoryFilter: false as boolean,
54
54
  };
@@ -98,7 +98,6 @@ export default defineComponent({
98
98
  await this.handleOrganisationFilter();
99
99
  this.handleIabIdFilter();
100
100
  this.handleRubriquesFilter();
101
- this.isInit = true;
102
101
  },
103
102
  async handleOrganisationFilter() {
104
103
  let orgaId = "";
@@ -48,6 +48,7 @@
48
48
  target="_blank"
49
49
  class="octopus-dropdown-item justify-content-start"
50
50
  :href="link.url"
51
+ realLink="true"
51
52
  >
52
53
  <span :class="link.icon" class="me-1" /> {{ link.title }}
53
54
  </a>
@@ -17,6 +17,7 @@
17
17
  @error="onError"
18
18
  @seeked="onSeeked"
19
19
  @pause="onPause"
20
+ @loadedmetadata="checkDelaytWithStitching"
20
21
  />
21
22
  <div id="ad-container"></div>
22
23
  <template v-if="displayWithTimeout">
@@ -1,4 +1,5 @@
1
1
  import { state } from "../../../stores/ParamSdkStore";
2
+ import dayjs from "dayjs";
2
3
  import { playerLogicProgress} from "./playerLogicProgress";
3
4
  import { usePlayerStore } from "@/stores/PlayerStore";
4
5
  import { useAuthStore } from "@/stores/AuthStore";
@@ -6,6 +7,7 @@ import { mapState, mapActions } from "pinia";
6
7
  /* eslint-disable */
7
8
  let Hls:any = null;
8
9
  /* eslint-enable */
10
+ const maxMinutesSessionId = 1;
9
11
  import { defineComponent } from "vue";
10
12
  export const playerLive = defineComponent({
11
13
  mixins: [playerLogicProgress],
@@ -31,7 +33,20 @@ export const playerLive = defineComponent({
31
33
  },
32
34
  playRadio() {
33
35
  if (!this.playerRadio) return;
34
- this.playHls(this.playerRadio.url);
36
+ this.handleSessionIdRadio();
37
+ this.playHls(this.playerRadio.url+"?origin=octopus&sessionId="+this.playerRadio.sessionId);
38
+ },
39
+ handleSessionIdRadio(){
40
+ if(!this.playerRadio) return;
41
+ if(this.playerRadio.sessionId && dayjs().diff(dayjs(this.playerRadio.dateSessionId), 'm')<maxMinutesSessionId){
42
+ return;
43
+ }
44
+ this.playerRadio.sessionId = this.uuidv4();
45
+ },
46
+ uuidv4() {
47
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
48
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
49
+ );
35
50
  },
36
51
  playLive() {
37
52
  if (!this.playerLive) return;
@@ -12,6 +12,7 @@ import { usePlayerStore } from "@/stores/PlayerStore";
12
12
  import { mapState, mapActions } from "pinia";
13
13
  import { FetchParam } from "@/stores/class/general/fetchParam";
14
14
  import { useVastStore } from "@/stores/VastStore";
15
+ import dayjs from "dayjs";
15
16
  export const playerLogic = defineComponent({
16
17
  mixins: [cookies, playerLive, playerComment, playerTranscript, playerStitching],
17
18
  data() {
@@ -114,6 +115,7 @@ export const playerLogic = defineComponent({
114
115
  return;
115
116
  }
116
117
  if ("PAUSED" === this.playerStatus && this.playerRadio) {
118
+ this.playerRadio.dateSessionId = dayjs().toISOString();
117
119
  this.hlsReady = false;
118
120
  this.reInitPlayer();
119
121
  this.endingLive();
@@ -58,7 +58,6 @@ export const playerStitching = defineComponent({
58
58
  return this.useVastPlayerPodcast;
59
59
  },
60
60
  defineRadioInterval(){
61
- //TODO remove tag en dur
62
61
  this.clearRadioInterval();
63
62
  const timeRemaining = dayjs(this.radioNextAdvertisingStartDate).diff(dayjs(), "millisecond");
64
63
  console.log("TimeRemaining "+timeRemaining);
@@ -66,6 +65,8 @@ export const playerStitching = defineComponent({
66
65
  return;
67
66
  }
68
67
  this.radioInterval = setTimeout(() => {
68
+ //If pause when ad needs to be played then skipped (TO THINK)
69
+ if("PAUSED"===this.playerStatus){return;}
69
70
  this.onRequestAd(this.getVastUrl(this.playerRadio?.nextAdvertising?.tag ??"5e385e1b51c86"));
70
71
  }, timeRemaining);
71
72
  },
@@ -2,13 +2,36 @@ import octopusApi from "@saooti/octopus-api";
2
2
  import { defineComponent } from "vue";
3
3
  import { usePlayerStore } from "@/stores/PlayerStore";
4
4
  import { mapState, mapActions } from "pinia";
5
+ import { AdserverOtherEmission } from "@/stores/class/adserver/adserverOtherEmission";
6
+ import { useVastStore } from "@/stores/VastStore";
5
7
  export const playerTranscript = defineComponent({
6
8
  computed: {
7
- ...mapState(usePlayerStore, ["playerTranscript", "playerPodcast"]),
9
+ ...mapState(usePlayerStore, ["playerTranscript", "playerPodcast", "playerDelayStitching"]),
10
+ ...mapState(useVastStore, ["useVastPlayerPodcast"]),
8
11
  },
9
12
  methods: {
10
- ...mapActions(usePlayerStore, ["playerUpdateTranscript", "playerUpdateChaptering"]),
11
-
13
+ ...mapActions(usePlayerStore, ["playerUpdateTranscript", "playerUpdateChaptering", "playerUpdateDelayStitching"]),
14
+ async checkDelaytWithStitching(){
15
+ this.playerUpdateDelayStitching(0);
16
+ if(this.useVastPlayerPodcast){return;}
17
+ const audioPlayer = document.querySelector("#audio-player") as HTMLAudioElement;
18
+ if (!this.playerTranscript || !audioPlayer || !this.playerPodcast ||
19
+ audioPlayer.duration <= this.playerPodcast.duration / 1000 + 5)
20
+ {
21
+ return;
22
+ }
23
+ let adserverConfig = await octopusApi.fetchDataPublic<AdserverOtherEmission>(0,`ad/test/podcast/${this.playerPodcast.podcastId}`);
24
+ const doubletsLength = adserverConfig.config.doublets.length;
25
+ if(1=== doubletsLength && "pre" === adserverConfig.config.doublets[0].timing.insertion){
26
+ this.playerUpdateDelayStitching( audioPlayer.duration - (this.playerPodcast.duration / 1000));
27
+ }else if(0===doubletsLength || 1=== doubletsLength && "post" === adserverConfig.config.doublets[0].timing.insertion){
28
+ return;
29
+ }else{
30
+ // todo remove chaptering
31
+ this.playerUpdateChaptering();
32
+ this.playerUpdateTranscript();
33
+ }
34
+ },
12
35
  async getTranscription(): Promise<void> {
13
36
  if (!this.playerPodcast) {
14
37
  this.playerUpdateTranscript();
@@ -59,12 +82,12 @@ export const playerTranscript = defineComponent({
59
82
  if(!this.playerTranscript?.value.length){
60
83
  return;
61
84
  }
62
- const startTime = (this.playerTranscript.value[this.playerTranscript.actual]?.startTime ?? 0);
85
+ const startTime = (this.playerTranscript.value[this.playerTranscript.actual]?.startTime ?? 0) + this.playerDelayStitching;
63
86
  if (startTime <= currentTime) {
64
87
  this.playerTranscript.actualText = this.playerTranscript.value[this.playerTranscript?.actual]?.text ??"";
65
88
  }
66
89
  if (
67
- (this.playerTranscript.value[this.playerTranscript.actual]?.endTime ??Infinity) < currentTime
90
+ (this.playerTranscript.value[this.playerTranscript.actual]?.endTime ??Infinity) + this.playerDelayStitching< currentTime
68
91
  ) {
69
92
  this.playerTranscript.actual += 1;
70
93
  this.playerTranscript.actualText =
@@ -76,7 +99,7 @@ export const playerTranscript = defineComponent({
76
99
  onSeekedTranscript(currentTime: number) {
77
100
  if (this.playerTranscript) {
78
101
  let newActual = 0;
79
- while (currentTime >(this.playerTranscript.value[newActual]?.endTime ?? Infinity)) {
102
+ while (currentTime >(this.playerTranscript.value[newActual]?.endTime ?? Infinity) + this.playerDelayStitching) {
80
103
  newActual += 1;
81
104
  }
82
105
  this.playerTranscript.actual = newActual;
@@ -31,7 +31,10 @@ export const fetchRadioData = defineComponent({
31
31
  );
32
32
  if(callbackAdvertising){
33
33
  //TODO remove mock
34
- //callbackAdvertising("2024-03-12T15:25:00Z");
34
+ /* callbackAdvertising({
35
+ startDate: "2024-03-25T08:21:00Z",
36
+ tag: "5e385e1b51c86"
37
+ }); */
35
38
  callbackAdvertising(metadata.nextAdvertising);
36
39
  }
37
40
  const arrayMetadata = metadata.previously;
@@ -44,22 +44,24 @@
44
44
  :podcast="podcast"
45
45
  :organisation-id="podcast.organisation.id"
46
46
  />
47
- <ClassicLazy :min-height="550">
48
- <PodcastInlineList
49
- class="mt-4"
50
- :podcast-id="podcastId"
51
- :title="$t('Suggested listening')"
52
- />
53
- </ClassicLazy>
54
- <ClassicLazy v-for="c in categories" :key="c.id" :min-height="550">
55
- <PodcastInlineList
56
- class="mt-4"
57
- :iab-id="c.id"
58
- :href="'/main/pub/category/' + c.id"
59
- :title="$t('More episodes of this category : ', { name: c.name })"
60
- :button-text="$t('All podcast button', { name: c.name })"
61
- />
62
- </ClassicLazy>
47
+ <template v-if="!hideSuggestions">
48
+ <ClassicLazy :min-height="550">
49
+ <PodcastInlineList
50
+ class="mt-4"
51
+ :podcast-id="podcastId"
52
+ :title="$t('Suggested listening')"
53
+ />
54
+ </ClassicLazy>
55
+ <ClassicLazy v-for="c in categories" :key="c.id" :min-height="550">
56
+ <PodcastInlineList
57
+ class="mt-4"
58
+ :iab-id="c.id"
59
+ :href="'/main/pub/category/' + c.id"
60
+ :title="$t('More episodes of this category : ', { name: c.name })"
61
+ :button-text="$t('All podcast button', { name: c.name })"
62
+ />
63
+ </ClassicLazy>
64
+ </template>
63
65
  </div>
64
66
  </template>
65
67
  <ClassicLoading
@@ -144,6 +146,14 @@ export default defineComponent({
144
146
 
145
147
  computed: {
146
148
  ...mapState(useGeneralStore, ["storedCategories"]),
149
+ hideSuggestions(): boolean {
150
+ return (
151
+ "true" ===
152
+ (this.podcast?.emission?.annotations?.["HIDE_SUGGESTIONS"] as
153
+ | string
154
+ | undefined)
155
+ );
156
+ },
147
157
  isComments(): boolean {
148
158
  if (!this.podcast) return true;
149
159
  let podcastComment = "INHERIT";
@@ -13,7 +13,7 @@ const state: ParamStore = {
13
13
  isProduction: true,
14
14
  isContribution: true,
15
15
  isRadio: true,
16
- ApiUri: "https://api.staging.saooti.org/",
16
+ ApiUri: "https://api.dev2.saooti.org/",
17
17
  podcastmaker: false,
18
18
  buttonPlus: true,
19
19
  allCategories: [],
@@ -27,8 +27,8 @@ const state: ParamStore = {
27
27
  SharePlayer: true,
28
28
  ShareButtons: true,
29
29
  ShareDistribution: true,
30
- MiniplayerUri: "https://playerbeta.staging.saooti.org/",
31
- hlsUri: "https://hls.live.staging.saooti.org/",
30
+ MiniplayerUri: "https://playerbeta.dev2.saooti.org/",
31
+ hlsUri: "https://hls.live.dev2.saooti.org/",
32
32
  mainRubrique: 0,
33
33
  resourceUrl: undefined,
34
34
  podcastItemShowEmission: false,
@@ -80,14 +80,14 @@ const state: ParamStore = {
80
80
  userName: "",
81
81
  },
82
82
  octopusApi: {
83
- url: "https://api.staging.saooti.org/",
84
- commentsUrl: "https://comments.staging.saooti.org/",
85
- imageUrl: "https://imageproxy.staging.saooti.org/",
86
- studioUrl: "https://studio.staging.saooti.org/",
87
- playerUrl: "https://playerbeta.staging.saooti.org/",
88
- speechToTextUrl: "https://speech2text.staging.saooti.org/",
89
- radioUrl:"https://radio.staging.saooti.org/",
90
- recoUrl: "https://reco.staging.saooti.org/",
83
+ url: "https://api.dev2.saooti.org/",
84
+ commentsUrl: "https://comments.dev2.saooti.org/",
85
+ imageUrl: "https://imageproxy.dev2.saooti.org/",
86
+ studioUrl: "https://studio.dev2.saooti.org/",
87
+ playerUrl: "https://playerbeta.dev2.saooti.org/",
88
+ speechToTextUrl: "https://speech2text.dev2.saooti.org/",
89
+ radioUrl:"https://radio.dev2.saooti.org/",
90
+ recoUrl: "https://reco.dev2.saooti.org/",
91
91
  organisationId: undefined,
92
92
  rubriqueIdFilter: undefined,
93
93
  },
@@ -26,6 +26,7 @@ interface PlayerState {
26
26
  playerLargeVersion: boolean;
27
27
  playerVideo: boolean;
28
28
  playerChaptering?: Chaptering;
29
+ playerDelayStitching: number;
29
30
  }
30
31
  export const usePlayerStore = defineStore("PlayerStore", {
31
32
  state: (): PlayerState => ({
@@ -42,6 +43,7 @@ export const usePlayerStore = defineStore("PlayerStore", {
42
43
  playerLargeVersion: false,
43
44
  playerVideo: false,
44
45
  playerChaptering: undefined,
46
+ playerDelayStitching:0,
45
47
  }),
46
48
  getters: {
47
49
  playerChapteringPercent(): ChapteringPercent|undefined{
@@ -230,6 +232,9 @@ export const usePlayerStore = defineStore("PlayerStore", {
230
232
  },
231
233
  playerUpdateChaptering(chaptering?: Chaptering){
232
234
  this.playerChaptering = chaptering;
233
- }
235
+ },
236
+ playerUpdateDelayStitching(delay: number){
237
+ this.playerDelayStitching = delay;
238
+ },
234
239
  },
235
240
  });
@@ -9,6 +9,8 @@ export interface Radio {
9
9
  nextAdvertising:NextAdvertising;
10
10
  isInit: boolean;
11
11
  podcast?: Podcast;
12
+ sessionId?: string;
13
+ dateSessionId?:string;
12
14
  }
13
15
  export interface MediaRadio {
14
16
  artist: string;