Comparing version 1.0.2 to 1.1.0
62
index.js
@@ -1,51 +0,31 @@ | ||
#!/usr/bin/env node | ||
'use strict' | ||
var util = require('util') | ||
var fs = require('fs') | ||
var http = require('http') | ||
var mime = require('mime') | ||
var bonjour = require('bonjour')() | ||
var rangeParser = require('range-parser') | ||
var ip = require('internal-ip').v4() | ||
var EventEmitter = require('events').EventEmitter | ||
var Bonjour = require('bonjour') | ||
var AirPlay = require('airplay-protocol') | ||
var filename = process.argv.slice(2).pop() | ||
module.exports = function () { | ||
var bonjour = Bonjour() | ||
var list = new EventEmitter() | ||
var found = [] | ||
var browser = bonjour.find({ type: 'airplay' }, function (service) { | ||
if (~found.indexOf(service.fqdn)) return | ||
if (!filename) { | ||
console.error('Usage: airplayer filename') | ||
process.exit(1) | ||
} | ||
var player = new AirPlay(service.host, service.port) | ||
player.name = service.name | ||
var contentType = mime.lookup(filename) | ||
found.push(service.fqdn) | ||
list.players.push(player) | ||
var browser = bonjour.find({ type: 'airplay' }, function (tv) { | ||
browser.stop() | ||
server.listen(function () { | ||
var port = server.address().port | ||
var airplay = AirPlay(tv.host, tv.port) | ||
airplay.play('http://' + ip + ':' + port + '/stream.m4v', function (err, res, body) { | ||
if (err) throw err | ||
}) | ||
list.emit('update', player) | ||
}) | ||
}) | ||
var server = http.createServer(function (req, res) { | ||
var stat = fs.statSync(filename) | ||
var size = stat.size | ||
var range = req.headers.range | ||
range = range && rangeParser(size, range)[0] | ||
list.players = [] | ||
list.update = browser.update.bind(browser) | ||
list.destroy = function () { | ||
browser.stop() | ||
bonjour.destroy() | ||
} | ||
res.writeHead(206, { | ||
'Access-Control-Allow-Origin': '*', | ||
'Accept-Ranges': 'bytes', | ||
'Content-Length': (range.end - range.start + 1), | ||
'Content-Type': contentType, | ||
'Content-Range': util.format('bytes %d-%d/%d', range.start, range.end, size) | ||
}) | ||
fs.createReadStream(filename, range).pipe(res) | ||
}) | ||
return list | ||
} |
{ | ||
"name": "airplayer", | ||
"version": "1.0.2", | ||
"description": "A simple command line tool that play local videos on your Apple TV", | ||
"bin": { | ||
"airplayer": "index.js" | ||
}, | ||
"version": "1.1.0", | ||
"description": "Query your local network for Apple TV's and have them play videos", | ||
"main": "index.js", | ||
"bin": "bin.js", | ||
"dependencies": { | ||
"airplay-protocol": "^1.0.0", | ||
"bonjour": "^3.2.2", | ||
"airplay-protocol": "^1.1.0", | ||
"appendable-cli-menu": "^2.0.0", | ||
"bonjour": "^3.3.0", | ||
"internal-ip": "^1.2.0", | ||
"mime": "^1.3.4", | ||
"minimist": "^1.2.0", | ||
"range-parser": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"standard": "^6.0.8" | ||
"standard": "^6.0.8", | ||
"tape": "^4.5.1" | ||
}, | ||
@@ -27,2 +29,5 @@ "scripts": { | ||
"airplay", | ||
"apple", | ||
"tv", | ||
"appletv", | ||
"video", | ||
@@ -41,5 +46,5 @@ "player", | ||
"coordinates": [ | ||
55.687678, | ||
12.5956794 | ||
55.6469012, | ||
12.5508987 | ||
] | ||
} |
# airplayer | ||
A simple command line tool that play local videos on your Apple TV. | ||
Query your local network for Apple TV's or other AirPlay video | ||
compatible devices and have them play videos. | ||
This application also serves as an example implementation of the | ||
[airplay-protocol](https://github.com/watson/airplay-protocol) module. | ||
[](https://travis-ci.org/watson/airplayer) | ||
@@ -13,13 +11,35 @@ [](https://github.com/feross/standard) | ||
For programmatic use, install using: | ||
``` | ||
npm install airplayer --save | ||
``` | ||
Or install globally to use via the command line: | ||
``` | ||
npm install airplayer --global | ||
``` | ||
## Example Usage | ||
## Example Programmatic Usage | ||
Simply install module globally and run the `airplayer` command with the | ||
file you want to play as the first argument. | ||
```js | ||
var airplayer = require('airplayer') | ||
var list = airplayer() | ||
list.on('update', function (player) { | ||
console.log('Found new AirPlay device:', player.name) | ||
player.play(url) | ||
}) | ||
``` | ||
## Example CLI Usage | ||
If you install the module gobally, simply run the `airplayer` command | ||
with the file you want to play as the first argument. | ||
The `airplayer` command will look for an Apple TV on your local network. | ||
When one is found, it will start playing the chosen video. | ||
When one is found, it will start playing the chosen video. Use the | ||
option `-i` to select the Apple TV to stream to. | ||
@@ -30,7 +50,34 @@ ``` | ||
Note that the video must be supported by your Apple TV in order for | ||
`airplayer` to play it. | ||
Note that the video must be in a format supported by your Apple TV in | ||
order for `airplayer` to play it. | ||
## API | ||
### `var list = airplayer()` | ||
Creates a AirPlay list. When creating a new list it will call | ||
`list.update()` once. It is up to you to call afterwards incase you want | ||
to update the list. | ||
### `list.update()` | ||
Updates the player list by querying the local network for `airplay` | ||
instances. | ||
### `list.destroy()` | ||
Stop browsing for players. | ||
### `list.on('update', player)` | ||
Emitted when a new player is found on the local network. | ||
The `player` is an instance of | ||
[`airplay-protocol`](https://github.com/watson/airplay-protocol) with | ||
the following extra properties: | ||
- `name` - The human readable name of the AirPlay device | ||
## License | ||
MIT |
44
test.js
'use strict' | ||
process.argv[2] = 'foo' | ||
require('./') | ||
process.exit() | ||
var Bonjour = require('bonjour') | ||
var test = require('tape') | ||
var airplayer = require('./') | ||
test('api', function (t) { | ||
var list = airplayer() | ||
t.ok(list instanceof require('events').EventEmitter) | ||
t.deepEqual(list.players, []) | ||
list.update() | ||
list.destroy() | ||
t.end() | ||
}) | ||
test('on update', function (t) { | ||
var list = airplayer() | ||
list.on('update', function (player) { | ||
t.ok(player instanceof require('airplay-protocol')) | ||
t.equal(player.name, 'foo') | ||
b.destroy() | ||
list.destroy() | ||
t.end() | ||
}) | ||
var b = Bonjour() | ||
b.publish({ name: 'foo', port: 7000, type: 'airplay' }) | ||
}) | ||
test('bin', function (t) { | ||
process.argv[2] = 'foo' | ||
require('./bin.js') | ||
t.end() | ||
}) | ||
test('end', function (t) { | ||
t.end() | ||
process.exit() | ||
}) |
Sorry, the diff of this file is not supported yet
7643
8
126
82
7
2
+ Addedappendable-cli-menu@^2.0.0
+ Addedminimist@^1.2.0
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedappendable-cli-menu@2.0.0(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedcode-point-at@1.1.0(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedis-fullwidth-code-point@1.0.0(transitive)
+ Addedkeypress@0.2.1(transitive)
+ Addednumber-is-nan@1.0.1(transitive)
+ Addedsingle-line-log@1.1.2(transitive)
+ Addedstring-width@1.0.2(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.0(transitive)
Updatedairplay-protocol@^1.1.0
Updatedbonjour@^3.3.0