@christianriedl/media 1.0.302 → 1.0.303
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 +24 -9
- package/dist/iMedia.js +12 -0
- package/dist/iMedia.js.map +1 -1
- package/dist/playlistService.d.ts +5 -8
- package/dist/playlistService.js +26 -15
- package/dist/playlistService.js.map +1 -1
- package/package.json +1 -1
- package/src/views/OnlinePodcastsPage.vue +189 -36
package/dist/iMedia.d.ts
CHANGED
|
@@ -317,15 +317,33 @@ 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
|
|
320
|
+
export interface IRssItem {
|
|
321
321
|
title: string;
|
|
322
|
-
description
|
|
322
|
+
description?: string;
|
|
323
323
|
link: string;
|
|
324
|
-
copyright?: string;
|
|
325
|
-
items?: IRssFeed[];
|
|
326
324
|
mediaType?: string;
|
|
327
325
|
duration?: number;
|
|
328
326
|
}
|
|
327
|
+
export declare enum EFeedType {
|
|
328
|
+
Unknown = 0,
|
|
329
|
+
Movie = 1,
|
|
330
|
+
Podcast = 2,
|
|
331
|
+
Music = 3,
|
|
332
|
+
MusicVideo = 4,
|
|
333
|
+
Audiobook = 5,
|
|
334
|
+
ShortFilm = 6,
|
|
335
|
+
TvShow = 7,
|
|
336
|
+
Ebook = 8
|
|
337
|
+
}
|
|
338
|
+
export interface IRssFeed extends IRssItem {
|
|
339
|
+
rssUrl: string;
|
|
340
|
+
genre?: string;
|
|
341
|
+
country?: string;
|
|
342
|
+
copyright?: string;
|
|
343
|
+
owner?: string;
|
|
344
|
+
imageUrl?: string;
|
|
345
|
+
items?: IRssItem[];
|
|
346
|
+
}
|
|
329
347
|
export declare const getPlaylistSymbol: InjectionKey<() => IPlaylistService>;
|
|
330
348
|
export declare enum EPlaylistCommand {
|
|
331
349
|
None = 0,
|
|
@@ -346,11 +364,8 @@ export interface IPlaylistState {
|
|
|
346
364
|
export interface IPlaylistService {
|
|
347
365
|
log: ILogger;
|
|
348
366
|
soundbarOn: boolean;
|
|
349
|
-
|
|
350
|
-
getFeed(
|
|
351
|
-
getFeeds(): Promise<IRssFeed[]>;
|
|
352
|
-
addFeed(url: string, save: boolean): Promise<IRssFeed | null>;
|
|
353
|
-
deleteFeed(title: string): Promise<boolean>;
|
|
367
|
+
searchFeeds(query: Dictionary<any>, limit?: number): Promise<IRssFeed[]>;
|
|
368
|
+
getFeed(rssUrl: string): Promise<IRssFeed | null>;
|
|
354
369
|
play(url: string): Promise<boolean>;
|
|
355
370
|
playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
|
|
356
371
|
playCommand(cmd: EPlaylistCommand): Promise<boolean>;
|
package/dist/iMedia.js
CHANGED
|
@@ -121,6 +121,18 @@ export var EPictureFlags;
|
|
|
121
121
|
EPictureFlags[EPictureFlags["Mask"] = 240] = "Mask";
|
|
122
122
|
})(EPictureFlags || (EPictureFlags = {}));
|
|
123
123
|
export const getMediaSymbol = Symbol("get-media");
|
|
124
|
+
export var EFeedType;
|
|
125
|
+
(function (EFeedType) {
|
|
126
|
+
EFeedType[EFeedType["Unknown"] = 0] = "Unknown";
|
|
127
|
+
EFeedType[EFeedType["Movie"] = 1] = "Movie";
|
|
128
|
+
EFeedType[EFeedType["Podcast"] = 2] = "Podcast";
|
|
129
|
+
EFeedType[EFeedType["Music"] = 3] = "Music";
|
|
130
|
+
EFeedType[EFeedType["MusicVideo"] = 4] = "MusicVideo";
|
|
131
|
+
EFeedType[EFeedType["Audiobook"] = 5] = "Audiobook";
|
|
132
|
+
EFeedType[EFeedType["ShortFilm"] = 6] = "ShortFilm";
|
|
133
|
+
EFeedType[EFeedType["TvShow"] = 7] = "TvShow";
|
|
134
|
+
EFeedType[EFeedType["Ebook"] = 8] = "Ebook";
|
|
135
|
+
})(EFeedType || (EFeedType = {}));
|
|
124
136
|
export const getPlaylistSymbol = Symbol("get-playlist");
|
|
125
137
|
export var EPlaylistCommand;
|
|
126
138
|
(function (EPlaylistCommand) {
|
package/dist/iMedia.js.map
CHANGED
|
@@ -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":"AAGA,MAAM,CAAN,IAAY,UASX;AATD,WAAY,UAAU;IAClB,6CAAS,CAAA;IACT,6CAAS,CAAA;IACT,iDAAW,CAAA;IACX,4CAAS,CAAA;IACT,0DAAgB,CAAA;IAChB,iDAAa,CAAA;IACb,6CAAW,CAAA;IACX,mDAAc,CAAA;AAClB,CAAC,EATW,UAAU,KAAV,UAAU,QASrB;AACD,MAAM,CAAN,IAAY,eAeX;AAfD,WAAY,eAAe;IACvB,qDAAiB,CAAA;IACjB,gEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,kEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,gEAAoB,CAAA;IACpB,kEAAoB,CAAA;IACpB,4DAAoB,CAAA;IACpB,4DAAoB,CAAA;IACpB,4DAAoB,CAAA;IACpB,8DAAoB,CAAA;AACxB,CAAC,EAfW,eAAe,KAAf,eAAe,QAe1B;AAaD,MAAM,CAAN,IAAY,SAoDX;AApDD,WAAY,SAAS;IACjB,yCAAQ,CAAA;IACR,mDAAa,CAAA;IACb,uDAAe,CAAA;IACf,uDAAe,CAAA;IACf,6DAAkB,CAAA;IAClB,iEAAoB,CAAA;IACpB,iEAAoB,CAAA;IACpB,iEAAoB,CAAA;IACpB,iEAAoB,CAAA;IACpB,mDAAgB,CAAA;IAChB,6CAAa,CAAA;IACb,4CAAY,CAAA;IACZ,4CAAY,CAAA;IACZ,gDAAc,CAAA;IACd,6DAAoB,CAAA;IACpB,qDAAgB,CAAA;IAChB,yCAAa,CAAA;IACb,mDAA6C,CAAA;IAC7C,oDAA0B,CAAA;IAC1B,wDAAkC,CAAA;IAClC,wDAAkC,CAAA;IAClC,8DAAqC,CAAA;IACrC,sDAAiC,CAAA;IACjC,wDAAkC,CAAA;IAClC,sDAAiC,CAAA;IACjC,0DAAmC,CAAA;IACnC,uEAA0C,CAAA;IAC1C,2EAA8C,CAAA;IAC9C,sDAAkB,CAAA;IAClB,+DAAkC,CAAA;IAClC,oDAA0B,CAAA;IAC1B,wDAAkC,CAAA;IAClC,wDAAkC,CAAA;IAClC,8DAAqC,CAAA;IACrC,4DAAoC,CAAA;IACpC,uEAA0C,CAAA;IAC1C,2EAA8C,CAAA;IAC9C,yEAA+C,CAAA;IAC/C,oDAAiB,CAAA;IACjB,+DAAkC,CAAA;IAClC,wDAA8B,CAAA;IAC9B,4DAAsC,CAAA;IACtC,4DAAsC,CAAA;IACtC,kEAAyC,CAAA;IACzC,gEAAwC,CAAA;IACxC,wDAAoC,CAAA;IACpC,0DAAqC,CAAA;IACrC,wDAAqB,CAAA;IACrB,uDAA+C,CAAA;IAC/C,qDAAgB,CAAA;IAChB,yCAAU,CAAA;AACd,CAAC,EApDW,SAAS,KAAT,SAAS,QAoDpB;AACD,MAAM,CAAN,IAAY,MAUX;AAVD,WAAY,MAAM;IACd,mCAAQ,CAAA;IACR,yDAAsB,CAAA;IACtB,2CAAe,CAAA;IACf,+CAAiB,CAAA;IACjB,qDAAoB,CAAA;IACpB,kDAAkB,CAAA;IAClB,sDAAoB,CAAA;IACpB,0DAAsB,CAAA;IACtB,+DAAwB,CAAA;AAC5B,CAAC,EAVW,MAAM,KAAN,MAAM,QAUjB;AAkDD,MAAM,CAAN,IAAY,YAaX;AAbD,WAAY,YAAY;IAEpB,+CAAY,CAAA;IACZ,qDAAmB,CAAA;IACnB,yDAAmB,CAAA;IACnB,6DAAmB,CAAA;IACnB,2DAAmB,CAAA;IACnB,qEAAmB,CAAA;IACnB,uDAAmB,CAAA;IACnB,mEAAmB,CAAA;IACnB,2DAAmB,CAAA;IACnB,yDAAiB,CAAA;IACjB,gDAAe,CAAA;AACnB,CAAC,EAbW,YAAY,KAAZ,YAAY,QAavB;AACD,MAAM,CAAN,IAAY,aAaX;AAbD,WAAY,aAAa;IAErB,iDAAe,CAAA;IACf,yDAAkB,CAAA;IAClB,gDAAkB,CAAA;IAClB,sDAAkB,CAAA;IAClB,oDAAkB,CAAA;IAClB,kDAAkB,CAAA;IAClB,sDAAkB,CAAA;IAClB,oDAAkB,CAAA;IAClB,qDAAkB,CAAA;IAClB,6DAAkB,CAAA;IAClB,mDAAkB,CAAA;AACtB,CAAC,EAbW,aAAa,KAAb,aAAa,QAaxB;AA6FD,MAAM,CAAC,MAAM,cAAc,GAAsC,MAAM,CAAC,WAAW,CAAC,CAAC;AA2ErF,MAAM,CAAN,IAAY,SAGX;AAHD,WAAY,SAAS;IAEjB,+CAAW,CAAA;IAAE,2CAAS,CAAA;IAAE,+CAAW,CAAA;IAAE,2CAAS,CAAA;IAAE,qDAAc,CAAA;IAAE,mDAAa,CAAA;IAAE,mDAAa,CAAA;IAAE,6CAAU,CAAA;IAAE,2CAAS,CAAA;AACvH,CAAC,EAHW,SAAS,KAAT,SAAS,QAGpB;AAWD,MAAM,CAAC,MAAM,iBAAiB,GAAyC,MAAM,CAAC,cAAc,CAAC,CAAC;AAC9F,MAAM,CAAN,IAAY,gBAEX;AAFD,WAAY,gBAAgB;IACxB,uDAAQ,CAAA;IAAE,uDAAI,CAAA;IAAE,yDAAK,CAAA;IAAE,2DAAM,CAAA;IAAE,uDAAI,CAAA;IAAE,uDAAI,CAAA;IAAE,+DAAQ,CAAA;AACvD,CAAC,EAFW,gBAAgB,KAAhB,gBAAgB,QAE3B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IRest } from '@christianriedl/rest';
|
|
2
|
-
import { ILogger } from '@christianriedl/utils';
|
|
2
|
+
import { ILogger, Dictionary } from '@christianriedl/utils';
|
|
3
3
|
import { IRssFeed, EPlaylistCommand, IPlaylistState, IPlaylistService } from "./iMedia";
|
|
4
4
|
export declare class PlaylistService implements IPlaylistService {
|
|
5
5
|
rest: IRest;
|
|
@@ -7,13 +7,10 @@ export declare class PlaylistService implements IPlaylistService {
|
|
|
7
7
|
log: ILogger;
|
|
8
8
|
soundbarOn: boolean;
|
|
9
9
|
setSoundbar: (name: string, value: string) => Promise<boolean>;
|
|
10
|
-
getSoundbarValue: (name: string) =>
|
|
11
|
-
constructor(rest: IRest, log: ILogger, getSoundbarValue: (name: string) =>
|
|
12
|
-
|
|
13
|
-
getFeed(
|
|
14
|
-
getFeeds(): Promise<IRssFeed[]>;
|
|
15
|
-
addFeed(url: string, save: boolean): Promise<IRssFeed | null>;
|
|
16
|
-
deleteFeed(title: string): Promise<boolean>;
|
|
10
|
+
getSoundbarValue: (name: string) => any;
|
|
11
|
+
constructor(rest: IRest, log: ILogger, getSoundbarValue: (name: string) => any, setSoundbar: (name: string, value: string) => Promise<boolean>);
|
|
12
|
+
searchFeeds(query: Dictionary<any>, limit?: number): Promise<IRssFeed[]>;
|
|
13
|
+
getFeed(rssUrl: string): Promise<IRssFeed | null>;
|
|
17
14
|
play(url: string): Promise<boolean>;
|
|
18
15
|
playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
|
|
19
16
|
playCommand(cmd: EPlaylistCommand): Promise<boolean>;
|
package/dist/playlistService.js
CHANGED
|
@@ -15,26 +15,37 @@ export class PlaylistService {
|
|
|
15
15
|
this.setSoundbar = setSoundbar;
|
|
16
16
|
this.soundbarOn = false;
|
|
17
17
|
}
|
|
18
|
-
async
|
|
19
|
-
|
|
18
|
+
async searchFeeds(query, limit) {
|
|
19
|
+
query['limit'] = limit ?? 50;
|
|
20
|
+
const res = await this.rest.getData('apiplaylist/feed/search', query);
|
|
20
21
|
return res.ok ? res.result : [];
|
|
21
22
|
}
|
|
22
|
-
async getFeed(
|
|
23
|
-
const res = await this.rest.getData('apiplaylist/feed', {
|
|
23
|
+
async getFeed(rssUrl) {
|
|
24
|
+
const res = await this.rest.getData('apiplaylist/feed', { rssUrl: rssUrl });
|
|
24
25
|
return res.ok ? res.result : null;
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/*
|
|
28
|
+
async getTitles(): Promise<string[]> {
|
|
29
|
+
const res = await this.rest.getData<string[]>('apiplaylist/title');
|
|
30
|
+
return res.ok ? res.result as string[] : [];
|
|
29
31
|
}
|
|
30
|
-
async
|
|
31
|
-
const res = await this.rest.
|
|
32
|
-
return res.ok ? res.result
|
|
32
|
+
async getFeed(title: string): Promise<IRssFeed|null> {
|
|
33
|
+
const res = await this.rest.getData<IRssFeed>('apiplaylist/feed', { title: title });
|
|
34
|
+
return res.ok ? res.result as IRssFeed : null;
|
|
33
35
|
}
|
|
34
|
-
async
|
|
35
|
-
const res = await this.rest.
|
|
36
|
-
return res.ok ? res.result :
|
|
36
|
+
async getFeeds(): Promise<IRssFeed[]> {
|
|
37
|
+
const res = await this.rest.getData<IRssFeed[]>('apiplaylist/feed');
|
|
38
|
+
return res.ok ? res.result as IRssFeed[] : [];
|
|
39
|
+
}
|
|
40
|
+
async addFeed(url: string, save: boolean): Promise<IRssFeed|null> {
|
|
41
|
+
const res = await this.rest.postDataEx<boolean,IRssFeed>(`apiplaylist/feed?url=${encodeURIComponent(url)}&save=${save}`);
|
|
42
|
+
return res.ok ? (res.result as IValueResult<IRssFeed>).result : null;
|
|
43
|
+
}
|
|
44
|
+
async deleteFeed(title: string): Promise<boolean> {
|
|
45
|
+
const res = await this.rest.deleteData<any, boolean>(`apiplaylist/feed?title=${encodeURIComponent(title)}`);
|
|
46
|
+
return res.ok ? res.result as boolean : false;
|
|
37
47
|
}
|
|
48
|
+
*/
|
|
38
49
|
async play(url) {
|
|
39
50
|
this.soundbarOn = await this.ensureOn();
|
|
40
51
|
if (!this.soundbarOn)
|
|
@@ -67,9 +78,9 @@ export class PlaylistService {
|
|
|
67
78
|
async ensureOn() {
|
|
68
79
|
let i = 0;
|
|
69
80
|
for (i = 0; i < 5; i++) {
|
|
70
|
-
if (this.getSoundbarValue('
|
|
81
|
+
if (this.getSoundbarValue('On') === true)
|
|
71
82
|
break;
|
|
72
|
-
const result = await this.setSoundbar('
|
|
83
|
+
const result = await this.setSoundbar('POWERON', '1');
|
|
73
84
|
await Helper.delay(1000);
|
|
74
85
|
}
|
|
75
86
|
if (i >= 5)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playlistService.js","sourceRoot":"","sources":["../src/playlistService.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,MAAM,
|
|
1
|
+
{"version":3,"file":"playlistService.js","sourceRoot":"","sources":["../src/playlistService.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { inject, ref, reactive, computed, onMounted, onUnmounted, nextTick, watch, StyleValue } from 'vue';
|
|
3
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, EPlaylistCommand } from '@christianriedl/media';
|
|
4
|
+
import { useRouter, useRoute } from 'vue-router';
|
|
5
|
+
import { IAppState, EScope, EDevice, Helper, appStateSymbol, appConfigSymbol, Dictionary } from '@christianriedl/utils';
|
|
6
|
+
import { getPlaylistSymbol, IPlaylistService, IPlaylistState, IRssFeed, IRssItem, EPlaylistCommand, EFeedType } from '@christianriedl/media';
|
|
7
7
|
|
|
8
8
|
const appState = inject(appStateSymbol)!;
|
|
9
9
|
const getPlaylistService = inject(getPlaylistSymbol)!;
|
|
@@ -11,31 +11,45 @@
|
|
|
11
11
|
const heightStyle = computed<StyleValue>(() => { return { height: appState.bodyHeight.value + 'px', overflowY: 'auto' } });
|
|
12
12
|
const isMobile = appState.isMobile && (appState.device != EDevice.iPad);
|
|
13
13
|
const router = useRouter();
|
|
14
|
+
const route = useRoute();
|
|
14
15
|
const feeds: IRssFeed[] = reactive([]);
|
|
15
|
-
const
|
|
16
|
+
const items: IRssItem[] = reactive([]);
|
|
17
|
+
const selectedItem = ref<IRssItem|null>(null);
|
|
18
|
+
const selectedFeed = ref<IRssFeed|null>(null);
|
|
16
19
|
const status = ref<IPlaylistState|null>(null);
|
|
17
20
|
const audio = ref<HTMLAudioElement | null>(null);
|
|
18
21
|
const listhead = ref<ComponentPublicInstance | null>(null);
|
|
19
22
|
const listHeight = ref(0);
|
|
20
23
|
const playerNames = ['Local', 'Soundbar'];
|
|
24
|
+
const backVisible = computed(() => !!route.query?.feed);
|
|
21
25
|
const currentPlayer = ref<string>(playerNames[0]);
|
|
22
26
|
const playLocal = computed(() => currentPlayer.value == 'Local');
|
|
23
27
|
const playIndex = ref(-1);
|
|
24
28
|
const itemIndex = ref(0);
|
|
25
|
-
const
|
|
29
|
+
const playingItem = ref<IRssItem|null>(null);
|
|
26
30
|
const position = ref(0);
|
|
27
31
|
const positionLength = ref(0);
|
|
28
32
|
const volume = ref(0);
|
|
29
33
|
const paused = ref(false);
|
|
34
|
+
const search = ref(true);
|
|
30
35
|
let statusTimer = 0;
|
|
36
|
+
const positionText = computed(() => {
|
|
37
|
+
if (playingItem.value?.duration)
|
|
38
|
+
return toTime(position.value) + '/' + toTime(playingItem.value.duration);
|
|
39
|
+
else
|
|
40
|
+
return toTime(position.value);
|
|
41
|
+
});
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
const feedTypes = Helper.getEnumOptions(EFeedType);
|
|
44
|
+
const feedType = ref<EFeedType>(0);
|
|
45
|
+
const countries = ["", "AT", "DE", "US"];
|
|
46
|
+
const country = ref("");
|
|
47
|
+
const query = ref("");
|
|
48
|
+
const limit = ref(50);
|
|
33
49
|
|
|
34
50
|
onMounted(async () => {
|
|
35
|
-
playlistService.log.info('
|
|
36
|
-
|
|
37
|
-
feeds.splice(0, feeds.length, ...f);
|
|
38
|
-
computeListHeight();
|
|
51
|
+
playlistService.log.info('OnlinePodcastsPage created');
|
|
52
|
+
await start();
|
|
39
53
|
});
|
|
40
54
|
onUnmounted(() => {
|
|
41
55
|
if (statusTimer > 0) {
|
|
@@ -43,6 +57,23 @@
|
|
|
43
57
|
statusTimer = 0;
|
|
44
58
|
}
|
|
45
59
|
});
|
|
60
|
+
async function start() {
|
|
61
|
+
if (route.query?.rssUrl) {
|
|
62
|
+
const rssUrl = decodeURIComponent(route.query.rssUrl.toString());
|
|
63
|
+
const f = await playlistService.getFeed(rssUrl);
|
|
64
|
+
if (f && f.items) {
|
|
65
|
+
selectedFeed.value = f;
|
|
66
|
+
items.splice(0, items.length, ...f.items);
|
|
67
|
+
search.value = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
search.value = true;
|
|
72
|
+
}
|
|
73
|
+
computeListHeight();
|
|
74
|
+
}
|
|
75
|
+
watch(appState.bodyHeight, () => computeListHeight());
|
|
76
|
+
watch(() => route.query, () => start());
|
|
46
77
|
|
|
47
78
|
function computeListHeight() {
|
|
48
79
|
nextTick(() => {
|
|
@@ -53,43 +84,66 @@
|
|
|
53
84
|
listHeight.value = height;
|
|
54
85
|
})
|
|
55
86
|
}
|
|
87
|
+
|
|
88
|
+
async function onSearch() {
|
|
89
|
+
const dict: Dictionary<any> = {};
|
|
90
|
+
if (feedType.value != EFeedType.None)
|
|
91
|
+
dict["media"] = EFeedType[feedType];
|
|
92
|
+
if (country.value != "")
|
|
93
|
+
dict["country"] = country.value;;
|
|
94
|
+
dict["query"] = query.value;
|
|
95
|
+
const fds = await playlistService.searchFeeds(dict, limit.value);;
|
|
96
|
+
feeds.splice (0, feeds.length, ...fds);
|
|
97
|
+
}
|
|
56
98
|
async function play() {
|
|
57
99
|
if (playLocal.value) {
|
|
58
|
-
audio.value!.src =
|
|
100
|
+
audio.value!.src = selectedItem.value!.link;
|
|
59
101
|
audio.value!.load();
|
|
60
102
|
audio.value!.play().then(() => {
|
|
61
|
-
playlistService.log.trace(`play local ${
|
|
103
|
+
playlistService.log.trace(`play local ${selectedItem.value!.title}`)
|
|
62
104
|
});
|
|
105
|
+
playingItem.value = selectedItem.value;
|
|
63
106
|
}
|
|
64
107
|
else {
|
|
65
|
-
const rc = await playlistService.play(
|
|
108
|
+
const rc = await playlistService.play(selectedItem.value!.link);
|
|
66
109
|
if (!rc)
|
|
67
110
|
return;
|
|
111
|
+
playingItem.value = selectedItem.value;
|
|
68
112
|
await getStatus();
|
|
69
|
-
playlistService.log.trace(`play remote ${
|
|
113
|
+
playlistService.log.trace(`play remote ${selectedItem.value!.title}`)
|
|
70
114
|
}
|
|
71
|
-
|
|
72
|
-
itemIndex.value = playIndex.value = feeds.findIndex((f) => f.link == selected.value!.link);
|
|
115
|
+
itemIndex.value = playIndex.value = feeds.findIndex((f) => f.link == selectedItem.value!.link);
|
|
73
116
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
117
|
+
function listFeed(feed: IRssFeed) {{
|
|
118
|
+
router.push ({path: 'onlinePodcasts', query: { rssUrl: feed.rssUrl }});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function listItem(item: IRssItem) {
|
|
122
|
+
selectedItem.value = item;
|
|
123
|
+
play();
|
|
124
|
+
computeListHeight();
|
|
77
125
|
}
|
|
78
126
|
function listBack() {
|
|
79
127
|
router.back();
|
|
80
128
|
}
|
|
81
129
|
async function getStatus() {
|
|
82
|
-
const
|
|
83
|
-
status.value =
|
|
84
|
-
|
|
85
|
-
|
|
130
|
+
const state = await playlistService.getState();
|
|
131
|
+
status.value = state;
|
|
132
|
+
if (state)
|
|
133
|
+
setPosition(Number(state.position));
|
|
134
|
+
statusTimer = window.setTimeout(async () => getStatus(), 1000);
|
|
86
135
|
}
|
|
87
136
|
|
|
88
137
|
function toSubTitle(f: IRssFeed): string {
|
|
89
|
-
if (!f.duration)
|
|
138
|
+
if (!f || !f.duration)
|
|
90
139
|
return "";
|
|
91
|
-
|
|
92
|
-
|
|
140
|
+
return toTime(f.duration);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function toTime(s: number): string {
|
|
144
|
+
if (!s)
|
|
145
|
+
return "";
|
|
146
|
+
let r = "";
|
|
93
147
|
s = Math.floor(s);
|
|
94
148
|
if (s >= 3600) {
|
|
95
149
|
r += Math.floor(s / 3600).toString() + ":"; s = s % 3600;
|
|
@@ -116,8 +170,8 @@
|
|
|
116
170
|
}
|
|
117
171
|
function setPosition(value: number) {
|
|
118
172
|
position.value = value;
|
|
119
|
-
if (
|
|
120
|
-
positionLength.value = position.value * 100 /
|
|
173
|
+
if (playingItem.value?.duration)
|
|
174
|
+
positionLength.value = position.value * 100 / playingItem.value!.duration;
|
|
121
175
|
else
|
|
122
176
|
positionLength.value = 0;
|
|
123
177
|
}
|
|
@@ -127,7 +181,7 @@
|
|
|
127
181
|
statusTimer = 0;
|
|
128
182
|
}
|
|
129
183
|
if (!playLocal.value) {
|
|
130
|
-
statusTimer = setTimeout(() => getStatus(), 1000);
|
|
184
|
+
statusTimer = window.setTimeout(() => getStatus(), 1000);
|
|
131
185
|
}
|
|
132
186
|
}
|
|
133
187
|
function playpause() {
|
|
@@ -154,13 +208,13 @@
|
|
|
154
208
|
function previous() {
|
|
155
209
|
if (playIndex.value <= 0)
|
|
156
210
|
return;
|
|
157
|
-
|
|
211
|
+
selectedItem.value = feeds[playIndex.value - 1];
|
|
158
212
|
play();
|
|
159
213
|
}
|
|
160
214
|
function next() {
|
|
161
215
|
if (playIndex.value >= feeds.length - 1)
|
|
162
216
|
return;
|
|
163
|
-
|
|
217
|
+
selectedItem.value = feeds[playIndex.value + 1];
|
|
164
218
|
play();
|
|
165
219
|
}
|
|
166
220
|
function changeVolume() {
|
|
@@ -170,20 +224,118 @@
|
|
|
170
224
|
|
|
171
225
|
<template>
|
|
172
226
|
<v-card ref="listhead" class="bg-media_head">
|
|
227
|
+
<audio ref="audio" preload="none" @ended="onEnded" @timeupdate="onTimeUpdate">
|
|
228
|
+
</audio>
|
|
229
|
+
<v-container v-if="search" fluid>
|
|
230
|
+
<v-row class="align-center">
|
|
231
|
+
<v-col cols="1"></v-col>
|
|
232
|
+
<v-col cols="2">Type</v-col>
|
|
233
|
+
<v-col cols="1">Country</v-col>
|
|
234
|
+
<v-col cols="6">Query</v-col>
|
|
235
|
+
<v-col cols="1">Limit</v-col>
|
|
236
|
+
</v-row>
|
|
237
|
+
<v-row class="align-center">
|
|
238
|
+
<v-col cols="1">
|
|
239
|
+
<v-btn v-if="backVisible" icon="$back" class="bg-media_head" variant="tonal" @click="listBack">
|
|
240
|
+
</v-btn>
|
|
241
|
+
</v-col>
|
|
242
|
+
<v-col cols="2">
|
|
243
|
+
<v-select density="compact" v-model="feedType"
|
|
244
|
+
:items="feedTypes"
|
|
245
|
+
persistent-hint hide-details single-line>
|
|
246
|
+
</v-select>
|
|
247
|
+
</v-col>
|
|
248
|
+
<v-col cols="1">
|
|
249
|
+
<v-combobox density="compact" v-model="country"
|
|
250
|
+
:items="countries"
|
|
251
|
+
persistent-hint hide-details single-line>
|
|
252
|
+
</v-combobox>
|
|
253
|
+
</v-col>
|
|
254
|
+
<v-col cols="6">
|
|
255
|
+
<v-text-field v-model="query" hide-details density="compact"></v-text-field>
|
|
256
|
+
</v-col>
|
|
257
|
+
<v-col cols="1">
|
|
258
|
+
<v-text-field v-model="limit" hide-details type="number" density="compact"></v-text-field>
|
|
259
|
+
</v-col>
|
|
260
|
+
<v-col cols="1">
|
|
261
|
+
<v-btn icon="$search" class="bg-media_head" variant="tonal" @click="onSearch">
|
|
262
|
+
</v-btn>
|
|
263
|
+
</v-col>
|
|
264
|
+
</v-row>
|
|
265
|
+
</v-container>
|
|
266
|
+
<v-container v-else fluid>
|
|
267
|
+
<v-row class="align-center">
|
|
268
|
+
<v-col cols="1">
|
|
269
|
+
<v-btn v-if="backVisible" icon="$back" class="bg-media_head" variant="tonal" @click="listBack">
|
|
270
|
+
</v-btn>
|
|
271
|
+
</v-col>
|
|
272
|
+
<v-col cols="1">
|
|
273
|
+
<v-img :src="selectedFeed.imageUrl"></v-img>
|
|
274
|
+
</v-col>
|
|
275
|
+
<v-col cols="1">{{selectedFeed.country}}</v-col>
|
|
276
|
+
<v-col cols="2">{{selectedFeed.genre}}</v-col>
|
|
277
|
+
<v-col cols="2">{{selectedFeed.owner}}</v-col>
|
|
278
|
+
<v-col cols="5">{{selectedFeed.title}}</v-col>
|
|
279
|
+
<v-col cols="2">
|
|
280
|
+
<v-select v-model="currentPlayer" density="compact" :items="playerNames" persistent-hint
|
|
281
|
+
@update:modelValue="onPlayerChange" hide-details single-line>
|
|
282
|
+
</v-select>
|
|
283
|
+
</v-col>
|
|
284
|
+
</v-row>
|
|
285
|
+
<v-row v-if="playingItem" class="align-center">
|
|
286
|
+
<v-col cols="4">
|
|
287
|
+
<v-btn :icon="paused ? '$play' : '$pause'" @click="playpause">
|
|
288
|
+
<v-btn icon="$prev" @click="previous">
|
|
289
|
+
<v-btn icon="$next" @click="next">
|
|
290
|
+
</v-col>
|
|
291
|
+
<v-col cols ="8">
|
|
292
|
+
<v-slider v-if="!playLocal" style="width:30%" color="red" track-color="blue" track-fill-color="red" v-model="volume" hide-details density="compact"
|
|
293
|
+
min="0" max="100" step="5" @update:modelValue="changeVolume">
|
|
294
|
+
</v-slider>
|
|
295
|
+
</v-col>
|
|
296
|
+
</v-row>
|
|
297
|
+
<v-row v-if="playingItem">
|
|
298
|
+
<v-col cols="12">
|
|
299
|
+
<v-progress-linear v-model="positionLength" color="blue" height="25"><strong>{{positionText}}</strong></v-progress-linear>
|
|
300
|
+
</v-col>
|
|
301
|
+
</v-row>
|
|
302
|
+
</v-container>
|
|
303
|
+
</v-card>
|
|
304
|
+
<v-card :height="listHeight" density="compact" class="overflow-y-auto bg-media">
|
|
305
|
+
<v-container v-if="search" fluid>
|
|
306
|
+
<v-row v-for="(feed,index) in feeds" :key="feed.rssUrl" @click="listFeed(feed)">
|
|
307
|
+
<v-col cols="1">{{feed.country}}</v-col>
|
|
308
|
+
<v-col cols="2">{{feed.genre}}</v-col>
|
|
309
|
+
<v-col cols="2">{{feed.owner}}</v-col>
|
|
310
|
+
<v-col cols="5">{{feed.title}}</v-col>
|
|
311
|
+
</v-row>
|
|
312
|
+
</v-container>
|
|
313
|
+
<v-container v-else>
|
|
314
|
+
<v-row v-for="(item,index) in items" :key="item.rssUrl" @click="listItem(item)">
|
|
315
|
+
<v-col cols="1">{{item.title}}</v-col>
|
|
316
|
+
<v-col cols="2">{{toTime(item.duration)}}</v-col>
|
|
317
|
+
<v-col cols="2">{{feed.owner}}</v-col>
|
|
318
|
+
<v-col cols="5">{{item.title}}</v-col>
|
|
319
|
+
</v-row>
|
|
320
|
+
</v-container>
|
|
321
|
+
</v-card>
|
|
322
|
+
|
|
323
|
+
<!--
|
|
324
|
+
<v-card class="bg-media_head">
|
|
173
325
|
<audio ref="audio" preload="none" @ended="onEnded" @timeupdate="onTimeUpdate">
|
|
174
326
|
</audio>
|
|
175
327
|
<v-list-item lines="three">
|
|
176
328
|
<v-list-item-content>
|
|
177
|
-
<v-list-item-title text-h6>{{selected
|
|
329
|
+
<v-list-item-title text-h6>{{selected?.title}}</v-list-item-title>
|
|
178
330
|
<v-list-item-subtitle>{{toSubTitle(selected!)}}</v-list-item-subtitle>
|
|
179
331
|
</v-list-item-content>
|
|
180
332
|
<template v-slot:append>
|
|
181
|
-
<v-select v-model="currentPlayer"
|
|
333
|
+
<v-select v-model="currentPlayer" density="compact"
|
|
182
334
|
:items="playerNames"
|
|
183
335
|
persistent-hint
|
|
184
336
|
@update:modelValue="onPlayerChange"
|
|
185
337
|
hide-details single-line>
|
|
186
|
-
</v-select
|
|
338
|
+
</v-select>
|
|
187
339
|
</template>
|
|
188
340
|
</v-list-item>
|
|
189
341
|
<v-card-actions>
|
|
@@ -209,11 +361,12 @@
|
|
|
209
361
|
<v-card :height="listHeight" density="compact" class="overflow-y-auto bg-media">
|
|
210
362
|
<v-list lines="two" class="bg-media">
|
|
211
363
|
<v-list-item-group v-model="itemIndex">
|
|
212
|
-
<v-list-item v-for="(
|
|
213
|
-
active-color="blue" :active="index == playIndex" @click="listItem(
|
|
364
|
+
<v-list-item v-for="(feed,index) in feeds" :key="feed.title" density="compact" :title="feed.title" :subtitle="toSubTitle(feed)"
|
|
365
|
+
active-color="blue" :active="index == playIndex" @click="listItem(feed)">
|
|
214
366
|
</v-list-item>
|
|
215
367
|
</v-list-item-group>
|
|
216
368
|
</v-list>
|
|
217
369
|
</v-card>
|
|
370
|
+
-->
|
|
218
371
|
</template>
|
|
219
372
|
|