@christianriedl/media 1.0.300 → 1.0.301

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/dist/iMedia.d.ts CHANGED
@@ -317,3 +317,41 @@ export interface IMediaService {
317
317
  getCloudUrl(folder: string, name: string): Promise<string>;
318
318
  getStatus(): Promise<Dictionary<boolean | number | string> | null>;
319
319
  }
320
+ export interface IRssFeed {
321
+ title: string;
322
+ description: string;
323
+ link: string;
324
+ copyright?: string;
325
+ items?: IRssFeed[];
326
+ mediaType?: string;
327
+ duration?: number;
328
+ }
329
+ export declare const getPlaylistSymbol: InjectionKey<() => IPlaylistService>;
330
+ export declare enum EPlaylistCommand {
331
+ None = 0,
332
+ Play = 1,
333
+ Pause = 2,
334
+ Resume = 3,
335
+ Stop = 4,
336
+ Next = 5,
337
+ Previous = 6
338
+ }
339
+ export interface IPlaylistState {
340
+ state: string;
341
+ device: string;
342
+ title: string;
343
+ url: string;
344
+ position: string;
345
+ }
346
+ export interface IPlaylistService {
347
+ soundbarOn: boolean;
348
+ getTitles(): Promise<string[]>;
349
+ getFeed(title: string): Promise<IRssFeed | null>;
350
+ getFeeds(): Promise<IRssFeed[]>;
351
+ addFeed(url: string, save: boolean): Promise<IRssFeed | null>;
352
+ deleteFeed(title: string): Promise<boolean>;
353
+ play(url: string): Promise<boolean>;
354
+ playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
355
+ playCommand(cmd: EPlaylistCommand): Promise<boolean>;
356
+ getState(): Promise<IPlaylistState | null>;
357
+ }
package/dist/iMedia.js CHANGED
@@ -121,4 +121,15 @@ export var EPictureFlags;
121
121
  EPictureFlags[EPictureFlags["Mask"] = 240] = "Mask";
122
122
  })(EPictureFlags || (EPictureFlags = {}));
123
123
  export const getMediaSymbol = Symbol("get-media");
124
+ export const getPlaylistSymbol = Symbol("get-playlist");
125
+ export var EPlaylistCommand;
126
+ (function (EPlaylistCommand) {
127
+ EPlaylistCommand[EPlaylistCommand["None"] = 0] = "None";
128
+ EPlaylistCommand[EPlaylistCommand["Play"] = 1] = "Play";
129
+ EPlaylistCommand[EPlaylistCommand["Pause"] = 2] = "Pause";
130
+ EPlaylistCommand[EPlaylistCommand["Resume"] = 3] = "Resume";
131
+ EPlaylistCommand[EPlaylistCommand["Stop"] = 4] = "Stop";
132
+ EPlaylistCommand[EPlaylistCommand["Next"] = 5] = "Next";
133
+ EPlaylistCommand[EPlaylistCommand["Previous"] = 6] = "Previous";
134
+ })(EPlaylistCommand || (EPlaylistCommand = {}));
124
135
  //# sourceMappingURL=iMedia.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"iMedia.js","sourceRoot":"","sources":["../src/iMedia.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"iMedia.js","sourceRoot":"","sources":["../src/iMedia.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './mediaHelper';
4
4
  export * from './locationHelper';
5
5
  export * from './mediaInstanceService';
6
6
  export * from './playerService';
7
+ export * from './playlistService';
7
8
  export * from './mediaServiceBin';
8
9
  export * from './iBooks';
9
10
  export * from './booksService';
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ export * from './mediaHelper';
5
5
  export * from './locationHelper';
6
6
  export * from './mediaInstanceService';
7
7
  export * from './playerService';
8
+ export * from './playlistService';
8
9
  export * from './mediaServiceBin';
9
10
  export * from './iBooks';
10
11
  export * from './booksService';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,iCAAiC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,iCAAiC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { IRest } from '@christianriedl/rest';
2
+ import { ILogger } from '@christianriedl/utils';
3
+ import { IRssFeed, EPlaylistCommand, IPlaylistState, IPlaylistService } from "./iMedia";
4
+ export declare class PlaylistService implements IPlaylistService {
5
+ rest: IRest;
6
+ mediaUrl: string;
7
+ log: ILogger;
8
+ soundbarOn: boolean;
9
+ setSoundbar: (name: string, value: string) => Promise<boolean>;
10
+ getSoundbarValue: (name: string) => string;
11
+ constructor(rest: IRest, log: ILogger, getSoundbarValue: (name: string) => string, setSoundbar: (name: string, value: string) => Promise<boolean>);
12
+ getTitles(): Promise<string[]>;
13
+ getFeed(title: string): Promise<IRssFeed | null>;
14
+ getFeeds(): Promise<IRssFeed[]>;
15
+ addFeed(url: string, save: boolean): Promise<IRssFeed | null>;
16
+ deleteFeed(title: string): Promise<boolean>;
17
+ play(url: string): Promise<boolean>;
18
+ playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
19
+ playCommand(cmd: EPlaylistCommand): Promise<boolean>;
20
+ getState(): Promise<IPlaylistState | null>;
21
+ ensureOn(): Promise<boolean>;
22
+ }
@@ -0,0 +1,86 @@
1
+ import { Helper } from '@christianriedl/utils';
2
+ import { EPlaylistCommand } from "./iMedia";
3
+ export class PlaylistService {
4
+ rest;
5
+ mediaUrl;
6
+ log;
7
+ soundbarOn;
8
+ setSoundbar;
9
+ getSoundbarValue;
10
+ constructor(rest, log, getSoundbarValue, setSoundbar) {
11
+ this.log = log;
12
+ this.rest = rest;
13
+ this.mediaUrl = rest.serviceUrl;
14
+ this.getSoundbarValue = getSoundbarValue;
15
+ this.setSoundbar = setSoundbar;
16
+ this.soundbarOn = false;
17
+ }
18
+ async getTitles() {
19
+ const res = await this.rest.getData('apiplaylist/title');
20
+ return res.ok ? res.result : [];
21
+ }
22
+ async getFeed(title) {
23
+ const res = await this.rest.getData('apiplaylist/feed', { title: title });
24
+ return res.ok ? res.result : null;
25
+ }
26
+ async getFeeds() {
27
+ const res = await this.rest.getData('apiplaylist/feed');
28
+ return res.ok ? res.result : [];
29
+ }
30
+ async addFeed(url, save) {
31
+ const res = await this.rest.postDataEx(`apiplaylist/feed?url=${encodeURIComponent(url)}&save=${save}`);
32
+ return res.ok ? res.result.result : null;
33
+ }
34
+ async deleteFeed(title) {
35
+ const res = await this.rest.deleteData(`apiplaylist/feed?title=${encodeURIComponent(title)}`);
36
+ return res.ok ? res.result : false;
37
+ }
38
+ async play(url) {
39
+ this.soundbarOn = await this.ensureOn();
40
+ if (!this.soundbarOn)
41
+ return false;
42
+ const res = await this.rest.postData(`apiplaylist/play?url=${encodeURIComponent(url)}`);
43
+ return res.ok ? res.result : false;
44
+ }
45
+ async playList(urls, clear, index) {
46
+ this.soundbarOn = await this.ensureOn();
47
+ if (!this.soundbarOn)
48
+ return false;
49
+ let url = `apiplaylist/play?clear=${clear}`;
50
+ if (index !== undefined)
51
+ url += `&index=${index}`;
52
+ const res = await this.rest.postData(url, urls);
53
+ return res.ok ? res.result : false;
54
+ }
55
+ async playCommand(cmd) {
56
+ this.soundbarOn = await this.ensureOn();
57
+ if (!this.soundbarOn)
58
+ return false;
59
+ let url = `apiplaylist/playcommand?cmd=${EPlaylistCommand[cmd]}`;
60
+ const res = await this.rest.postData(url);
61
+ return res.ok ? res.result : false;
62
+ }
63
+ async getState() {
64
+ const res = await this.rest.getData('apiplaylist/state');
65
+ return res.ok ? res.result : null;
66
+ }
67
+ async ensureOn() {
68
+ let i = 0;
69
+ for (i = 0; i < 5; i++) {
70
+ if (this.getSoundbarValue('ON') === 'ON')
71
+ break;
72
+ const result = await this.setSoundbar('POWER', 'on');
73
+ await Helper.delay(1000);
74
+ }
75
+ if (i >= 5)
76
+ return false;
77
+ for (i = 0; i < 5; i++) {
78
+ if (this.getSoundbarValue('Info') === 'digital')
79
+ return true;
80
+ const result = await this.setSoundbar('SOURCE', 'digital');
81
+ await Helper.delay(1000);
82
+ }
83
+ return false;
84
+ }
85
+ }
86
+ //# sourceMappingURL=playlistService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playlistService.js","sourceRoot":"","sources":["../src/playlistService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@christianriedl/media",
3
- "version": "1.0.300",
3
+ "version": "1.0.301",
4
4
  "description": "RIC media interfaces",
5
5
 
6
6
  "main": "dist/index.js",
