@christianriedl/media 1.0.302 → 1.0.304
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 +26 -9
- package/dist/iMedia.js +12 -0
- package/dist/iMedia.js.map +1 -1
- package/dist/playlistService.d.ts +8 -9
- package/dist/playlistService.js +36 -19
- package/dist/playlistService.js.map +1 -1
- package/package.json +1 -1
- package/src/views/OnlinePodcastsPage.vue +211 -38
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,13 +364,12 @@ export interface IPlaylistState {
|
|
|
346
364
|
export interface IPlaylistService {
|
|
347
365
|
log: ILogger;
|
|
348
366
|
soundbarOn: boolean;
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
addFeed(url: string, save: boolean): Promise<IRssFeed | null>;
|
|
353
|
-
deleteFeed(title: string): Promise<boolean>;
|
|
367
|
+
soundbarVolume: number;
|
|
368
|
+
searchFeeds(query: Dictionary<any>, limit?: number): Promise<IRssFeed[]>;
|
|
369
|
+
getFeed(rssUrl: string): Promise<IRssFeed | null>;
|
|
354
370
|
play(url: string): Promise<boolean>;
|
|
355
371
|
playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
|
|
356
372
|
playCommand(cmd: EPlaylistCommand): Promise<boolean>;
|
|
373
|
+
setSoundbarVolume(value: number): Promise<boolean>;
|
|
357
374
|
getState(): Promise<IPlaylistState | null>;
|
|
358
375
|
}
|
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":"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"}
|
|
@@ -1,22 +1,21 @@
|
|
|
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;
|
|
6
6
|
mediaUrl: string;
|
|
7
7
|
log: ILogger;
|
|
8
8
|
soundbarOn: boolean;
|
|
9
|
+
soundbarVolume: number;
|
|
9
10
|
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>;
|
|
11
|
+
getSoundbarValue: (name: string) => any;
|
|
12
|
+
constructor(rest: IRest, log: ILogger, getSoundbarValue: (name: string) => any, setSoundbar: (name: string, value: string) => Promise<boolean>);
|
|
13
|
+
searchFeeds(query: Dictionary<any>, limit?: number): Promise<IRssFeed[]>;
|
|
14
|
+
getFeed(rssUrl: string): Promise<IRssFeed | null>;
|
|
17
15
|
play(url: string): Promise<boolean>;
|
|
18
16
|
playList(urls: string[], clear: boolean, index?: number): Promise<boolean>;
|
|
19
17
|
playCommand(cmd: EPlaylistCommand): Promise<boolean>;
|
|
20
18
|
getState(): Promise<IPlaylistState | null>;
|
|
21
|
-
|
|
19
|
+
ensureSoundbarOn(): Promise<boolean>;
|
|
20
|
+
setSoundbarVolume(value: number): Promise<boolean>;
|
|
22
21
|
}
|
package/dist/playlistService.js
CHANGED
|
@@ -5,6 +5,7 @@ export class PlaylistService {
|
|
|
5
5
|
mediaUrl;
|
|
6
6
|
log;
|
|
7
7
|
soundbarOn;
|
|
8
|
+
soundbarVolume;
|
|
8
9
|
setSoundbar;
|
|
9
10
|
getSoundbarValue;
|
|
10
11
|
constructor(rest, log, getSoundbarValue, setSoundbar) {
|
|
@@ -15,35 +16,46 @@ export class PlaylistService {
|
|
|
15
16
|
this.setSoundbar = setSoundbar;
|
|
16
17
|
this.soundbarOn = false;
|
|
17
18
|
}
|
|
18
|
-
async
|
|
19
|
-
|
|
19
|
+
async searchFeeds(query, limit) {
|
|
20
|
+
query['limit'] = limit ?? 50;
|
|
21
|
+
const res = await this.rest.getData('apiplaylist/feed/search', query);
|
|
20
22
|
return res.ok ? res.result : [];
|
|
21
23
|
}
|
|
22
|
-
async getFeed(
|
|
23
|
-
const res = await this.rest.getData('apiplaylist/feed', {
|
|
24
|
+
async getFeed(rssUrl) {
|
|
25
|
+
const res = await this.rest.getData('apiplaylist/feed', { rssUrl: rssUrl });
|
|
24
26
|
return res.ok ? res.result : null;
|
|
25
27
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
/*
|
|
29
|
+
async getTitles(): Promise<string[]> {
|
|
30
|
+
const res = await this.rest.getData<string[]>('apiplaylist/title');
|
|
31
|
+
return res.ok ? res.result as string[] : [];
|
|
29
32
|
}
|
|
30
|
-
async
|
|
31
|
-
const res = await this.rest.
|
|
32
|
-
return res.ok ? res.result
|
|
33
|
+
async getFeed(title: string): Promise<IRssFeed|null> {
|
|
34
|
+
const res = await this.rest.getData<IRssFeed>('apiplaylist/feed', { title: title });
|
|
35
|
+
return res.ok ? res.result as IRssFeed : null;
|
|
33
36
|
}
|
|
34
|
-
async
|
|
35
|
-
const res = await this.rest.
|
|
36
|
-
return res.ok ? res.result :
|
|
37
|
+
async getFeeds(): Promise<IRssFeed[]> {
|
|
38
|
+
const res = await this.rest.getData<IRssFeed[]>('apiplaylist/feed');
|
|
39
|
+
return res.ok ? res.result as IRssFeed[] : [];
|
|
40
|
+
}
|
|
41
|
+
async addFeed(url: string, save: boolean): Promise<IRssFeed|null> {
|
|
42
|
+
const res = await this.rest.postDataEx<boolean,IRssFeed>(`apiplaylist/feed?url=${encodeURIComponent(url)}&save=${save}`);
|
|
43
|
+
return res.ok ? (res.result as IValueResult<IRssFeed>).result : null;
|
|
37
44
|
}
|
|
45
|
+
async deleteFeed(title: string): Promise<boolean> {
|
|
46
|
+
const res = await this.rest.deleteData<any, boolean>(`apiplaylist/feed?title=${encodeURIComponent(title)}`);
|
|
47
|
+
return res.ok ? res.result as boolean : false;
|
|
48
|
+
}
|
|
49
|
+
*/
|
|
38
50
|
async play(url) {
|
|
39
|
-
this.soundbarOn = await this.
|
|
51
|
+
this.soundbarOn = await this.ensureSoundbarOn();
|
|
40
52
|
if (!this.soundbarOn)
|
|
41
53
|
return false;
|
|
42
54
|
const res = await this.rest.postData(`apiplaylist/play?url=${encodeURIComponent(url)}`);
|
|
43
55
|
return res.ok ? res.result : false;
|
|
44
56
|
}
|
|
45
57
|
async playList(urls, clear, index) {
|
|
46
|
-
this.soundbarOn = await this.
|
|
58
|
+
this.soundbarOn = await this.ensureSoundbarOn();
|
|
47
59
|
if (!this.soundbarOn)
|
|
48
60
|
return false;
|
|
49
61
|
let url = `apiplaylist/play?clear=${clear}`;
|
|
@@ -53,7 +65,7 @@ export class PlaylistService {
|
|
|
53
65
|
return res.ok ? res.result : false;
|
|
54
66
|
}
|
|
55
67
|
async playCommand(cmd) {
|
|
56
|
-
this.soundbarOn = await this.
|
|
68
|
+
this.soundbarOn = await this.ensureSoundbarOn();
|
|
57
69
|
if (!this.soundbarOn)
|
|
58
70
|
return false;
|
|
59
71
|
let url = `apiplaylist/playcommand?cmd=${EPlaylistCommand[cmd]}`;
|
|
@@ -61,15 +73,16 @@ export class PlaylistService {
|
|
|
61
73
|
return res.ok ? res.result : false;
|
|
62
74
|
}
|
|
63
75
|
async getState() {
|
|
76
|
+
this.soundbarVolume = Number(this.getSoundbarValue('Volume'));
|
|
64
77
|
const res = await this.rest.getData('apiplaylist/state');
|
|
65
78
|
return res.ok ? res.result : null;
|
|
66
79
|
}
|
|
67
|
-
async
|
|
80
|
+
async ensureSoundbarOn() {
|
|
68
81
|
let i = 0;
|
|
69
82
|
for (i = 0; i < 5; i++) {
|
|
70
|
-
if (this.getSoundbarValue('
|
|
83
|
+
if (this.getSoundbarValue('On') === true)
|
|
71
84
|
break;
|
|
72
|
-
const result = await this.setSoundbar('
|
|
85
|
+
const result = await this.setSoundbar('POWERON', '1');
|
|
73
86
|
await Helper.delay(1000);
|
|
74
87
|
}
|
|
75
88
|
if (i >= 5)
|
|
@@ -82,5 +95,9 @@ export class PlaylistService {
|
|
|
82
95
|
}
|
|
83
96
|
return false;
|
|
84
97
|
}
|
|
98
|
+
async setSoundbarVolume(value) {
|
|
99
|
+
const result = await this.setSoundbar('VOLUME', value.toString());
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
85
102
|
}
|
|
86
103
|
//# sourceMappingURL=playlistService.js.map
|
|
@@ -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,8 +11,11 @@
|
|
|
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);
|
|
@@ -22,27 +25,57 @@
|
|
|
22
25
|
const playLocal = computed(() => currentPlayer.value == 'Local');
|
|
23
26
|
const playIndex = ref(-1);
|
|
24
27
|
const itemIndex = ref(0);
|
|
25
|
-
const
|
|
28
|
+
const playingItem = ref<IRssItem|null>(null);
|
|
26
29
|
const position = ref(0);
|
|
27
30
|
const positionLength = ref(0);
|
|
28
31
|
const volume = ref(0);
|
|
29
32
|
const paused = ref(false);
|
|
33
|
+
const search = ref(true);
|
|
30
34
|
let statusTimer = 0;
|
|
35
|
+
let volumeTimer = 0;
|
|
36
|
+
let volumeCount = 0;
|
|
31
37
|
|
|
38
|
+
const positionText = computed(() => {
|
|
39
|
+
if (playingItem.value?.duration)
|
|
40
|
+
return toTime(position.value) + '/' + toTime(playingItem.value.duration);
|
|
41
|
+
else
|
|
42
|
+
return toTime(position.value);
|
|
43
|
+
});
|
|
32
44
|
|
|
45
|
+
const feedTypes = Helper.getEnumOptions(EFeedType);
|
|
46
|
+
const feedType = ref<EFeedType>(0);
|
|
47
|
+
const countries = ["", "AT", "DE", "US"];
|
|
48
|
+
const country = ref("");
|
|
49
|
+
const query = ref("");
|
|
50
|
+
const limit = ref(50);
|
|
33
51
|
|
|
34
52
|
onMounted(async () => {
|
|
35
|
-
playlistService.log.info('
|
|
36
|
-
|
|
37
|
-
feeds.splice(0, feeds.length, ...f);
|
|
38
|
-
computeListHeight();
|
|
53
|
+
playlistService.log.info('OnlinePodcastsPage created');
|
|
54
|
+
await start();
|
|
39
55
|
});
|
|
40
56
|
onUnmounted(() => {
|
|
41
57
|
if (statusTimer > 0) {
|
|
42
|
-
clearTimeout(statusTimer);
|
|
58
|
+
window.clearTimeout(statusTimer);
|
|
43
59
|
statusTimer = 0;
|
|
44
60
|
}
|
|
45
61
|
});
|
|
62
|
+
async function start() {
|
|
63
|
+
if (route.query?.rssUrl) {
|
|
64
|
+
const rssUrl = decodeURIComponent(route.query.rssUrl.toString());
|
|
65
|
+
const f = await playlistService.getFeed(rssUrl);
|
|
66
|
+
if (f && f.items) {
|
|
67
|
+
selectedFeed.value = f;
|
|
68
|
+
items.splice(0, items.length, ...f.items);
|
|
69
|
+
search.value = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
search.value = true;
|
|
74
|
+
}
|
|
75
|
+
computeListHeight();
|
|
76
|
+
}
|
|
77
|
+
watch(appState.bodyHeight, () => computeListHeight());
|
|
78
|
+
watch(() => route.query, () => start());
|
|
46
79
|
|
|
47
80
|
function computeListHeight() {
|
|
48
81
|
nextTick(() => {
|
|
@@ -53,43 +86,69 @@
|
|
|
53
86
|
listHeight.value = height;
|
|
54
87
|
})
|
|
55
88
|
}
|
|
89
|
+
async function onSearch() {
|
|
90
|
+
const dict: Dictionary<any> = {};
|
|
91
|
+
if (feedType.value != EFeedType.Unknown)
|
|
92
|
+
dict["media"] = EFeedType[feedType.value];
|
|
93
|
+
if (country.value != "")
|
|
94
|
+
dict["country"] = country.value;;
|
|
95
|
+
dict["query"] = query.value;
|
|
96
|
+
const fds = await playlistService.searchFeeds(dict, limit.value);
|
|
97
|
+
feeds.splice (0, feeds.length, ...fds);
|
|
98
|
+
}
|
|
56
99
|
async function play() {
|
|
57
100
|
if (playLocal.value) {
|
|
58
|
-
audio.value!.src =
|
|
101
|
+
audio.value!.src = selectedItem.value!.link;
|
|
59
102
|
audio.value!.load();
|
|
60
103
|
audio.value!.play().then(() => {
|
|
61
|
-
playlistService.log.trace(`play local ${
|
|
104
|
+
playlistService.log.trace(`play local ${selectedItem.value!.title}`)
|
|
62
105
|
});
|
|
106
|
+
playingItem.value = selectedItem.value;
|
|
63
107
|
}
|
|
64
108
|
else {
|
|
65
|
-
const rc = await playlistService.play(
|
|
109
|
+
const rc = await playlistService.play(selectedItem.value!.link);
|
|
66
110
|
if (!rc)
|
|
67
111
|
return;
|
|
112
|
+
playingItem.value = selectedItem.value;
|
|
68
113
|
await getStatus();
|
|
69
|
-
playlistService.log.trace(`play remote ${
|
|
114
|
+
playlistService.log.trace(`play remote ${selectedItem.value!.title}`);
|
|
70
115
|
}
|
|
71
|
-
|
|
72
|
-
itemIndex.value = playIndex.value = feeds.findIndex((f) => f.link == selected.value!.link);
|
|
116
|
+
itemIndex.value = playIndex.value = items.findIndex((f) => f.link == selectedItem.value!.link);
|
|
73
117
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
118
|
+
function listFeed(feed: IRssFeed) {
|
|
119
|
+
router.push ({path: 'onlinePodcasts', query: { rssUrl: feed.rssUrl }});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function listItem(item: IRssItem) {
|
|
123
|
+
selectedItem.value = item;
|
|
124
|
+
play();
|
|
125
|
+
computeListHeight();
|
|
77
126
|
}
|
|
78
127
|
function listBack() {
|
|
79
128
|
router.back();
|
|
80
129
|
}
|
|
81
130
|
async function getStatus() {
|
|
82
|
-
const
|
|
83
|
-
status.value =
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
const state = await playlistService.getState();
|
|
132
|
+
status.value = state;
|
|
133
|
+
if (state)
|
|
134
|
+
setPosition(Number(state.position));
|
|
135
|
+
if (volumeCount > 0)
|
|
136
|
+
volumeCount--;
|
|
137
|
+
else
|
|
138
|
+
volume.value = playlistService.soundbarVolume;
|
|
139
|
+
statusTimer = window.setTimeout(async () => getStatus(), 1000);
|
|
86
140
|
}
|
|
87
141
|
|
|
88
142
|
function toSubTitle(f: IRssFeed): string {
|
|
89
|
-
if (!f.duration)
|
|
143
|
+
if (!f || !f.duration)
|
|
90
144
|
return "";
|
|
91
|
-
|
|
92
|
-
|
|
145
|
+
return toTime(f.duration);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function toTime(s?: number): string {
|
|
149
|
+
if (!s)
|
|
150
|
+
return "";
|
|
151
|
+
let r = "";
|
|
93
152
|
s = Math.floor(s);
|
|
94
153
|
if (s >= 3600) {
|
|
95
154
|
r += Math.floor(s / 3600).toString() + ":"; s = s % 3600;
|
|
@@ -116,8 +175,8 @@
|
|
|
116
175
|
}
|
|
117
176
|
function setPosition(value: number) {
|
|
118
177
|
position.value = value;
|
|
119
|
-
if (
|
|
120
|
-
positionLength.value = position.value * 100 /
|
|
178
|
+
if (playingItem.value?.duration)
|
|
179
|
+
positionLength.value = position.value * 100 / playingItem.value!.duration;
|
|
121
180
|
else
|
|
122
181
|
positionLength.value = 0;
|
|
123
182
|
}
|
|
@@ -127,7 +186,7 @@
|
|
|
127
186
|
statusTimer = 0;
|
|
128
187
|
}
|
|
129
188
|
if (!playLocal.value) {
|
|
130
|
-
statusTimer = setTimeout(() => getStatus(), 1000);
|
|
189
|
+
statusTimer = window.setTimeout(() => getStatus(), 1000);
|
|
131
190
|
}
|
|
132
191
|
}
|
|
133
192
|
function playpause() {
|
|
@@ -154,36 +213,143 @@
|
|
|
154
213
|
function previous() {
|
|
155
214
|
if (playIndex.value <= 0)
|
|
156
215
|
return;
|
|
157
|
-
|
|
216
|
+
selectedItem.value = items[playIndex.value - 1];
|
|
158
217
|
play();
|
|
159
218
|
}
|
|
160
219
|
function next() {
|
|
161
|
-
if (playIndex.value >=
|
|
220
|
+
if (playIndex.value >= items.length - 1)
|
|
162
221
|
return;
|
|
163
|
-
|
|
222
|
+
selectedItem.value = items[playIndex.value + 1];
|
|
164
223
|
play();
|
|
165
224
|
}
|
|
166
|
-
function
|
|
225
|
+
async function stop() {
|
|
226
|
+
await playlistService.playCommand(EPlaylistCommand.Stop);
|
|
227
|
+
}
|
|
228
|
+
async function changeVolume() {
|
|
229
|
+
if (volumeTimer)
|
|
230
|
+
window.clearTimeout(volumeTimer);
|
|
231
|
+
|
|
232
|
+
volumeCount = 3;
|
|
233
|
+
volumeTimer = window.setTimeout(async () => {
|
|
234
|
+
await playlistService.setSoundbarVolume(volume.value);
|
|
235
|
+
volumeTimer = 0;
|
|
236
|
+
}, 500);
|
|
167
237
|
}
|
|
168
238
|
|
|
169
239
|
</script>
|
|
170
240
|
|
|
171
241
|
<template>
|
|
172
242
|
<v-card ref="listhead" class="bg-media_head">
|
|
243
|
+
<audio ref="audio" preload="none" @ended="onEnded" @timeupdate="onTimeUpdate">
|
|
244
|
+
</audio>
|
|
245
|
+
<v-container v-if="search" fluid>
|
|
246
|
+
<v-row class="align-center">
|
|
247
|
+
<v-col cols="1"></v-col>
|
|
248
|
+
<v-col cols="2">Type</v-col>
|
|
249
|
+
<v-col cols="1">Country</v-col>
|
|
250
|
+
<v-col cols="6">Query</v-col>
|
|
251
|
+
<v-col cols="1">Limit</v-col>
|
|
252
|
+
</v-row>
|
|
253
|
+
<v-row class="align-center">
|
|
254
|
+
<v-col cols="1">
|
|
255
|
+
</v-col>
|
|
256
|
+
<v-col cols="2">
|
|
257
|
+
<v-select density="compact" v-model="feedType"
|
|
258
|
+
:items="feedTypes"
|
|
259
|
+
persistent-hint hide-details single-line>
|
|
260
|
+
</v-select>
|
|
261
|
+
</v-col>
|
|
262
|
+
<v-col cols="1">
|
|
263
|
+
<v-combobox density="compact" v-model="country"
|
|
264
|
+
:items="countries"
|
|
265
|
+
persistent-hint hide-details single-line>
|
|
266
|
+
</v-combobox>
|
|
267
|
+
</v-col>
|
|
268
|
+
<v-col cols="6">
|
|
269
|
+
<v-text-field v-model="query" hide-details density="compact"></v-text-field>
|
|
270
|
+
</v-col>
|
|
271
|
+
<v-col cols="1">
|
|
272
|
+
<v-text-field v-model="limit" hide-details type="number" density="compact"></v-text-field>
|
|
273
|
+
</v-col>
|
|
274
|
+
<v-col cols="1">
|
|
275
|
+
<v-btn icon="$search" class="bg-media_head" variant="tonal" @click="onSearch">
|
|
276
|
+
</v-btn>
|
|
277
|
+
</v-col>
|
|
278
|
+
</v-row>
|
|
279
|
+
</v-container>
|
|
280
|
+
<v-container v-else fluid>
|
|
281
|
+
<v-row class="align-center">
|
|
282
|
+
<v-col cols="1">
|
|
283
|
+
<v-btn icon="$back" class="bg-media_head" variant="tonal" @click="listBack">
|
|
284
|
+
</v-btn>
|
|
285
|
+
</v-col>
|
|
286
|
+
<v-col cols="1">
|
|
287
|
+
<v-img :src="selectedFeed!.imageUrl"></v-img>
|
|
288
|
+
</v-col>
|
|
289
|
+
<v-col cols="1">{{selectedFeed!.country}}</v-col>
|
|
290
|
+
<v-col cols="2">{{selectedFeed!.genre}}</v-col>
|
|
291
|
+
<v-col cols="2">{{selectedFeed!.owner}}</v-col>
|
|
292
|
+
<v-col cols="4">{{selectedFeed!.title}}</v-col>
|
|
293
|
+
<v-col cols="1">
|
|
294
|
+
<v-select v-model="currentPlayer" density="compact" :items="playerNames" persistent-hint
|
|
295
|
+
@update:modelValue="onPlayerChange" hide-details single-line>
|
|
296
|
+
</v-select>
|
|
297
|
+
</v-col>
|
|
298
|
+
</v-row>
|
|
299
|
+
<v-row v-if="playingItem" class="align-center">
|
|
300
|
+
<v-col cols="4">
|
|
301
|
+
<v-btn :icon="paused ? '$play' : '$pause'" class="bg-media_head" variant="tonal" @click="playpause"></v-btn>
|
|
302
|
+
<v-btn v-if="!playLocal" icon="$stop" class="bg-media_head" variant="tonal" @click="stop"></v-btn>
|
|
303
|
+
<v-btn icon="$prev" class="bg-media_head" variant="tonal" @click="previous"></v-btn>
|
|
304
|
+
<v-btn icon="$next" class="bg-media_head" variant="tonal" @click="next"></v-btn>
|
|
305
|
+
</v-col>
|
|
306
|
+
<v-col cols ="8">
|
|
307
|
+
<v-slider v-if="!playLocal" style="width:30%" color="red" track-color="blue" track-fill-color="red" v-model="volume" hide-details density="compact"
|
|
308
|
+
min="0" max="100" step="5" @update:modelValue="changeVolume">
|
|
309
|
+
</v-slider>
|
|
310
|
+
<v-div v-else>{{playingItem.title}}</v-div>
|
|
311
|
+
</v-col>
|
|
312
|
+
</v-row>
|
|
313
|
+
<v-row v-if="playingItem">
|
|
314
|
+
<v-col cols="12">
|
|
315
|
+
<v-progress-linear v-model="positionLength" color="blue" height="25"><strong>{{positionText}}</strong></v-progress-linear>
|
|
316
|
+
</v-col>
|
|
317
|
+
</v-row>
|
|
318
|
+
</v-container>
|
|
319
|
+
</v-card>
|
|
320
|
+
<v-card :height="listHeight" density="compact" class="overflow-y-auto bg-media">
|
|
321
|
+
<v-container v-if="search" fluid>
|
|
322
|
+
<v-row v-for="(feed,index) in feeds" :key="feed.rssUrl" @click="listFeed(feed)">
|
|
323
|
+
<v-col cols="1">{{feed.country}}</v-col>
|
|
324
|
+
<v-col cols="2">{{feed.genre}}</v-col>
|
|
325
|
+
<v-col cols="2">{{feed.owner}}</v-col>
|
|
326
|
+
<v-col cols="5">{{feed.title}}</v-col>
|
|
327
|
+
</v-row>
|
|
328
|
+
</v-container>
|
|
329
|
+
<v-container v-else>
|
|
330
|
+
<v-row v-for="(item,index) in items" :key="item.title" :class="{ active: index == playIndex }" @click="listItem(item)">
|
|
331
|
+
<v-col cols="6">{{item.title}}</v-col>
|
|
332
|
+
<v-col cols="6">{{toTime(item.duration)}}</v-col>
|
|
333
|
+
</v-row>
|
|
334
|
+
</v-container>
|
|
335
|
+
</v-card>
|
|
336
|
+
|
|
337
|
+
<!--
|
|
338
|
+
<v-card class="bg-media_head">
|
|
173
339
|
<audio ref="audio" preload="none" @ended="onEnded" @timeupdate="onTimeUpdate">
|
|
174
340
|
</audio>
|
|
175
341
|
<v-list-item lines="three">
|
|
176
342
|
<v-list-item-content>
|
|
177
|
-
<v-list-item-title text-h6>{{selected
|
|
343
|
+
<v-list-item-title text-h6>{{selected?.title}}</v-list-item-title>
|
|
178
344
|
<v-list-item-subtitle>{{toSubTitle(selected!)}}</v-list-item-subtitle>
|
|
179
345
|
</v-list-item-content>
|
|
180
346
|
<template v-slot:append>
|
|
181
|
-
<v-select v-model="currentPlayer"
|
|
347
|
+
<v-select v-model="currentPlayer" density="compact"
|
|
182
348
|
:items="playerNames"
|
|
183
349
|
persistent-hint
|
|
184
350
|
@update:modelValue="onPlayerChange"
|
|
185
351
|
hide-details single-line>
|
|
186
|
-
</v-select
|
|
352
|
+
</v-select>
|
|
187
353
|
</template>
|
|
188
354
|
</v-list-item>
|
|
189
355
|
<v-card-actions>
|
|
@@ -209,11 +375,18 @@
|
|
|
209
375
|
<v-card :height="listHeight" density="compact" class="overflow-y-auto bg-media">
|
|
210
376
|
<v-list lines="two" class="bg-media">
|
|
211
377
|
<v-list-item-group v-model="itemIndex">
|
|
212
|
-
<v-list-item v-for="(
|
|
213
|
-
active-color="blue" :active="index == playIndex" @click="listItem(
|
|
378
|
+
<v-list-item v-for="(feed,index) in feeds" :key="feed.title" density="compact" :title="feed.title" :subtitle="toSubTitle(feed)"
|
|
379
|
+
active-color="blue" :active="index == playIndex" @click="listItem(feed)">
|
|
214
380
|
</v-list-item>
|
|
215
381
|
</v-list-item-group>
|
|
216
382
|
</v-list>
|
|
217
383
|
</v-card>
|
|
384
|
+
-->
|
|
218
385
|
</template>
|
|
219
386
|
|
|
387
|
+
<style scoped>
|
|
388
|
+
.active {
|
|
389
|
+
background-color: aliceblue;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
</style>
|