Merge branch 'develop' of https://github.com/ciderapp/Cider into develop

This commit is contained in:
yazninja 2022-04-23 20:45:29 +08:00
commit 17c5b8ffab
4 changed files with 107 additions and 24 deletions

View file

@ -108,9 +108,9 @@
} }
], ],
"build": { "build": {
"electronVersion": "18.0.3", "electronVersion": "18.0.4",
"electronDownload": { "electronDownload": {
"version": "18.0.3+wvcus", "version": "18.0.4+wvcus",
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v" "mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
}, },
"appId": "cider", "appId": "cider",

View file

@ -6,6 +6,8 @@ import * as CiderReceiver from '../base/castreceiver';
import fetch from 'electron-fetch'; import fetch from 'electron-fetch';
import {Stream} from "stream"; import {Stream} from "stream";
import {spawn} from 'child_process'; import {spawn} from 'child_process';
import {Worker} from 'worker_threads';
import { Blob } from 'buffer';
export default class RAOP { export default class RAOP {
@ -31,6 +33,60 @@ export default class RAOP {
private i: any = false; private i: any = false;
private audioStream: any = new Stream.PassThrough(); private audioStream: any = new Stream.PassThrough();
private ffmpeg: any = null; private ffmpeg: any = null;
private worker: any = null;
private processNode = `
import {parentPort, workerData} from "worker_threads";
function getAudioConv (buffers) {
function interleave16(leftChannel, rightChannel) {
var length = leftChannel.length + rightChannel.length;
var result = new Int16Array(length);
var inputIndex = 0;
for (var index = 0; index < length;) {
result[index++] = leftChannel[inputIndex];
result[index++] = rightChannel[inputIndex];
inputIndex++;
}
return result;
}
function convert(n) {
var v = n < 0 ? n * 32768 : n * 32767; // convert in range [-32768, 32767]
return Math.max(-32768, Math.min(32768, v)); // clamp
}
function bitratechange(e) {
var t = e.length;
let sampleRate = 96.0;
let outputSampleRate = 44.1;
var s = 0,
o = sampleRate / outputSampleRate,
u = Math.ceil(t * outputSampleRate / sampleRate),
a = new Int16Array(u);
for (let i = 0; i < u; i++) {
a[i] = e[Math.floor(s)];
s += o;
}
return a;
}
let newaudio = buffers;
let pcmData = new Int8Array(interleave16(bitratechange(Int16Array.from(newaudio[0], x => convert(x))), bitratechange(Int16Array.from(newaudio[1], x => convert(x)))).buffer);
return pcmData;
}
parentPort.on("message", data => {
parentPort.postMessage({buffer: data.buffer, outbuffer: getAudioConv(data.buffer)});
});
`;
private ondeviceup(name: any, host: any, port: any, addresses: any) { private ondeviceup(name: any, host: any, port: any, addresses: any) {
if (this.castDevices.findIndex((item: any) => item.name === host && item.port === port && item.addresses === addresses) === -1) { if (this.castDevices.findIndex((item: any) => item.name === host && item.port === port && item.addresses === addresses) === -1) {
@ -148,25 +204,52 @@ export default class RAOP {
}); });
electron.ipcMain.on('writeWAV', (event) => { electron.ipcMain.on('writeWAV', (event, leftbuffer, rightbuffer) => {
if (this.airtunes != null) { if (this.airtunes != null) {
if (!this.i){ if (this.worker == null) {
this.ffmpeg != null ? this.ffmpeg.kill() : null; try{
this.ffmpeg = spawn(this._utils.getStoreValue("advanced.ffmpegLocation"), [ const toDataUrl = (js: any) => new URL(`data:text/javascript,${encodeURIComponent(js)}`);
'-f', 's16le', // PCM 16bits, little-endian // let blob = new Blob([this.processNode], { type: 'application/javascript' });
'-ar', '48000', //Create new worker
'-ac', "2", this.worker = new Worker(toDataUrl(this.processNode));
'-i', "http://localhost:9000/audio.wav",
'-acodec', 'pcm_s16le', //Listen for a message from worker
'-f', 's16le', // PCM 16bits, little-endian this.worker.on("message", (result: any) => {
'-ar', '44100', // Sampling rate // fs.writeFile(join(electron.app.getPath('userData'), 'buffer.raw'), Buffer.from(Int8Array.from(result.outbuffer)),{flag: 'a+'}, function (err) {
'-ac', "2", // Stereo // if (err) throw err;
'pipe:1' // Output on stdout // console.log('It\'s saved!');
]); // });
this.airtunes.circularBuffer.write(Buffer.from(Int8Array.from(result.outbuffer)));
});
this.worker.on("error", (error: any) => {
console.log("bruh",error);
});
this.worker.postMessage({buffer: [leftbuffer, rightbuffer]});
} catch (e){console.log(e)}
// pipe data to AirTunes
this.ffmpeg.stdout.pipe(this.airtunes); // this.ffmpeg != null ? this.ffmpeg.kill() : null;
this.i = true;}} // this.ffmpeg = spawn(this._utils.getStoreValue("advanced.ffmpegLocation"), [
// '-f', 's16le', // PCM 16bits, little-endian
// '-ar', '48000',
// '-ac', "2",
// '-err_detect','ignore_err',
// '-i', "http://localhost:9000/audio.wav",
// '-acodec', 'pcm_s16le',
// '-f', 's16le', // PCM 16bits, little-endian
// '-ar', '44100', // Sampling rate
// '-ac', "2", // Stereo
// 'pipe:1' // Output on stdout
// ]);
// // pipe data to AirTunes
// this.ffmpeg.stdout.pipe(this.airtunes);
// this.i = true;
} else {
this.worker.postMessage({buffer: [leftbuffer, rightbuffer]});
}
}
}); });
@ -256,4 +339,4 @@ export default class RAOP {
} }
} }
} }

View file

@ -37,9 +37,9 @@
<div class="md-option-container" style="margin-top: 12px;margin-bottom: 12px;"> <div class="md-option-container" style="margin-top: 12px;margin-bottom: 12px;">
<div class="md-option-line"> <div class="md-option-line">
<div class="md-option-segment"> <div class="md-option-segment">
{{$root.cfg.advanced.ffmpegLocation != "" ? 'Homepods only for now! (NO PASSWORD PLEASE!)' : 'Please add FFmpeg location in Settings -> Advanced'}} {{true ? 'Homepods only for now! (NO PASSWORD PLEASE!)' : 'Please add FFmpeg location in Settings -> Advanced'}}
<!-- {{$root.getLz('action.cast.airplay.underdevelopment')}} --> <!-- {{$root.getLz('action.cast.airplay.underdevelopment')}} -->
<template v-if="$root.cfg.advanced.ffmpegLocation != ''" v-for="(device) in devices.airplay"> <template v-if="true" v-for="(device) in devices.airplay">
<div class="md-option-line" style="cursor: pointer" @click="setAirPlayCast(device)"> <div class="md-option-line" style="cursor: pointer" @click="setAirPlayCast(device)">
<div class="md-option-segment"> <div class="md-option-segment">
{{ device.name }} {{ device.name }}

View file

@ -1,7 +1,7 @@
{ {
"electronVersion": "18.0.3", "electronVersion": "18.0.4",
"electronDownload": { "electronDownload": {
"version": "18.0.3+wvcus", "version": "18.0.4+wvcus",
"mirror": "https://github.com/castlabs/electron-releases/releases/download/v" "mirror": "https://github.com/castlabs/electron-releases/releases/download/v"
}, },
"appId": "cider", "appId": "cider",