« get me outta code hell

interactive-bgm - Browser extension that adds background music based on the site you're browsing
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README.md11
-rw-r--r--extension/background.js42
-rw-r--r--extension/borderify.js3
-rw-r--r--extension/icons/beasts-32.pngbin0 -> 1093 bytes
-rw-r--r--extension/manifest.json36
-rw-r--r--extension/popup/index.html1
-rw-r--r--index.js113
-rwxr-xr-xnative-app/index.js122
-rw-r--r--native-app/manifest.json7
-rw-r--r--package-lock.json21
-rw-r--r--package.json14
-rwxr-xr-xtrack1.wavbin0 -> 29635016 bytes
-rwxr-xr-xtrack2.wavbin0 -> 29635016 bytes
-rwxr-xr-xtrack3.wavbin0 -> 29635016 bytes
15 files changed, 372 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cf5c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/node_modules
+/native-app/log
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f8e1753
--- /dev/null
+++ b/README.md
@@ -0,0 +1,11 @@
+# Interactive BGM
+
+Adds background music to your browsing.
+
+## Installation
+
+Modfy `native-app/index.js` to have the proper paths and filenames.
+
+Copy (or link) `native-app/interactive_bgm.json` into `~/.mozilla/native-messaging-hosts/`. Open `about:debugging`, click "Load Temporary Add-on...", and pick `extension/manifest.json`.
+
+(The music files included here, while WIP, are ripped from Hollow Knight.)
diff --git a/extension/background.js b/extension/background.js
new file mode 100644
index 0000000..b23c38b
--- /dev/null
+++ b/extension/background.js
@@ -0,0 +1,42 @@
+console.log('Start');
+
+const port = browser.runtime.connectNative('interactive_bgm');
+
+browser.browserAction.onClicked.addListener(() => {
+    console.log('Hello??');
+    // port.postMessage('[{"track": "mantis", "volume": 100}]\n');
+});
+
+console.log('Hi', port);
+
+port.postMessage('[{"track": "mantis", "volume": 100}]\n');
+
+port.onMessage.addListener(msg => {
+    console.log('Nyoom', msg);
+});
+
+/*
+setTimeout(() => {
+    port.disconnect();
+}, 4000);
+*/
+
+port.onDisconnect.addListener(() => {
+    console.log('Disconnected');
+});
+
+browser.runtime.onMessage.addListener(({hostname}) => {
+    const map = {
+        'scratch.mit.edu': ['mantis'],
+        'stackoverflow.com': ['bass', 'main']
+    };
+
+    const mode = map[hostname];
+
+    if (mode) {
+        console.log('BGM:', mode);
+        port.postMessage(mode.map(track => ({track, volume: 100})));
+    } else {
+        console.log('No BGM found for ' + location.hostname);
+    }
+});
diff --git a/extension/borderify.js b/extension/borderify.js
new file mode 100644
index 0000000..032dc19
--- /dev/null
+++ b/extension/borderify.js
@@ -0,0 +1,3 @@
+window.addEventListener('focus', () => {
+    browser.runtime.sendMessage({hostname: location.hostname});
+});
diff --git a/extension/icons/beasts-32.png b/extension/icons/beasts-32.png
new file mode 100644
index 0000000..89863cc
--- /dev/null
+++ b/extension/icons/beasts-32.png
Binary files differdiff --git a/extension/manifest.json b/extension/manifest.json
new file mode 100644
index 0000000..27cafda
--- /dev/null
+++ b/extension/manifest.json
@@ -0,0 +1,36 @@
+{
+    "manifest_version": 2,
+    "name": "Interactive BGM",
+    "version": "1.0",
+
+    "description": "Adds a red border to all webpages matching mozilla.org.",
+
+    "permissions": [
+        "activeTab",
+        "nativeMessaging"
+    ],
+
+    "applications": {
+        "gecko": {
+            "id": "interactive_bgm@florrie.ed1.club",
+            "strict_min_version": "50.0"
+        }
+    },
+
+    "browser_action": {
+        "default_icon": "icons/beasts-32.png",
+        "default_title": "Interactive BGM",
+        "default_popup": "popup/index.html"
+    },
+
+    "content_scripts": [
+        {
+            "matches": ["<all_urls>"],
+            "js": ["borderify.js"]
+        }
+    ],
+
+    "background": {
+        "scripts": ["background.js"]
+    }
+}
diff --git a/extension/popup/index.html b/extension/popup/index.html
new file mode 100644
index 0000000..e6cf5e5
--- /dev/null
+++ b/extension/popup/index.html
@@ -0,0 +1 @@
+<p>Nice.</p>
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..72beebf
--- /dev/null
+++ b/index.js
@@ -0,0 +1,113 @@
+const { spawn } = require('child_process');
+const FIFO = require('fifo-js');
+const http = require('http');
+
+class TrackPlayer {
+    constructor(file) {
+        this.file = file;
+        this.volume = 0;
+        this.storedVolume = this.volume;
+    }
+
+    loadProcess() {
+        this.fifo = new FIFO();
+        this.process = spawn('mpv', [
+            '--no-video',
+            '--loop',
+            '--volume=' + this.volume,
+            '--input-file=' + this.fifo.path,
+            this.file,
+        ]);
+
+        this.process.stderr.pipe(process.stderr);
+    }
+
+    sendCommand(command) {
+        if (this.fifo) {
+            this.fifo.write(command);
+        }
+    }
+
+    seekToStart() {
+        this.sendCommand('seek 0 absolute');
+    }
+
+    pause() {
+        this.sendCommand('set pause yes');
+    }
+
+    play() {
+        this.sendCommand('set pause no');
+    }
+
+    setVolume(volume) {
+        if (Math.floor(volume) !== this.storedVolume) {
+            this.storedVolume = Math.floor(volume);
+            this.sendCommand(`set volume ${volume}`);
+        }
+        this.volume = volume;
+    }
+}
+
+const tracks = {
+    mantis: new TrackPlayer('track1.wav'),
+    bass: new TrackPlayer('track2.wav'),
+    main: new TrackPlayer('track3.wav')
+};
+
+for (const track of Object.values(tracks)) {
+    track.loadProcess();
+    track.pause();
+}
+
+setTimeout(() => {
+    for (const track of Object.values(tracks)) {
+        track.seekToStart();
+        track.play();
+    }
+
+    let targetMode = [
+        {track: 'main', volume: 100}
+    ];
+
+    setInterval(() => {
+        if (!Array.isArray(targetMode)) {
+            console.log('targetMode is not an array.');
+            targetMode = [];
+        }
+
+        for (const [key, track] of Object.entries(tracks)) {
+            const mode = targetMode.find(m => m.track === key) || {volume: 0};
+            track.setVolume(track.volume + 0.1 * (mode.volume - track.volume));
+        }
+    }, 100);
+
+    const server = http.createServer((request, response) => {
+        response.setHeader('Access-Control-Allow-Origin', '*');
+        response.setHeader('Access-Control-Allow-Headers', 'Authorization, Cache-Control, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');
+        console.log('Got request.');
+
+        if (request.method === 'GET') {
+            response.write('Please use POST.');
+            response.end();
+        } else if (request.method === 'POST') {
+            let allData = '';
+            request.on('data', data => {
+                allData += data;
+            });
+            request.on('end', () => {
+                try {
+                    targetMode = JSON.parse(allData);
+                    response.write('Set.');
+                } catch (error) {
+                    response.write('Invalid JSON.');
+                }
+                response.end();
+            });
+        } else {
+            response.end();
+        }
+    });
+
+    server.listen(8000);
+}, 250);
diff --git a/native-app/index.js b/native-app/index.js
new file mode 100755
index 0000000..2f174ea
--- /dev/null
+++ b/native-app/index.js
@@ -0,0 +1,122 @@
+#!/usr/bin/env node
+
+const basePath = '/home/florrie/Documents/interactive-bgm';
+
+const logFile = basePath + '/native-app/log';
+
+const log = msg => {
+    require('fs').appendFileSync(logFile, msg + '\n');
+};
+
+
+log('Started ' + Date());
+
+const { spawn } = require('child_process');
+const EventEmitter = require('events');
+const FIFO = require('fifo-js');
+const http = require('http');
+
+log('Loaded modules');
+
+class TrackPlayer {
+    constructor(file) {
+        this.file = file;
+        this.volume = 0;
+        this.storedVolume = this.volume;
+    }
+
+    loadProcess() {
+        this.fifo = new FIFO();
+        this.process = spawn('mpv', [
+            '--no-video',
+            '--loop',
+            '--volume=' + this.volume,
+            '--input-file=' + this.fifo.path,
+            this.file,
+        ]);
+
+        const stream = new EventEmitter();
+        stream.write = () => {};
+        this.process.stderr.pipe(stream);
+    }
+
+    sendCommand(command) {
+        if (this.fifo) {
+            this.fifo.write(command);
+        }
+    }
+
+    seekToStart() {
+        this.sendCommand('seek 0 absolute');
+    }
+
+    pause() {
+        this.sendCommand('set pause yes');
+    }
+
+    play() {
+        this.sendCommand('set pause no');
+    }
+
+    setVolume(volume) {
+        if (Math.floor(volume) !== this.storedVolume) {
+            this.storedVolume = Math.floor(volume);
+            this.sendCommand(`set volume ${volume}`);
+        }
+        this.volume = volume;
+    }
+}
+
+const tracks = {
+    mantis: new TrackPlayer(basePath + '/track1.wav'),
+    bass: new TrackPlayer(basePath + '/track2.wav'),
+    main: new TrackPlayer(basePath + '/track3.wav')
+};
+
+for (const track of Object.values(tracks)) {
+    track.loadProcess();
+    track.pause();
+}
+
+setTimeout(() => {
+    for (const track of Object.values(tracks)) {
+        track.seekToStart();
+        track.play();
+    }
+
+    let targetMode = [
+        {track: 'main', volume: 100}
+    ];
+
+    setInterval(() => {
+        if (!Array.isArray(targetMode)) {
+            targetMode = [];
+        }
+
+        for (const [key, track] of Object.entries(tracks)) {
+            const mode = targetMode.find(m => m.track === key) || {volume: 0};
+            track.setVolume(track.volume + 0.1 * (mode.volume - track.volume));
+        }
+    }, 100);
+
+    process.stdin.on('data', data => {
+        log('STDIN: ' + data);
+
+        const probablyJSON = data.toString().slice(data.indexOf('[')).trim();
+
+        try {
+            targetMode = JSON.parse(probablyJSON);
+        } catch (error) {
+        }
+    });
+}, 250);
+
+log('Go!');
+
+process.on('SIGTERM', () => {
+    log('Exiting [sigterm]');
+    for (const track of Object.values(tracks)) {
+        track.process.kill();
+    }
+    log('Cleaned up');
+});
diff --git a/native-app/manifest.json b/native-app/manifest.json
new file mode 100644
index 0000000..73f90dd
--- /dev/null
+++ b/native-app/manifest.json
@@ -0,0 +1,7 @@
+{
+    "name": "interactive_bgm",
+    "description": "Adds background music to your browsing.",
+    "path": "/home/florrie/Documents/interactive-bgm/native-app/index.js",
+    "type": "stdio",
+    "allowed_extensions": ["interactive_bgm@florrie.ed1.club"]
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..0a342b5
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,21 @@
+{
+  "name": "interactive-bgm",
+  "version": "1.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "es6-error": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-3.2.0.tgz",
+      "integrity": "sha1-5WfP3LMk1OeuWSKjcAraXeh5oMo="
+    },
+    "fifo-js": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fifo-js/-/fifo-js-2.1.0.tgz",
+      "integrity": "sha1-iEBfId6gZzYlWBieegdlXcD+FL4=",
+      "requires": {
+        "es6-error": "^3.0.1"
+      }
+    }
+  }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6fcae8f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,14 @@
+{
+  "name": "interactive-bgm",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "GPL-3.0",
+  "dependencies": {
+    "fifo-js": "^2.1.0"
+  }
+}
diff --git a/track1.wav b/track1.wav
new file mode 100755
index 0000000..bdbba6e
--- /dev/null
+++ b/track1.wav
Binary files differdiff --git a/track2.wav b/track2.wav
new file mode 100755
index 0000000..76452bd
--- /dev/null
+++ b/track2.wav
Binary files differdiff --git a/track3.wav b/track3.wav
new file mode 100755
index 0000000..09fcef7
--- /dev/null
+++ b/track3.wav
Binary files differ