@@ -0,0 +1,171 @@
1
+ <script setup lang="ts">
2
+ import { inject, ref, reactive, computed, onMounted, onUnmounted, nextTick, watch, StyleValue } from 'vue';
3
+ import type { ComponentPublicInstance } from 'vue';
4
+ import { useRouter } from 'vue-router';
5
+ import { IAppState, EScope, EDevice, appStateSymbol, appConfigSymbol } from '@christianriedl/utils';
6
+ import { getPlaylistSymbol, IPlaylistService, IPlaylistState, IRssFeed } from '@christianriedl/media';
7
+
8
+ const appState = inject(appStateSymbol)!;
9
+ const getPlaylistService = inject(getPlaylistSymbol)!;
10
+ const playlistService = getPlaylistService() ;
11
+ const heightStyle = computed<StyleValue>(() => { return { height: appState.bodyHeight.value + 'px', overflowY: 'auto' } });
12
+ const isMobile = appState.isMobile && (appState.device != EDevice.iPad);
13
+ const router = useRouter();
14
+ const feeds: IRssFeed[] = reactive([]);
15
+ const selected = ref<IRssFeed|null>(null);
16
+ const status = ref<IPlaylistState|null>(null);
17
+ const audio = ref<HTMLAudioElement | null>(null);
18
+ const listhead = ref<ComponentPublicInstance | null>(null);
19
+ const listHeight = ref(0);
20
+ const playerNames = ['Local', 'Soundbar'];
21
+ const currentPlayer = ref<string>(playerNames[0]);
22
+ const playLocal = computed(() => currentPlayer.value == 'Local');
23
+ const playIndex = ref(-1);
24
+ const playingFeed = ref<IRssFeed|null>(null);
25
+ const position = ref(0);
26
+ const positionLength = ref(0);
27
+ let statusTimer = 0;
28
+
29
+
30
+
31
+ onMounted(async () => {
32
+ playlistService.log.info('OnlineBroadcast created');
33
+ const f = await playlistService.getFeeds();
34
+ feeds.splice(0, feeds.length, ...f);
35
+ computeListHeight();
36
+ });
37
+ onUnmounted(() => {
38
+ if (statusTimer > 0) {
39
+ clearTimeout(statusTimer);
40
+ statusTimer = 0;
41
+ }
42
+ });
43
+
44
+ function computeListHeight() {
45
+ nextTick(() => {
46
+ let height = appState.bodyHeight.value;
47
+ if (listhead.value) {
48
+ height = height - (listhead.value.$el as HTMLElement).clientHeight;
49
+ }
50
+ listHeight.value = height;
51
+ })
52
+ }
53
+ async function play() {
54
+ if (playLocal.value) {
55
+ audio.value!.src = selected.value.link;
56
+ audio.value!.load();
57
+ await audio.value!.play();
58
+ playlistService.log.trace(`play local ${selected.value.title}`)
59
+ }
60
+ else {
61
+ const rc = await playlistService.play(selected.value.link);
62
+ if (!rc)
63
+ return;
64
+ await getStatus();
65
+ playlistService.log.trace(`play remote ${selected.value.title}`)
66
+ }
67
+ playingFeed.value = selected.value;
68
+ playIndex.value = feeds.findIndex((f) => f.link == selected.value.link);
69
+ }
70
+ function listItem(item: IRssFeed) {
71
+ selected.value = item;
72
+ computeListHeight();
73
+ }
74
+ function listBack() {
75
+ router.back();
76
+ }
77
+ async function getStatus() {
78
+ const status = await playlistService.getStatus();
79
+ status.value = status;
80
+ setPosition(status.position.toNumber());
81
+ statusTimer = setTimeout(async () => getStatus(), 1000);
82
+ }
83
+
84
+ function toSubTitle(f: IRssFeed): string {
85
+ if (!f.duration)
86
+ return "";
87
+ let s = f.duration;
88
+ var r = "";
89
+ s = Math.floor(s);
90
+ if (s >= 3600) {
91
+ r += Math.floor(s / 3600).toString() + ":"; s = s % 3600;
92
+ }
93
+ if (!r || s >= 600) {
94
+ r += Math.floor(s / 60).toString() + ":"; s = s % 60;
95
+ }
96
+ else {
97
+ r += "0"; r += Math.floor(s / 60).toString() + ":"; s = s % 60;
98
+ }
99
+ if (s >= 10) {
100
+ r += s.toString(); s = -1;
101
+ }
102
+ else if (s >= 0) {
103
+ r += "0"; r += s.toString();
104
+ s = -1;
105
+ }
106
+ return r;
107
+ }
108
+ function onEnded() {
109
+ }
110
+ function onTimeUpdate() {
111
+ setPosition(audio.value!.currentTime);
112
+ }
113
+ function setPosition(value: number) {
114
+ position.value = value;
115
+ if (playingFeed.value && playingFeed.value.duration > 0)
116
+ positionLength.value = position.value * 100 / playingFeed.value.duration;
117
+ else
118
+ positionLength.value = 0;
119
+ }
120
+
121
+ </script>
122
+
123
+ <template>
124
+ <v-card ref="listhead" class="bg-media_head">
125
+ <audio ref="audio" preload="none" @ended="onEnded" @timeupdate="onTimeUpdate">
126
+ </audio>
127
+ <v-list-item lines="three">
128
+ <v-list-item-content>
129
+ <v-list-item-title text-h6>{{selected.title}}</v-list-item-title>
130
+ <v-list-item-subtitle>{{toSubTitle(selected)}}</v-list-item-subtitle>
131
+ </v-list-item-content>
132
+ <template v-slot:append>
133
+ <v-select v-model="currentPlayer"
134
+ :items="playerNames"
135
+ persistent-hint
136
+ @update:modelValue="onPlayerChange"
137
+ hide-details single-line>
138
+ </v-select>
139
+ </template>
140
+ </v-list-item>
141
+ <v-card-actions>
142
+ <v-btn v-if="backVisible" @click="listBack">
143
+ <v-icon icon="$back" />
144
+ </v-btn>
145
+ <v-btn size="small" v-if="playingTrack" @click="playpause">
146
+ <v-icon v-if="paused" icon="$play" />
147
+ <v-icon v-else icon="$pause" />
148
+ </v-btn>
149
+ <v-btn size="small" v-if="playingTrack" @click="previous">
150
+ <v-icon icon="$prev" />
151
+ </v-btn>
152
+ <v-btn size="small" v-if="playingTrack" @click="next">
153
+ <v-icon icon="$next" />
154
+ </v-btn>
155
+ <v-slider v-if="!isLocal && playingTrack" style="width:30%" color="red" track-color="blue" track-fill-color="red" v-model="volume" hide-details density="compact"
156
+ min="0" max="100" step="5" @update:modelValue="changeVolume">
157
+ </v-slider>
158
+ </v-card-actions>
159
+ <v-progress-linear v-if="playingTrack" v-model="positionLength" color="blue" height="25"><strong>{{positionText}}</strong></v-progress-linear>
160
+ </v-card>
161
+ <v-card :height="listHeight" density="compact" class="overflow-y-auto bg-media">
162
+ <v-list lines="two" class="bg-media">
163
+ <v-list-item-group v-model="itemIndex">
164
+ <v-list-item v-for="(item,index) in items" :key="item.title" density="compact" :title="item.title" :subtitle="toSubTitle(item)"
165
+ active-color="blue" :active="index == playIndex" @click="listItem(item)">
166
+ </v-list-item>
167
+ </v-list-item-group>
168
+ </v-list>
169
+ </v-card>
170
+ </template>
171
+
@@ -67,11 +67,12 @@
67
67
  mimeType = 'image/png';
