Replace python player with node.js player
This commit is contained in:
parent
82d3506ff7
commit
0ff369c53d
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
lib
|
24
package.json
Normal file
24
package.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "rfid",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "player.js",
|
||||||
|
"scripts": {
|
||||||
|
"build-css": "stylus source/stylesheets/index.styl -o static/css",
|
||||||
|
"watch-css": "stylus source/stylesheets/index.styl -o static/css -w",
|
||||||
|
"clean": "rm -rf static/css && mkdir -p static/css",
|
||||||
|
"build": "npm run clean && npm run build-css",
|
||||||
|
"watch": "npm run clean && npm run watch-css & nodemon player -e js,jade",
|
||||||
|
"start": "node player"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.14.0",
|
||||||
|
"glob": "^7.1.1",
|
||||||
|
"jade": "^1.11.0",
|
||||||
|
"morgan": "^1.7.0",
|
||||||
|
"nodemon": "^1.9.2",
|
||||||
|
"stylus": "^0.54.5"
|
||||||
|
}
|
||||||
|
}
|
79
player.js
Normal file
79
player.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
const glob = require('glob');
|
||||||
|
const spawn = require('child_process').spawn;
|
||||||
|
const tag_reader = spawn('/home/annika/rfid/run-tag-reader');
|
||||||
|
const player = spawn('/usr/bin/sudo', ['-n', '/usr/bin/mpg321', '-R', '-']);
|
||||||
|
|
||||||
|
tag_reader.on('error', function(err) {
|
||||||
|
console.log(`[tag_reader:error] ${err}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
player.on('error', function(err) {
|
||||||
|
console.log(`[player:error] ${err}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// player.stdin.write("GAIN 100");
|
||||||
|
|
||||||
|
last_tag = null;
|
||||||
|
debounce_until = 0;
|
||||||
|
|
||||||
|
function lookup(tag, cb) {
|
||||||
|
if (tag === 'b9506555d9') {
|
||||||
|
return cb('STOP');
|
||||||
|
}
|
||||||
|
if (tag === 'aa89665510') {
|
||||||
|
return cb('PAUSE', 2);
|
||||||
|
}
|
||||||
|
glob('media/' + tag + ' - *.mp3', function(er, files) {
|
||||||
|
if (files.length > 0) {
|
||||||
|
return cb("LOAD " + files[0], 5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_reader.stdout.on('data', (data) => {
|
||||||
|
if (Date.now() / 1000 < debounce_until) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_tag = String(data).trim();
|
||||||
|
console.log("Tag: " + last_tag);
|
||||||
|
lookup(last_tag, function(action, wait_sec) {
|
||||||
|
wait_sec = wait_sec || 1;
|
||||||
|
if (action) {
|
||||||
|
debounce_until = Date.now() / 1000 + wait_sec;
|
||||||
|
console.log(`Running ${action} for ${last_tag}`);
|
||||||
|
player.stdin.write(action + "\n");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tag_reader.stderr.on('data', (data) => {
|
||||||
|
console.log(`[tag_reader:stderr] ${data}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
player.stderr.on('data', (data) => {
|
||||||
|
if (String(data).substr(0, 3) === "@F ") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(`[player:stderr] ${data}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
var express = require('express')
|
||||||
|
, logger = require('morgan')
|
||||||
|
, app = express()
|
||||||
|
, template = require('jade').compileFile(__dirname + '/source/templates/homepage.jade')
|
||||||
|
|
||||||
|
app.use(logger('dev'))
|
||||||
|
app.use(express.static(__dirname + '/static'))
|
||||||
|
|
||||||
|
app.get('/', function (req, res, next) {
|
||||||
|
try {
|
||||||
|
var html = template({ title: 'Home', last_tag: last_tag })
|
||||||
|
res.send(html)
|
||||||
|
} catch (e) {
|
||||||
|
next(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(process.env.PORT || 80, function () {
|
||||||
|
console.log('Listening on http://localhost:' + (process.env.PORT || 80))
|
||||||
|
})
|
58
player.py
58
player.py
@ -1,58 +0,0 @@
|
|||||||
from pirc522 import RFID
|
|
||||||
from glob import glob
|
|
||||||
|
|
||||||
import atexit
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import signal
|
|
||||||
import subprocess
|
|
||||||
import vlc
|
|
||||||
|
|
||||||
rdr = RFID()
|
|
||||||
util = rdr.util()
|
|
||||||
|
|
||||||
last_seen = None
|
|
||||||
seen_at = 0
|
|
||||||
p = None
|
|
||||||
|
|
||||||
RETRY_TIME = 2
|
|
||||||
|
|
||||||
#player = subprocess.Popen(["mpg321", "-R", "-"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
player = subprocess.Popen(["mpg321", "-R", "-"], stdin=subprocess.PIPE)
|
|
||||||
player.stdin.write("GAIN 100")
|
|
||||||
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
(error, tag_type) = rdr.request()
|
|
||||||
if not error:
|
|
||||||
(error, uid) = rdr.anticoll()
|
|
||||||
if not error:
|
|
||||||
tag_id = ''.join(hex(x)[2:].zfill(2) for x in uid)
|
|
||||||
print("Tag: " + tag_id)
|
|
||||||
|
|
||||||
if tag_id == 'b9506555d9':
|
|
||||||
print("Stopping playback.")
|
|
||||||
player.stdin.write("STOP\n")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if time.time() > (seen_at + RETRY_TIME):
|
|
||||||
last_seen = uid
|
|
||||||
seen_at = time.time()
|
|
||||||
|
|
||||||
if tag_id == 'aa89665510':
|
|
||||||
print("Toggling pause.")
|
|
||||||
player.stdin.write("PAUSE\n")
|
|
||||||
continue
|
|
||||||
|
|
||||||
file = glob("media/" + tag_id + " - *.mp3")
|
|
||||||
if file:
|
|
||||||
print("Playing file " + file[0])
|
|
||||||
player.stdin.write("STOP\n")
|
|
||||||
player.stdin.write("LOAD " + file[0] + "\n")
|
|
||||||
|
|
||||||
continue
|
|
||||||
except (KeyboardInterrupt, SystemExit):
|
|
||||||
os.kill(player.pid, signal.SIGTERM)
|
|
||||||
|
|
||||||
# Calls GPIO cleanup
|
|
||||||
rdr.cleanup()
|
|
3
run-tag-reader
Executable file
3
run-tag-reader
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo -n /home/annika/rfid/lib/bin/python tag-reader.py
|
56
source/stylesheets/index.styl
Normal file
56
source/stylesheets/index.styl
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro:400,200,700')
|
||||||
|
|
||||||
|
*
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
box-sizing border-box
|
||||||
|
|
||||||
|
body
|
||||||
|
font-family 'Source Code Pro', monospace
|
||||||
|
|
||||||
|
.header
|
||||||
|
background url('https://images.unsplash.com/photo-1451337516015-6b6e9a44a8a3?crop=entropy&fit=crop&fm=jpg&h=975&ixjsv=2.1.0&ixlib=rb-0.3.5&q=80&w=1925')
|
||||||
|
background-position center
|
||||||
|
|
||||||
|
.page-title
|
||||||
|
font-weight 200
|
||||||
|
font-size 80px
|
||||||
|
text-align center
|
||||||
|
padding 100px
|
||||||
|
text-transform uppercase
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
.nav
|
||||||
|
background #000
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
li
|
||||||
|
display inline-block
|
||||||
|
|
||||||
|
a
|
||||||
|
display inline-block
|
||||||
|
padding 20px
|
||||||
|
color #fff
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color #3AB795
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
.main-content
|
||||||
|
margin 50px auto
|
||||||
|
max-width 600px
|
||||||
|
|
||||||
|
p
|
||||||
|
line-height 1.6
|
||||||
|
margin-bottom 1.7em
|
||||||
|
|
||||||
|
.footer
|
||||||
|
margin 50px auto
|
||||||
|
max-width 600px
|
||||||
|
border-top 1px solid #444
|
||||||
|
padding 20px 0
|
||||||
|
|
||||||
|
p
|
||||||
|
color #444
|
||||||
|
font-size 12px
|
20
source/templates/default.jade
Normal file
20
source/templates/default.jade
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
doctype html
|
||||||
|
html
|
||||||
|
head
|
||||||
|
link(rel='stylesheet', href='/css/index.css')
|
||||||
|
title World Wide Web
|
||||||
|
body
|
||||||
|
.header
|
||||||
|
h1.page-title World Wide Web
|
||||||
|
|
||||||
|
ul.nav
|
||||||
|
li: a(href='/') Home
|
||||||
|
li: a(href='#news') News
|
||||||
|
li: a(href='#about') About
|
||||||
|
li: a(href='#contact') Contact
|
||||||
|
|
||||||
|
.main-content
|
||||||
|
block content
|
||||||
|
|
||||||
|
.footer
|
||||||
|
p Copyright © 2020 Futurecorpz. Futurecorpz ® is a Registered Trademark of Futures (un)Ltd. in the Mars Community and other solar systems.
|
5
source/templates/homepage.jade
Normal file
5
source/templates/homepage.jade
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extend default
|
||||||
|
|
||||||
|
block content
|
||||||
|
p.
|
||||||
|
Last tag seen: #{last_tag}
|
56
static/css/index.css
Normal file
56
static/css/index.css
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css?family=Source+Code+Pro:400,200,700");
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: 'Source Code Pro', monospace;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background: url("https://images.unsplash.com/photo-1451337516015-6b6e9a44a8a3?crop=entropy&fit=crop&fm=jpg&h=975&ixjsv=2.1.0&ixlib=rb-0.3.5&q=80&w=1925");
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
.header .page-title {
|
||||||
|
font-weight: 200;
|
||||||
|
font-size: 80px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 100px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.nav {
|
||||||
|
background: #000;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.nav li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.nav a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 20px;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.nav a:hover {
|
||||||
|
background-color: #3ab795;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.main-content {
|
||||||
|
margin: 50px auto;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
.main-content p {
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 1.7em;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin: 50px auto;
|
||||||
|
max-width: 600px;
|
||||||
|
border-top: 1px solid #444;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
.footer p {
|
||||||
|
color: #444;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
19
tag-reader.py
Normal file
19
tag-reader.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from pirc522 import RFID
|
||||||
|
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
import sys
|
||||||
|
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
|
||||||
|
rdr = RFID()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
(error, tag_type) = rdr.request()
|
||||||
|
if not error:
|
||||||
|
(error, uid) = rdr.anticoll()
|
||||||
|
if not error:
|
||||||
|
tag_id = ''.join(hex(x)[2:].zfill(2) for x in uid)
|
||||||
|
print(tag_id)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
rdr.cleanup()
|
Loading…
Reference in New Issue
Block a user