GithubHelp home page GithubHelp logo

hughsk / komponist Goto Github PK

View Code? Open in Web Editor NEW
36.0 9.0 4.0 201 KB

A simple, yet flexible, Node client library for MPD, the hackable headless audio playback server.

Home Page: http://hughsk.github.com/komponist

JavaScript 100.00%

komponist's Introduction

komponist

A simple, yet flexible, Node client library for MPD, the hackable headless audio playback server. As a bonus, it runs the same if you use it server-side or on the browser!

Installation

npm install komponist

Of course, before you go ahead and write any code - make sure you install MPD and start it up wherever you want to play your music from. You should probably get MPC (the simple CLI client) too.

Basic Usage

With a small number of exceptions, komponist exposes all of the available commands as callback-style methods. For a full list check out the docs.

var komponist = require('komponist')

var client = komponist.createConnection(6600, 'localhost', function() {
  client.add('~/iTunes', function(err) {
    client.play(function(err) {
      client.currentsong(function(err, info) {
        console.log(info.Artist); // Ennio Morricone
        console.log(info.Title);  // Il Buono, Il Cattivo, Il Brutto
        console.log(info.Album);  // The Good, The Bad, And The Ugly
      });
    });
  });
});

If you prefer to just fire and forget, you can omit the callbacks.

// You can always omit the port/host if you're running
// MPD locally and with the default settings.
komponist.createConnection(function(err, client) {
  client.add('~/iTunes');
  client.random();
  client.play();
});

There's also a general purpose command method:

var client = komponist.createConnection(function() {
  // Jump 60 seconds into the 5th track in your playlist:
  client.command('seek', [5, 60], function(err) {
    // And stop playing when it's done.
    client.command('single');
  });
});

The client returned by komponist.createConnection is just an extended TCP stream, so if you like you can just pipe data around the Node way:

var fs = require('fs')
  , client = komponist.createConnection()

// Pipe a list of commands to MPD from
// a file, piping the raw response out to
// stdout! (For kicks)
fs.createReadStream('./commands.mpd', 'utf8')
  .pipe(client)
  .pipe(process.stdout)

Watching for Changes

If you're building an interface-driven client for MPD, you're going to want to be able to listen for changes as they happen. This is all taken care of for you: just listen for the "changed" event for MPD updates.

var komponist = require('komponist')

komponist.createConnection(6600, 'localhost')
   .on('changed', function(system) {
     console.log('Subsystem changed: ' + system);
   });

According to the MPD protocol documentation, you can track changes to the following systems this way:

  • update: a database update has started or finished.
  • database: the song database has been modified after update.
  • stored_playlist: a stored playlist has been modified.
  • playlist: the current playlist has been modified.
  • player: the player has been started, stopped or seeked.
  • mixer: the volume has been changed.
  • output: an audio output has been enabled or disabled.
  • options: options like repeat, random, crossfade, replay gain.
  • sticker: the sticker database has been modified.
  • subscription: a client has subscribed or unsubscribed to a channel.

Publish/Subscribe

MPD has simple publish/subscribe support for communicating across multiple clients. Using the publish and subscribe methods, you can send messages to other subscribers across the network, e.g. for simple service discovery.

komponist.createConnection(function(err, subscriber) {
  subscriber.subscribe('hello');
  subscriber.subscribe('world');

  subscriber.on('message', function(message, channel) {
    console.log('Got message "' + message + '" on channel "' + channel + '"');
  });
});

komponist.createConnection(function(err, publisher) {
  setTimeout(function() {
    publisher.publish('hello', 'message #1');
    publisher.publish('world', 'message #2');
  }, 1000);
});

// Output:
// Got message "message #1" on channel "hello"
// Got message "message #2" on channel "world"

Stickers

MPD stickers are a way for you to store arbitrary data in the MPD database, associated with particular objects. Note that to enable stickers, add sticker_file ~/.mpd/mpd.stickers to your mpd.conf file.

komponist.createConnection(function(err, client) {
  client.sticker('song', 'iTunes/song1.mp3').set({
      hello: 'world'
    , lorem: 'ipsum'
  }, function(err) {
    // The sticker method returns a reusable object, taking
    // the arguments "type" and "uri".
    var sticker = client.sticker('song', 'iTunes/song1.mp3');

    sticker.get('hello', function(err, data) {
      console.log(data); // { hello: 'world' }
    });

    sticker.get(['hello', 'lorem'], function(err, data) {
      console.log(data); // { hello: 'world', lorem: 'ipsum' }
    });

    sticker.list(function(err, data) {
      console.log(data); // { hello: 'world', lorem: 'ipsum' }
    });

    client.sticker('song', 'iTunes').find('lorem', function(err, data) {
      console.log(data[0].file);    // 'iTunes/song1.mp3'
      console.log(data[0].sticker); // { name: 'lorem', value: 'ipsum' }
      console.log(data[1].file);    // 'iTunes/song2.mp3'
      console.log(data[1].sticker); // { name: 'lorem', value: 'another ipsum' }
    });
  });

  client.sticker('song', 'iTunes/song2.mp3').set({
    lorem: 'another ipsum'
  });
});

