local backend
This commit is contained in:
parent
0d9236a4ad
commit
0b57e22e55
3 changed files with 122 additions and 7 deletions
|
@ -14,7 +14,7 @@ import {
|
||||||
statSync,
|
statSync,
|
||||||
unlinkSync,
|
unlinkSync,
|
||||||
rmdirSync,
|
rmdirSync,
|
||||||
lstatSync
|
lstatSync,
|
||||||
} from "fs";
|
} from "fs";
|
||||||
import {Stream} from "stream";
|
import {Stream} from "stream";
|
||||||
import {networkInterfaces} from "os";
|
import {networkInterfaces} from "os";
|
||||||
|
@ -27,6 +27,8 @@ import {watch} from "chokidar";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
import wallpaper from "wallpaper";
|
import wallpaper from "wallpaper";
|
||||||
import * as AdmZip from "adm-zip";
|
import * as AdmZip from "adm-zip";
|
||||||
|
import * as path from 'path';
|
||||||
|
const { readdir } = require('fs').promises;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +44,7 @@ export class BrowserWindow {
|
||||||
private audioStream: any = new Stream.PassThrough();
|
private audioStream: any = new Stream.PassThrough();
|
||||||
private headerSent: any = false;
|
private headerSent: any = false;
|
||||||
private chromecastIP: any = [];
|
private chromecastIP: any = [];
|
||||||
|
private localSongs: any = [];
|
||||||
private clientPort: number = 0;
|
private clientPort: number = 0;
|
||||||
private remotePort: number = 6942;
|
private remotePort: number = 6942;
|
||||||
private EnvironmentVariables: object = {
|
private EnvironmentVariables: object = {
|
||||||
|
@ -543,6 +546,13 @@ export class BrowserWindow {
|
||||||
res.send(`// Theme not found - ${userThemePath}`);
|
res.send(`// Theme not found - ${userThemePath}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
app.get("/ciderlocal/:songs", (req, res) => {
|
||||||
|
const audio = atob(req.params.songs);
|
||||||
|
let data = {data:
|
||||||
|
this.localSongs.filter((f: any) => audio.split(',').includes(f.id))};
|
||||||
|
res.send(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
app.get("/themes/:theme/*", (req: { params: { theme: string, 0: string } }, res) => {
|
app.get("/themes/:theme/*", (req: { params: { theme: string, 0: string } }, res) => {
|
||||||
const theme = req.params.theme;
|
const theme = req.params.theme;
|
||||||
|
@ -647,7 +657,7 @@ export class BrowserWindow {
|
||||||
// intercept "https://js-cdn.music.apple.com/hls.js/2.141.1/hls.js/hls.js" and redirect to local file "./apple-hls.js" instead
|
// intercept "https://js-cdn.music.apple.com/hls.js/2.141.1/hls.js/hls.js" and redirect to local file "./apple-hls.js" instead
|
||||||
BrowserWindow.win.webContents.session.webRequest.onBeforeRequest(
|
BrowserWindow.win.webContents.session.webRequest.onBeforeRequest(
|
||||||
{
|
{
|
||||||
urls: ["https://*/*.js"],
|
urls: ["https://*/*"],
|
||||||
},
|
},
|
||||||
(
|
(
|
||||||
details: { url: string | string[] },
|
details: { url: string | string[] },
|
||||||
|
@ -657,6 +667,12 @@ export class BrowserWindow {
|
||||||
callback({
|
callback({
|
||||||
redirectURL: `http://localhost:${this.clientPort}/apple-hls.js`,
|
redirectURL: `http://localhost:${this.clientPort}/apple-hls.js`,
|
||||||
});
|
});
|
||||||
|
} else if (details.url.includes("ciderlocal")) {
|
||||||
|
let text = details.url.toString().includes('ids=') ? decodeURIComponent(details.url.toString()).split("?ids=")[1] : decodeURIComponent(details.url.toString().substring(details.url.toString().lastIndexOf('/') + 1));
|
||||||
|
console.log('localurl',text)
|
||||||
|
callback({
|
||||||
|
redirectURL: `http://localhost:${this.clientPort}/ciderlocal/${btoa(text)}`,
|
||||||
|
});
|
||||||
}else {
|
}else {
|
||||||
callback({
|
callback({
|
||||||
cancel: false,
|
cancel: false,
|
||||||
|
@ -1158,6 +1174,104 @@ export class BrowserWindow {
|
||||||
`)
|
`)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
ipcMain.on("scanLibrary", async (event, folders) => {
|
||||||
|
async function getFiles(dir : any) {
|
||||||
|
const dirents = await readdir(dir, { withFileTypes: true });
|
||||||
|
const files = await Promise.all(dirents.map((dirent: any) => {
|
||||||
|
const res = path.resolve(dir, dirent.name);
|
||||||
|
return dirent.isDirectory() ? getFiles(res) : res;
|
||||||
|
}));
|
||||||
|
return Array.prototype.concat(...files);
|
||||||
|
}
|
||||||
|
if (folders == null || folders.length == null || folders.length == 0) folders = ["D:\\Music"]
|
||||||
|
console.log('folders', folders)
|
||||||
|
let files: any[] = []
|
||||||
|
for (var folder of folders){
|
||||||
|
// get files from the Music folder
|
||||||
|
files = files.concat(await getFiles(folder))
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("cider.files", files2);
|
||||||
|
let supporttedformats = ["mp3", "aac", "webm", "flac", "m4a", "ogg", "wav", "opus"]
|
||||||
|
let audiofiles = files.filter(f => supporttedformats.includes(f.substring(f.lastIndexOf('.') + 1)));
|
||||||
|
// console.log("cider.files2", audiofiles, audiofiles.length);
|
||||||
|
let metadatalist = []
|
||||||
|
let numid = 0;
|
||||||
|
for (var audio of audiofiles) {
|
||||||
|
try{
|
||||||
|
const metadata = await mm.parseFile(audio);
|
||||||
|
if (metadata != null){
|
||||||
|
let form = {
|
||||||
|
"id": "ciderlocal" + numid,
|
||||||
|
"type": "podcast-episodes",
|
||||||
|
"href": audio,
|
||||||
|
"attributes": {
|
||||||
|
"artwork": {
|
||||||
|
"width": 3000,
|
||||||
|
"height": 3000,
|
||||||
|
"url": metadata.common.picture != undefined ? "data:image/png;base64,"+metadata.common.picture[0].data.toString('base64')+"" : "",
|
||||||
|
},
|
||||||
|
"topics": [],
|
||||||
|
"url": "",
|
||||||
|
"subscribable": true,
|
||||||
|
"mediaKind": "audio",
|
||||||
|
"genreNames": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
// "playParams": {
|
||||||
|
// "id": "ciderlocal" + numid,
|
||||||
|
// "kind": "episode",
|
||||||
|
// "isLibrary": false,
|
||||||
|
// "reporting": false },
|
||||||
|
"trackNumber": metadata.common.track?.no ?? 0,
|
||||||
|
"discNumber": metadata.common.disk?.no ?? 0,
|
||||||
|
"name": metadata.common.title,
|
||||||
|
"albumName": metadata.common.album,
|
||||||
|
"artistName": metadata.common.artist,
|
||||||
|
"copyright": metadata.common.copyright ?? "",
|
||||||
|
"assetUrl": "file:///" +audio,
|
||||||
|
"contentAdvisory": "",
|
||||||
|
"releaseDateTime": "2022-05-13T00:23:00Z",
|
||||||
|
"durationInMilliseconds": Math.floor((metadata.format.duration?? 0) * 1000),
|
||||||
|
|
||||||
|
"offers": [
|
||||||
|
{
|
||||||
|
"kind": "get",
|
||||||
|
"type": "STDQ"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contentRating": "clean"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
numid += 1;
|
||||||
|
|
||||||
|
// let form = {"id": "/ciderlocal?" + audio,
|
||||||
|
// "type": "library-songs",
|
||||||
|
// "href": "/ciderlocal?" + audio,
|
||||||
|
// "artwork": {
|
||||||
|
// "url": metadata.common.picture != undefined ? "data:image/png;base64,"+metadata.common.picture[0].data.toString('base64')+"" : "",
|
||||||
|
// },
|
||||||
|
// "attributes":
|
||||||
|
// { "durationInMillis": Math.floor((metadata.format.duration?? 0) * 1000),
|
||||||
|
// "hasLyrics": false,
|
||||||
|
// "playParams": { "id": "/ciderlocal?" + audio, "kind": "song", "isLibrary": true, "reporting": false },
|
||||||
|
// "trackNumber": 0,
|
||||||
|
// "discNumber": 0,
|
||||||
|
// "genreNames": [""],
|
||||||
|
// "name": metadata.common.title,
|
||||||
|
// "albumName": metadata.common.album,
|
||||||
|
// "artistName": metadata.common.artist}}
|
||||||
|
metadatalist.push(form)}
|
||||||
|
} catch (e){}
|
||||||
|
}
|
||||||
|
// console.log('metadatalist', metadatalist);
|
||||||
|
this.localSongs = metadatalist;
|
||||||
|
BrowserWindow.win.webContents.send('getUpdatedLocalList', metadatalist);
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
ipcMain.on('writeWAV', (event, leftpcm, rightpcm, bufferlength) => {
|
ipcMain.on('writeWAV', (event, leftpcm, rightpcm, bufferlength) => {
|
||||||
|
|
||||||
function interleave16(leftChannel: any, rightChannel: any) {
|
function interleave16(leftChannel: any, rightChannel: any) {
|
||||||
|
|
|
@ -117,6 +117,7 @@ const app = new Vue({
|
||||||
displayListing: [],
|
displayListing: [],
|
||||||
downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library
|
downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library
|
||||||
},
|
},
|
||||||
|
localsongs : []
|
||||||
},
|
},
|
||||||
playlists: {
|
playlists: {
|
||||||
listing: [],
|
listing: [],
|
||||||
|
@ -705,9 +706,6 @@ const app = new Vue({
|
||||||
// Set mk.volume to -1 (setting to 0 wont work, so temp solution setting to -1)
|
// Set mk.volume to -1 (setting to 0 wont work, so temp solution setting to -1)
|
||||||
this.mk.volume = -1;
|
this.mk.volume = -1;
|
||||||
}
|
}
|
||||||
// ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => {
|
|
||||||
// self.mk.volume = value
|
|
||||||
// })
|
|
||||||
|
|
||||||
// load cached library
|
// load cached library
|
||||||
let librarySongs = await CiderCache.getCache("library-songs")
|
let librarySongs = await CiderCache.getCache("library-songs")
|
||||||
|
@ -831,6 +829,9 @@ const app = new Vue({
|
||||||
userid: user.id
|
userid: user.id
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
ipcRenderer.on('getUpdatedLocalList', (event,data) => {
|
||||||
|
console.log("cider-local",data);
|
||||||
|
this.library.localsongs = data;
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcRenderer.on('SoundCheckTag', (event, tag) => {
|
ipcRenderer.on('SoundCheckTag', (event, tag) => {
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
<transition name="wpfade">
|
<transition name="wpfade">
|
||||||
<div class="podcasts-details" v-if="selected.id != -1">
|
<div class="podcasts-details" v-if="selected.id != -1">
|
||||||
<div class="podcasts-details-header">
|
<div class="podcasts-details-header">
|
||||||
<button class="close-btn" @click="selected.id = -1" :aria-label="app.getLz('action.close')"></button>
|
<button class="close-btn" @click="selected.id = -1" :aria-label="$root.getLz('action.close')"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="podcast-artwork">
|
<div class="podcast-artwork">
|
||||||
<mediaitem-artwork shadow="large" :url="selected.attributes.artwork.url" size="300"></mediaitem-artwork>
|
<mediaitem-artwork shadow="large" :url="selected.attributes.artwork.url" size="300"></mediaitem-artwork>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue