mirror of
https://github.com/danbulant/colors
synced 2026-05-19 04:08:35 +00:00
basic formatting
This commit is contained in:
parent
09cb648e5b
commit
fd5bc47cb7
11 changed files with 132 additions and 58 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
/node_modules
|
||||
/pnpm-lock.yaml
|
||||
/pnpm-lock.yaml
|
||||
dist
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"typescript.preferences.importModuleSpecifierEnding": "js"
|
||||
}
|
||||
11
README.md
Normal file
11
README.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# PS4 controller colors
|
||||
|
||||
I had the great idea to programatically set colors of my PS4 controller.
|
||||
|
||||
It's not supposed to be easy to setup, but if you need help just contact me. For now, scripts try to find all the connected joy sticks (doesn't filter by type) and set their LEDs (No idea what happens if a joystick doesn't have one), and then sets colors on them.
|
||||
|
||||
Project highly depends on linux (uses sys class to control the LEDs) and requires root (non-root operations are setuid'd internally).
|
||||
|
||||
## Spotify colors
|
||||
|
||||
Uses DBUS which needs your username. For now just edit the utils function getUsername to return your username.
|
||||
28
index.ts
28
index.ts
|
|
@ -1,28 +0,0 @@
|
|||
import { JoyStick } from "./joystick";
|
||||
|
||||
const devices = await JoyStick.getList();
|
||||
|
||||
for(const device of devices) {
|
||||
const colors = await device.getColors();
|
||||
const max = await device.getMaxColors();
|
||||
console.log(`Found device ${device.name}:
|
||||
Colors:
|
||||
RED ${colors.red}
|
||||
GREEN ${colors.green}
|
||||
BLUE ${colors.blue}
|
||||
Max colors:
|
||||
RED ${max.red}
|
||||
GREEN ${max.green}
|
||||
BLUE ${max.blue}`)
|
||||
const newColors = {
|
||||
red: Math.floor(Math.random() * max.red),
|
||||
green: Math.floor(Math.random() * max.green),
|
||||
blue: Math.floor(Math.random() * max.blue),
|
||||
};
|
||||
await device.setColors(newColors);
|
||||
console.log(`
|
||||
Updated colors:
|
||||
RED ${newColors.red}
|
||||
GREEN ${newColors.green}
|
||||
BLUE ${newColors.blue}`);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { exec, readUTF, writeUTF } from "./utils";
|
||||
import { exec, readUTF, writeUTF } from "./utils.js";
|
||||
import * as fs from "fs";
|
||||
|
||||
interface IJoyStick {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@types/node": "^16.9.1",
|
||||
"got": "^11.8.2",
|
||||
"node-vibrant": "^3.2.1-alpha.1"
|
||||
}
|
||||
"node-vibrant": "^3.2.1-alpha.1",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
|
|||
21
spotify.ts
21
spotify.ts
|
|
@ -1,21 +0,0 @@
|
|||
import { exec } from "./utils";
|
||||
|
||||
interface Track {
|
||||
length: number;
|
||||
artURL: string;
|
||||
id: string;
|
||||
url: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
albumArtist: string;
|
||||
}
|
||||
|
||||
class Spotify {
|
||||
async getCurrentTrack() {
|
||||
const data: Record<string, string> = {};
|
||||
const out = await exec(["qdbus", "org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.Metadata"]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default new Spotify();
|
||||
48
spotifyColors/index.ts
Normal file
48
spotifyColors/index.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { JoyStick } from "../joystick.js";
|
||||
import spotify from "./spotify.js";
|
||||
import { getColor, lerp } from "../utils.js";
|
||||
|
||||
type ThenArg<T> = T extends PromiseLike<infer U> ? U : T;
|
||||
type Palette = ThenArg<ReturnType<typeof getColor>>;
|
||||
|
||||
const devices = await JoyStick.getList();
|
||||
var color: Palette, lastURL: string, lastColor: Palette["DarkMuted"];
|
||||
|
||||
const perColor = 1000;
|
||||
|
||||
setInterval(async () => {
|
||||
const track = await spotify.getCurrentTrack();
|
||||
if(lastURL !== track.artURL) {
|
||||
console.log("Track:", track.artist, "-", track.title);
|
||||
color = await getColor(track.artURL);
|
||||
lastURL = track.artURL;
|
||||
}
|
||||
|
||||
function transitionColors(startColor: Palette["DarkMuted"], endColor: Palette["DarkMuted"]) {
|
||||
return new Promise<void>((resolve) => {
|
||||
const start = Date.now();
|
||||
var i = setInterval(async() => {
|
||||
if(start + perColor < Date.now()) {
|
||||
resolve();
|
||||
return clearInterval(i);
|
||||
}
|
||||
const progress = (Date.now() - start) / perColor;
|
||||
|
||||
const newColors = {
|
||||
red: Math.round(lerp(startColor.r, endColor.r, progress)),
|
||||
green: Math.round(lerp(startColor.g, endColor.g, progress)),
|
||||
blue: Math.round(lerp(startColor.b, endColor.b, progress)),
|
||||
};
|
||||
|
||||
for(const device of devices) {
|
||||
await device.setColors(newColors);
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
}
|
||||
|
||||
await transitionColors(lastColor || color.LightMuted, color.LightVibrant);
|
||||
await transitionColors(color.LightVibrant, color.Vibrant);
|
||||
await transitionColors(color.Vibrant, color.DarkVibrant);
|
||||
lastColor = color.DarkVibrant;
|
||||
}, perColor * 3);
|
||||
37
spotifyColors/spotify.ts
Normal file
37
spotifyColors/spotify.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { exec, getCurrentUser } from "../utils.js";
|
||||
|
||||
interface Track {
|
||||
length: number;
|
||||
title: string;
|
||||
artURL: string;
|
||||
id: string;
|
||||
url: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
albumArtist: string;
|
||||
}
|
||||
|
||||
class Spotify {
|
||||
async getCurrentTrack() {
|
||||
const data: Record<string, string> = {};
|
||||
const out = await exec(["machinectl", "shell", "--uid=" + await getCurrentUser(), ".host", "/usr/bin/qdbus", "org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.Metadata"]);
|
||||
for(const line of out.split("\n")) {
|
||||
const key = line.substr(0, line.indexOf(" ")).trim();
|
||||
if(!key) continue;
|
||||
const value = line.substr(line.indexOf(" ") + 1).trim();
|
||||
data[key] = value;
|
||||
}
|
||||
return {
|
||||
length: Number(data["mpris:length:"]),
|
||||
title: data["xesam:title:"],
|
||||
artURL: data["mpris:artUrl:"],
|
||||
id: data["mpris:trackid:"],
|
||||
url: data["xesam:url:"],
|
||||
artist: data["xesam:artist:"],
|
||||
album: data["xesam:album:"],
|
||||
albumArtist: data["xesam:albumArtist:"]
|
||||
} as Track;
|
||||
}
|
||||
}
|
||||
|
||||
export default new Spotify();
|
||||
|
|
@ -1,8 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"allowJs": true,
|
||||
"target": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist"
|
||||
},
|
||||
"buildOptions": {
|
||||
"incremental": true
|
||||
},
|
||||
"ts-node": {}
|
||||
}
|
||||
18
utils.ts
18
utils.ts
|
|
@ -7,25 +7,37 @@ export async function readUTF(file: string) {
|
|||
return await afs.readFile(file, { encoding: "utf-8" }) as string;
|
||||
}
|
||||
export async function writeUTF(file: string, data: string) {
|
||||
return await afs.writeFile(file, data);
|
||||
await afs.writeFile(file, data);
|
||||
}
|
||||
|
||||
export function exec(cmd: string[]) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
var output = "";
|
||||
var error = "";
|
||||
const p = spawn(cmd.shift(), cmd);
|
||||
p.stdout.on("data", (chunk) => output += chunk);
|
||||
p.stderr.on("data", (chunk) => error += chunk);
|
||||
|
||||
p.on("exit", (code) => {
|
||||
if(code) return reject(code);
|
||||
if(code) return reject(error);
|
||||
resolve(output);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCurrentUser() {
|
||||
return "dan";
|
||||
}
|
||||
|
||||
export async function getColor(image: string) {
|
||||
var resp = await got(image, {
|
||||
responseType: "buffer"
|
||||
});
|
||||
var vibrant = new Vibrant(resp.body);
|
||||
var color = await vibrant.getPalette();
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
export function lerp(a: number, b: number, u: number) {
|
||||
return (1 - u) * a + u * b;
|
||||
};
|
||||
Loading…
Reference in a new issue