add chromecast/airplay support
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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('')
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user