add chromecast/airplay support

This commit is contained in:
Feross Aboukhadijeh
2016-03-02 04:14:17 -08:00
parent 39b46e126f
commit c1e2b9ec5c
4 changed files with 121 additions and 24 deletions

View File

@@ -70,30 +70,45 @@ body.drag::before {
.torrent .metadata { .torrent .metadata {
float: left; float: left;
width: calc(100% - 80px); width: calc(100% - 240px);
color: #FFF; color: #FFF;
text-shadow: rgba(0, 0, 0, 0.5) 0 0 4px; text-shadow: rgba(0, 0, 0, 0.5) 0 0 4px;
} }
.torrent .play { .btn {
float: right;
margin-top: 25px;
background-color: #C62828;
width: 50px; width: 50px;
height: 50px; height: 50px;
border-radius: 25px; border-radius: 25px;
color: #FFF; color: #FFF;
font-size: 24px; font-size: 24px;
padding-top: 14px;
padding-left: 3px;
text-align: center;
transition: all 0.1s; transition: all 0.1s;
text-align: center;
} }
.torrent .play:not(.disabled):hover { .btn:not(.disabled):hover {
-webkit-filter: brightness(1.5); -webkit-filter: brightness(1.5);
} }
.torrent .btn {
float: right;
margin-top: 25px;
padding-top: 14px;
margin-left: 20px;
}
.torrent .play {
background-color: #C62828;
padding-left: 3px;
}
.torrent .chromecast {
background-color: #64B5F6;
}
.torrent .airplay {
background-color: #607D8B;
}
.torrent .name { .torrent .name {
font-size: 1.6em; font-size: 1.6em;
font-weight: bold; font-weight: bold;

View File

@@ -1,9 +1,12 @@
/* global URL, Blob */ /* global URL, Blob */
// var prettyBytes = require('pretty-bytes') // var prettyBytes = require('pretty-bytes')
var airplay = require('airplay-js')
var chromecasts = require('chromecasts')
var createTorrent = require('create-torrent') var createTorrent = require('create-torrent')
var dragDrop = require('drag-drop') var dragDrop = require('drag-drop')
var electron = require('electron') var electron = require('electron')
var networkAddress = require('network-address')
var path = require('path') var path = require('path')
var throttle = require('throttleit') var throttle = require('throttleit')
var thunky = require('thunky') var thunky = require('thunky')
@@ -26,7 +29,11 @@ global.WEBTORRENT_ANNOUNCE = createTorrent.announceList
}) })
var state = global.state = { var state = global.state = {
torrents: [] torrents: [],
server: null,
player: null,
chromcast: null,
airplay: null
} }
var currentVDom, rootElement, getClient, updateThrottled var currentVDom, rootElement, getClient, updateThrottled
@@ -53,6 +60,15 @@ function init () {
getClient(function () {}) getClient(function () {})
dragDrop('body', onFiles) dragDrop('body', onFiles)
chromecasts().on('update', function (player) {
state.chromecasts = player
update()
})
airplay.createBrowser().on('deviceOn', function (player) {
state.airplay = player
}).start()
} }
init() init()
@@ -66,20 +82,23 @@ function update () {
function handler (action, ...args) { function handler (action, ...args) {
console.log('handler: %s %o', action, args) console.log('handler: %s %o', action, args)
if (action === 'addTorrent') { if (action === 'addTorrent') {
var torrentId = args[0] addTorrent(args[0] /* torrentId */)
addTorrent(torrentId)
} }
if (action === 'seed') { if (action === 'seed') {
var files = args[0] seed(args[0] /* files */)
seed(files)
} }
if (action === 'openPlayer') { if (action === 'openPlayer') {
var torrent = args[0] openPlayer(args[0] /* torrent */)
openPlayer(torrent)
} }
if (action === 'closePlayer') { if (action === 'closePlayer') {
closePlayer() closePlayer()
} }
if (action === 'openChromecast') {
openChromecast(args[0] /* torrent */)
}
if (action === 'openAirplay') {
openAirplay(args[0] /* torrent */)
}
} }
electron.ipcRenderer.on('action', function (e, action, ...args) { electron.ipcRenderer.on('action', function (e, action, ...args) {
@@ -161,7 +180,7 @@ function torrentReady (torrent) {
update() update()
} }
function openPlayer (torrent) { function startServer (torrent, cb) {
// use largest file // use largest file
var index = torrent.files.indexOf(torrent.files.reduce(function (a, b) { var index = torrent.files.indexOf(torrent.files.reduce(function (a, b) {
return a.length > b.length ? a : b return a.length > b.length ? a : b
@@ -170,20 +189,56 @@ function openPlayer (torrent) {
var server = torrent.createServer() var server = torrent.createServer()
server.listen(0, function () { server.listen(0, function () {
var port = server.address().port var port = server.address().port
state.player = { var urlSuffix = ':' + port + '/' + index
state.server = {
server: server, server: server,
url: 'http://localhost:' + port + '/' + index localURL: 'http://localhost' + urlSuffix,
networkURL: 'http://' + networkAddress() + urlSuffix
} }
cb()
})
}
function closeServer () {
state.server.server.destroy()
state.server = null
}
function openPlayer (torrent) {
startServer(torrent, function () {
state.player = 'local'
update() update()
}) })
} }
function closePlayer () { function closePlayer () {
state.player.server.destroy() closeServer()
state.player = null state.player = null
update() update()
} }
function openChromecast (torrent) {
startServer(torrent, function () {
console.log(state.server.networkURL)
state.chromecast.play(state.server.networkURL, { title: torrent.name })
state.chromecast.on('error', function (err) {
err.message = 'Chromecast: ' + err.message
onError(err)
})
state.player = 'chromecast'
update()
})
}
function openAirplay (torrent) {
startServer(torrent, function () {
state.airplay.play(state.server.networkURL, 0, function () {})
// TODO: handle airplay errors
state.player = 'airplay'
update()
})
}
// function onTorrent (torrent) { // function onTorrent (torrent) {
// function updateSpeed () { // function updateSpeed () {
// ipc.send('') // ipc.send('')

View File

@@ -3,10 +3,10 @@ module.exports = App
var h = require('virtual-dom/h') var h = require('virtual-dom/h')
function App (state, handler) { function App (state, handler) {
if (state.player) { if (state.player === 'local') {
return h('.player', [ return h('.player', [
h('video', { h('video', {
src: state.player.url, src: state.server.localURL,
autoplay: true, autoplay: true,
controls: true controls: true
}), }),
@@ -34,15 +34,39 @@ function App (state, handler) {
})() })()
]) ])
]), ]),
h('a.play', { h('a.btn.play', {
className: !torrent.ready ? 'disabled' : '', className: !torrent.ready ? 'disabled' : '',
onclick: openPlayer onclick: openPlayer
}, '▶') }, '▶'),
(function () {
if (state.chromecast) {
return h('a.btn.chromecast', {
className: !torrent.ready ? 'disabled' : '',
onclick: openChromecast
}, 'C')
}
})(),
(function () {
if (state.airplay) {
return h('a.btn.airplay', {
className: !torrent.ready ? 'disabled' : '',
onclick: openAirplay
}, 'A')
}
})()
]) ])
function openPlayer () { function openPlayer () {
handler('openPlayer', torrent) handler('openPlayer', torrent)
} }
function openChromecast () {
handler('openChromecast', torrent)
}
function openAirplay () {
handler('openAirplay', torrent)
}
}) })
return h('.app', [ return h('.app', [
h('.torrent-list', list), h('.torrent-list', list),

View File

@@ -11,10 +11,13 @@
"url": "https://github.com/feross/webtorrent-app/issues" "url": "https://github.com/feross/webtorrent-app/issues"
}, },
"dependencies": { "dependencies": {
"airplay-js": "^0.2.16",
"chromecasts": "^1.8.0",
"create-torrent": "^3.22.1", "create-torrent": "^3.22.1",
"debug": "^2.2.0", "debug": "^2.2.0",
"drag-drop": "^2.3.1", "drag-drop": "^2.3.1",
"electron-debug": "^0.5.0", "electron-debug": "^0.5.0",
"network-address": "^1.1.0",
"pretty-bytes": "^3.0.0", "pretty-bytes": "^3.0.0",
"throttleit": "^1.0.0", "throttleit": "^1.0.0",
"thunky": "^0.1.0", "thunky": "^0.1.0",