68
68
  else if (url.includes('.jpg') || url.includes('.jpeg'))
69
69
  mimeType = 'image/jpeg';
70
+ if (mimeType)
71
+ return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
72
+ else
73
+ return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}`;
70
74
  }
71
- if (mimeType)
72
- return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
73
- else
74
- return `${mediaService.mediaUrl}apistream/stream?url=${encodeURIComponent(url)}`;
75
+ return `${mediaService.mediaUrl}apistream/stream?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
75
76
  }
76
77
  function listItem(item: IMediaItem) {
77
78
  if (item.itemType == EItemType.AudioTrack || item.itemType == EItemType.AudioBroadcast) {
@@ -91,11 +91,12 @@
91
91
  mimeType = 'image/png';
92
92
  else if (url.includes('.jpg') || url.includes('.jpeg'))
93
93
  mimeType = 'image/jpeg';
94
+ if (mimeType)
95
+ return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
96
+ else
97
+ return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}`;
94
98
  }
95
- if (mimeType)
96
- return `${mediaService.mediaUrl}apiimage/cachedimage?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
97
- else
98
- return `${mediaService.mediaUrl}apistream/stream?url=${encodeURIComponent(url)}`;
99
+ return `${mediaService.mediaUrl}apistream/stream?url=${encodeURIComponent(url)}&mimeType=${encodeURIComponent(mimeType)}`;
99
100
  }
100
101
  async function listItem(item: IMediaItem) {
101
102
  if (item.itemType == EItemType.VideoItem || item.itemType == EItemType.VideoBroadcast) {