parent
257b18a879
commit
da68d2957b
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "mpvremote-server",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"repository": "indefero@ghostdub.de:mpvremote.git",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "gpl"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"bunyan": "^1.8.0",
|
||||
"every-moment": "0.0.1",
|
||||
"nesh": "1.6.0",
|
||||
"nodemon": "1.9.1",
|
||||
"q": "1.4.1",
|
||||
"q-io": "1.13.2",
|
||||
"restify": "4.0.4",
|
||||
"restify-plugins": "1.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "./node_modules/.bin/nodemon server.js | ./node_modules/.bin/bunyan"
|
||||
}
|
||||
}
|
||||
@ -1,253 +0,0 @@
|
||||
var restify = require('restify');
|
||||
var bunyan = require('bunyan');
|
||||
var Q = require("q");
|
||||
var FS = require("q-io/fs");
|
||||
const net = require('net');
|
||||
var util = require("util");
|
||||
|
||||
String.prototype.format = function() {
|
||||
var formatted = this;
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
|
||||
formatted = formatted.replace(regexp, arguments[i]);
|
||||
}
|
||||
return formatted;
|
||||
};
|
||||
|
||||
// CONNECTIONS AND STUF
|
||||
var socketPath = '/home/daddel9/.mpv-sock';
|
||||
var log = bunyan.createLogger({name: 'MpvRemote'});
|
||||
|
||||
// SETUP
|
||||
var server = restify.createServer();
|
||||
server.pre(restify.pre.sanitizePath());
|
||||
|
||||
|
||||
// Serve static files
|
||||
server.get(/\/client\/?.*/, restify.serveStatic({
|
||||
directory: __dirname
|
||||
}));
|
||||
|
||||
|
||||
// Cödê
|
||||
|
||||
|
||||
global.mpvstate = {
|
||||
"percent-pos":null,
|
||||
"time-pos":null,
|
||||
"time-remaining":null,
|
||||
"chapter":null,
|
||||
"chapter-list/count":null,
|
||||
"pause":null,
|
||||
"volume":null,
|
||||
"mute":null,
|
||||
};
|
||||
global.mpvisWaitingFor = null;
|
||||
|
||||
global.mpvsocket = null;
|
||||
global.mpvisConnected = false;
|
||||
global.mpvconnect = function() {
|
||||
defer = Q.defer();
|
||||
|
||||
log.info("socket is {0} isConnected is {1}".format(global.mpvsocket, global.mpvisConnected));
|
||||
if(global.mpvisConnected) {
|
||||
defer.resolve(global.mpvsocket);
|
||||
return defer.promise;
|
||||
}
|
||||
|
||||
sock = net.connect(socketPath);
|
||||
|
||||
sock.on("connect", function() {
|
||||
log.info("socket had connect event");
|
||||
global.mpvsocket = sock;
|
||||
global.mpvisConnected=true;
|
||||
defer.resolve(sock)
|
||||
});
|
||||
sock.on("error", function(err) {
|
||||
global.mpvisConnected=false;
|
||||
defer.reject(err)
|
||||
});
|
||||
sock.on("end", function() {
|
||||
global.mpvisConnected=false;
|
||||
defer.reject(new Error("socket ended"))
|
||||
});
|
||||
sock.on("data", function(dta) {
|
||||
log.info("had data '{0}' while waitingfor {1}".format(dta, global.mpvisWaitingFor));
|
||||
if(global.mpvisWaitingFor) {
|
||||
dta = JSON.parse(dta);
|
||||
var property = global.mpvisWaitingFor[0];
|
||||
var defer = global.mpvisWaitingFor[1];
|
||||
log.info("was waitingfor {0}, had data {1}, resolving now".format(property, dta['data']));
|
||||
global.mpvstate[property] = dta['data'];
|
||||
global.mpvisWaitingFor = null;
|
||||
defer.resolve();
|
||||
}
|
||||
});
|
||||
return defer.promise;
|
||||
}
|
||||
|
||||
|
||||
function buildCommand(cmd, params) {
|
||||
paramsStr="";
|
||||
params.forEach(function(val, idx, arr) {
|
||||
paramsStr = paramsStr+', "{0}"'.format(val);
|
||||
})
|
||||
ret = '{ "command": [ "{0}"{1} ] }\n'.format(cmd, paramsStr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function writeCommand(cmd, params) {
|
||||
defer = Q.defer();
|
||||
global.mpvconnect()
|
||||
.then( function(sock) {
|
||||
log.info("can write in "+sock);
|
||||
try {
|
||||
cmdStr = buildCommand(cmd, params);
|
||||
log.info("trying to write cmd '{0}' to sock".format(cmdStr));
|
||||
sock.write(cmdStr);
|
||||
defer.resolve();
|
||||
} catch(e) {
|
||||
log.error("got error "+e);
|
||||
defer.reject(e);
|
||||
}
|
||||
}, function(reason) {
|
||||
defer.reject(reason);
|
||||
});
|
||||
return defer.promise;
|
||||
}
|
||||
|
||||
|
||||
function updateProperty(propertyIdx) {
|
||||
var defer = Q.defer();
|
||||
var keys = Object.keys(global.mpvstate);
|
||||
var property = keys[propertyIdx];
|
||||
log.info("updating property at idx {0} which is {1}".format(propertyIdx, property));
|
||||
|
||||
writeCommand("get_property", [property]).then(function(){
|
||||
global.mpvisWaitingFor=[property,defer];
|
||||
|
||||
if(propertyIdx >= keys.length-1) {
|
||||
log.info("idx too large, returning");
|
||||
return;
|
||||
} else {
|
||||
log.info("deferring updateProperty({0})".format(propertyIdx+1));
|
||||
defer.promise.then(function() { updateProperty(propertyIdx+1) } );
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function stateUpdate() {
|
||||
log.info("updating state");
|
||||
updateProperty(0);
|
||||
}
|
||||
|
||||
var every = require('every-moment');
|
||||
var timer = every(10, 'second', function() {
|
||||
stateUpdate();
|
||||
});
|
||||
|
||||
var timer = every(12, 'second', function() {
|
||||
log.info("my current state is: "+util.inspect(global.mpvstate));
|
||||
});
|
||||
|
||||
// /seekTime/:time — seeks relative
|
||||
// /seekPercent/:percent — seeks percent absolute
|
||||
// /seekChapter/:where — seeks to prev (where=-x) or next (where=+x) chapter
|
||||
// /volume/:amount — increases (amount=+x) or decreases (amount=-x) volume
|
||||
// /progress — show osd progress
|
||||
// /playpause — toggles playing
|
||||
// /muteunmute — toggles muting
|
||||
// /stateUpdate — update state
|
||||
// /stateVar/:name — get value of tracked property with name
|
||||
|
||||
server.get('/seek/:time', function (req, res, next) {
|
||||
log.info("seek "+req.params.time);
|
||||
writeCommand("seek", [req.params.time])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/seekPercent/:percent', function (req, res, next) {
|
||||
log.info("seekpercent "+req.params.percent);
|
||||
writeCommand("seek", [req.params.percent, "absolute-percent"])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/seekChapter/:where', function (req, res, next) {
|
||||
log.info("seekChapter "+req.params.where);
|
||||
writeCommand("add", ["chapter", req.params.where])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});server.get('/volume/:amount', function (req, res, next) {
|
||||
log.info("volume "+req.params.amount);
|
||||
writeCommand("add", ["volume", req.params.amount])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/volume/:amount', function (req, res, next) {
|
||||
log.info("volume "+req.params.amount);
|
||||
writeCommand("add", ["volume", req.params.amount])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/playpause', function (req, res, next) {
|
||||
log.info("playpause ");
|
||||
writeCommand("cycle", ["pause"])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/muteunmute', function (req, res, next) {
|
||||
log.info("muteunmute ");
|
||||
writeCommand("cycle", ["mute"])
|
||||
.then(function() {
|
||||
res.send({"success":true});
|
||||
return next(false);
|
||||
}, function(reason) {
|
||||
res.send({"success":false, "reason": reason});
|
||||
return next(false);
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/stateUpdate', function (req, res, next) {
|
||||
log.info("stateUpdate ");
|
||||
stateUpdate();
|
||||
});
|
||||
|
||||
server.listen(8080, function() {
|
||||
console.log('%s listening at %s', server.name, server.url);
|
||||
});
|
||||
Loading…
Reference in new issue