If you're looking to use the command in the same style as above, it's still accessible as komponist._sticker().

Using Komponist in the Browser

Thanks to the fact that Komponist connections are streams, you can get the use the module just the same on the browser as you would server-side, using @substack's browserify module.

// On the server:
var http = require('http')
  , komponist = require('komponist')

var server = http.createServer(function(req, res) {
  res.end('Hello world.')
});

komponist.install(server, 'localhost', 6600);

// And on the browser:
var komponist = require('komponist');

komponist.createConnection(function(err, client) {
  client.status(function(err, status) {
    console.log('Status: ', status);
  });
});

There's a full example available in the Github repository.

Gotchas

The following methods are reserved for TCP sockets, and as such have been aliased:

  • pause is now client.toggle()
  • kill is now client.killServer()
  • close will close the connection without issuing a command to MPD.

There's no support for command_list_* commands right now.

You can still access them as normal through the command method. If you come across any other bugs or inconsistencies, you're more than welcome create an issue or a pull request.

komponist's People

Contributors

bananushka avatar hughsk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

komponist's Issues

"Cannot read property 'apply' of undefined

I'm currently working on a class project dealing with MPD and I'm attempting to use Komponist. I'm running into an issue and I was wondering if you could help me solve this problem since you developed Komponist.

Here I have the following code that just attempts to create a connection to my MPD server.

var komponist = require('komponist');

var client = komponist.createConnection(6600, 'localhost', function() {
  console.log('Connected!');
});

However, when I try to execute this code the Chrome debugger's returning "Cannot read property 'apply' of undefined " and it's pointing to this:

MPDClient.prototype.connect = function() {
    var returnVal = MPDClient.super_.prototype.connect.apply(this, arguments);
    this.write = MPDClient.prototype.write;
    return returnVal;
}

At first I thought it was because MPD simply wasn't running or there was a connection issue but my MPD server is running on localhost:6600 and I can connect to it just fine from another third party client, so I'm wondering if I'm missing a library or some other dev dependencies to use komponist. I'm not familiar with the "super_" notation.

If you have any ideas as to what's causing this issue I'd be eternally grateful. If possible, I need to know this ASAP for project deadlines. Thanks so much!

Commands with parameters don't work under node 0.10

It seems that in the current version of node (0.10) net.Socket#connect was changed in a way that makes it very difficult to overwrite the write method, therefore the call this.write from MPDClient#command always goes to net.Socket#write.
A simple fix would be overriding the connect method to always revert to the "correct" write.

Error handling when MPD doesn't exist

Hi,

I'm running a nodejs project using express and the MPD daemon is not running.
When I run my app and go to a page using komponist, the app crashes.
I tried to handle error inside the createConnection callback, unfortunately it doesn't seem to have any effect.

Do you have any recommendation on handling errors which are issued when the MPD daemon is not running ?

Thanks,
Mathieu

losing socket connection when using command lists

when i use the command lists (i know, it is not supported at the moment, i am accessing those using the general command method), i lose the socket connection to mpd: no "change" events are fired any more and client.on('error') is telling me, that the socket has been ended by another party.
i am doing something like this:

socket.emitMpdCommand('command_list_ok_begin', [], handleMsg);
  _.each(songs, function(song) { // iterate selection
    if (_.has(song, 'file')) {
      socket.emitMpdCommand('add', song.file, handleMsg); // add song
  }
});
socket.emitMpdCommand('command_list_end', [], handleMsg);

where socket.emitMpdCommand is just a wrapper, that emits to my server. there, the komponist-client is retrieving the message and sending it to mpd. this is going good so far with the normal commands, but with the command-list-* commands, it is not. i can still use the client and send commands with it, but i am not getting 'changed' events anymore.

thanks for help,
hinrich

Demo Project using komponist

Hi,

I set up a project that uses komponist. juke provides a light user interface for it. Basically I took your example and wrapped it into an alternative UI.

Thanks a lot for the work! It saved me a lot of trouble.

Initially I tried setting up the project based on Express but ran into issues with WebSockets. I redefined komponist.install in that case as suggested by shoe documentation but it still failed. It might be nice to look into this.

The way the example project deals with static files is a bit unsecure. It might be a good idea to serve them some other way. I ended up using node-static myself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.