| @@ -31,7 +31,7 @@ exports.rmdir = function(dir) { | |||
| try { | |||
| fs.accessSync(dir, fs.F_OK) | |||
| } catch (err) { | |||
| console.trace(err); | |||
| console.log(err.toString()); | |||
| return; | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| var spawn = require("child_process").spawn; | |||
| module.exports = function(name, msg) { | |||
| var args = ["--urgency", "low"]; | |||
| args.push(name); | |||
| if (msg) args.push(msg); | |||
| spawn("notify-send", args); | |||
| } | |||
| @@ -1,6 +1,10 @@ | |||
| var fs = require("fs"); | |||
| var http = require("http"); | |||
| var https = require("https"); | |||
| var pathlib = require("path"); | |||
| var urllib = require("url"); | |||
| var fsutil = require("../fsutil"); | |||
| var notify = require("../notify"); | |||
| var player = require("./player"); | |||
| var httpStream = require("./http-stream"); | |||
| var torrentStreamer = require("./torrent-streamer"); | |||
| @@ -29,6 +33,8 @@ exports.init = function(_app, _conf) { | |||
| exports.playFile = function(path, cb, filename) { | |||
| filename = filename || pathlib.basename(path); | |||
| notify("Playing file", filename); | |||
| // Find file's length | |||
| fs.stat(path, (err, stat) => { | |||
| if (err) { | |||
| @@ -38,7 +44,6 @@ exports.playFile = function(path, cb, filename) { | |||
| // Find subtitles | |||
| subtitleFinder.find(stat.size, filename, subFile => { | |||
| exports.cleanupFiles.push(subFile); | |||
| // Play! | |||
| player.play(path, subFile, cb); | |||
| @@ -46,14 +51,18 @@ exports.playFile = function(path, cb, filename) { | |||
| }); | |||
| } | |||
| exports.playUrl = function(path, cb) { | |||
| exports.playUrl = function(url, cb) { | |||
| notify("Playing url...", url); | |||
| // Just play, we won't bother finding subtitles | |||
| player.play(path, null, cb); | |||
| player.play(url, null, cb); | |||
| } | |||
| exports.playTorrent = function(magnet, cb) { | |||
| notify("Playing torrent..."); | |||
| // Stream torrent | |||
| torrentStreamer.stream(magnet, (err, filesize, filename) => { | |||
| if (err) | |||
| @@ -61,14 +70,51 @@ exports.playTorrent = function(magnet, cb) { | |||
| // Find subtitles | |||
| subtitleFinder.find(filesize, filename, subFile => { | |||
| exports.cleanupFiles.push(subFile); | |||
| // Play! | |||
| notify("Starting playback.", filename); | |||
| player.play(app.getAddress()+httpStream.httpPath, subFile, cb); | |||
| }); | |||
| }); | |||
| } | |||
| exports.playTorrentPage = function(url, cb) { | |||
| function findMagnet(str) { | |||
| var rx = /['"](magnet:[^'"]+)['"]/; | |||
| var match = str.match(rx); | |||
| if (!match) | |||
| return null; | |||
| return match[1]; | |||
| } | |||
| notify("Finding magnet on torrent page...", url); | |||
| var urlobj = urllib.parse(url); | |||
| var o = urlobj.protocol === "https:" ? https : http; | |||
| o.request(urlobj, res => { | |||
| var str = ""; | |||
| res | |||
| .on("data", d => str += d ) | |||
| .on("error", err => { | |||
| notify("Error downloading page!", err.toString()); | |||
| console.trace(err); | |||
| cb(); | |||
| }) | |||
| .on("end", () => { | |||
| var magnet = findMagnet(str); | |||
| if (!magnet) { | |||
| notify("No magnet link on page!"); | |||
| cb(); | |||
| return; | |||
| } | |||
| exports.playTorrent(magnet, cb); | |||
| }); | |||
| }).end(); | |||
| } | |||
| exports.isPlaying = player.isPlaying; | |||
| player.onstop = function() { | |||
| @@ -79,7 +125,7 @@ player.onstop = function() { | |||
| try { | |||
| fs.unlink(f, err => { if (err) console.trace(err) }); | |||
| } catch (err) { | |||
| console.trace(err); | |||
| console.log(err.toString()); | |||
| } | |||
| }); | |||
| exports.cleanupFiles = []; | |||
| @@ -41,12 +41,13 @@ exports.find = function(filesize, filename, cb) { | |||
| res | |||
| .on("error", err => { | |||
| notify("Error finding subtitles", err.toString()); | |||
| console.trace(err); | |||
| cb(); | |||
| }) | |||
| .on("end", () => { | |||
| ws.close(); | |||
| cb(subFile); | |||
| setTimeout(() => cb(subFile), 500); | |||
| }); | |||
| }).end(); | |||
| }); | |||
| @@ -1,7 +1,17 @@ | |||
| var httpStream = require("./http-stream"); | |||
| var torrentStream = require("torrent-stream"); | |||
| var mediarx = /\.(mp4|mkv|mov|avi|ogv)$/; | |||
| var mediaformats = [ | |||
| "webm", "mkv", "flv", "vob", "avi", "mov","wmv", "you", | |||
| "asf", "mp4", "m4p", "m4v", "svi", "ogv", "ogg" | |||
| ] | |||
| var rxstr = | |||
| "\\.("+ | |||
| mediaformats.join("|")+ | |||
| ")$"; | |||
| var mediarx = new RegExp(rxstr, "i"); | |||
| var engine; | |||
| var conf; | |||
| @@ -1,6 +1,7 @@ | |||
| var fs = require("fs"); | |||
| var pathlib = require("path"); | |||
| var web = require("webstuff"); | |||
| var notify = require("./js/notify"); | |||
| var play = require("./js/play"); | |||
| var fsutil = require("./js/fsutil"); | |||
| @@ -23,24 +24,22 @@ app.post("/play/url", (req, res) => { | |||
| if (!fields.url) | |||
| return res.redirect("/"); | |||
| play.playUrl(fields.url, () => { | |||
| function cb() { | |||
| res.redirect(play.httpPath); | |||
| }); | |||
| }); | |||
| }); | |||
| app.post("/play/magnet", (req, res) => { | |||
| req.parseBody((err, fields) => { | |||
| if (!fields.magnet) | |||
| return res.redirect("/"); | |||
| } | |||
| play.playTorrent(fields.magnet, () => { | |||
| res.redirect(play.httpPath); | |||
| }); | |||
| if (fields.url.indexOf("magnet:") === 0) { | |||
| play.playTorrent(fields.url, cb); | |||
| } else if (fields.url.indexOf("/torrent") !== -1) { | |||
| play.playTorrentPage(fields.url, cb); | |||
| } else { | |||
| play.playUrl(fields.url, cb); | |||
| } | |||
| }); | |||
| }); | |||
| app.post("/play/file", (req, res) => { | |||
| notify("Receiving file..."); | |||
| req.parseBody((err, fields, files) => { | |||
| var file = files.file; | |||
| @@ -9,17 +9,11 @@ | |||
| <body> | |||
| <div id="parts"> | |||
| <form class="part" method="post" action="/play/url"> | |||
| <div class="name">URL:</div> | |||
| <div class="name">URL or Magnet Link:</div> | |||
| <input type="url" name="url" autocomplete="off"> | |||
| <button>Play</button> | |||
| </form> | |||
| <form class="part" method="post" action="/play/magnet"> | |||
| <div class="name">Magnet Link:</div> | |||
| <input type="url" name="magnet" autocomplete="off"> | |||
| <button>Play</button> | |||
| </form> | |||
| <form class="part" method="post" enctype="multipart/form-data" action="/play/file"> | |||
| <div class="name">File:</div> | |||
| <input type="file" name="file" autocomplete="off"> | |||