Ver código fonte

now automatically finds subtitles

master
mortie 7 anos atrás
pai
commit
f1cef0cc1a
9 arquivos alterados com 110 adições e 21 exclusões
  1. 2
    1
      conf.json.example
  2. 30
    3
      js/play/index.js
  3. 11
    4
      js/play/player.js
  4. 53
    0
      js/play/subtitle-finder.js
  5. 8
    8
      js/play/torrent-streamer.js
  6. 1
    0
      package.json
  7. 2
    2
      server.js
  8. 1
    1
      web/index.html
  9. 2
    2
      web/style.css

+ 2
- 1
conf.json.example Ver arquivo

@@ -1,3 +1,4 @@
{
"tmpdir": "tmp"
"tmpdir": "tmp",
"subtitles": "en"
}

+ 30
- 3
js/play/index.js Ver arquivo

@@ -1,6 +1,9 @@
var fs = require("fs");
var pathlib = require("path");
var player = require("./player");
var httpStream = require("./http-stream");
var torrentStreamer = require("./torrent-streamer");
var subtitleFinder = require("./subtitle-finder");

exports.httpPath = player.httpPath;

@@ -11,18 +14,42 @@ exports.init = function(_app, conf) {
player.init(app, conf);
httpStream.init(app, conf);
torrentStreamer.init(app, conf);
subtitleFinder.init(app, conf);
}

exports.playFile = function(path, cb) {
player.play(path, cb);

// Find file's length
fs.stat(path, (err, stat) => {

// Find subtitles
subtitleFinder.find(stat.size, pathlib.basename(path), subFile => {

// Play!
player.play(path, subFile, cb);
});
});
}

exports.playUrl = function(path, cb) {

// Just play, we won't bother finding subtitles
player.play(path, null, cb);
}

exports.playTorrent = function(magnet, cb) {
torrentStreamer.stream(magnet, err => {

// Stream torrent
torrentStreamer.stream(magnet, (err, filesize, filename) => {
if (err)
return cb(err);

player.play(app.getAddress()+httpStream.httpPath, cb);
// Find subtitles
subtitleFinder.find(filesize, filename, subFile => {

// Play!
player.play(app.getAddress()+httpStream.httpPath, subFile, cb);
});
});
}


+ 11
- 4
js/play/player.js Ver arquivo

@@ -83,20 +83,27 @@ exports.isPlaying = function() {
return child != null;
}

exports.play = function(path, cb) {
exports.play = function(path, subFile, cb) {
exports.stop();

var lchild = spawn("mpv", [
var args = [
path,
"--no-cache-pause",
"--no-resume-playback",
"--input-unix-socket", ipcServer
], { stdio: "inherit" });
];

if (subFile) {
args.push("--sub-file");
args.push(subFile);
}

var lchild = spawn("mpv", args, { stdio: "inherit" });
child = lchild;

lchild.running = true;

lchild.once("close", () => {
console.log("child closed");
if (lchild.running) exports.stop();
});
lchild.on("error", err => console.error(err.toString()));

+ 53
- 0
js/play/subtitle-finder.js Ver arquivo

@@ -0,0 +1,53 @@
var OpenSubtitles = require("opensubtitles-api");
var fs = require("fs");
var http = require("http");
var urllib = require("url");

var subs = new OpenSubtitles({ useragent: "mmpc-media-streamer" });

var conf;

exports.init = function(app, _conf) {
conf = _conf;
}

exports.find = function(filesize, filename, cb) {
if (!conf.subtitles)
return cb();

var subFile = conf.tmpdir+"/subs.srt";
try {
fs.unlinkSync(subFile);
} catch (err) {}

subs.search({
sublanguageid: conf.subtitles,
filesize: filesize,
filename: filename
}).then(subtitles => {
var sub = subtitles[conf.subtitles];
if (!sub || !sub.url)
return cb();

try {
var ws = fs.createWriteStream(subFile);
} catch (err) {
console.trace(err);
cb();
}

http.request(urllib.parse(sub.url), res => {
res.pipe(ws);

res
.on("error", err => {
console.trace(err);
cb();
})
.on("end", () => {
ws.close();
cb(subFile);
});
}).end();
});
}

+ 8
- 8
js/play/torrent-streamer.js Ver arquivo

@@ -2,7 +2,6 @@ var httpStream = require("./http-stream");
var torrentStream = require("torrent-stream");

var mediarx = /\.(mp4|mkv|mov|avi|ogv)$/;
var tmpdir = process.cwd()+"/tmp";

var engine;
var conf;
@@ -16,9 +15,13 @@ exports.stream = function(magnet, cb) {
return engine.destroy(() =>
{ engine = null; exports.stream(magnet, cb) });

engine = torrentStream(magnet, {
tmp: conf.tmpdir
});
try {
engine = torrentStream(magnet, {
tmp: conf.tmpdir
});
} catch (err) {
return cb(err.toString());
}

engine.on("ready", () => {
var file = null;
@@ -36,17 +39,14 @@ exports.stream = function(magnet, cb) {
file.select();

httpStream.readStreamCreator = function(options) {
console.log("creating stream with", options);
var rs = file.createReadStream(options);
rs.filesize = file.length;
rs.filename = file.name;

rs.on("close", () => console.log("stream closing"));

return rs;
}

cb();
cb(null, file.length, file.name);
});
}


+ 1
- 0
package.json Ver arquivo

@@ -11,6 +11,7 @@
"license": "ISC",
"dependencies": {
"mime": "^1.3.4",
"opensubtitles-api": "^3.2.0",
"torrent-stream": "^1.0.3",
"webstuff": "^1.4.0"
}

+ 2
- 2
server.js Ver arquivo

@@ -18,12 +18,12 @@ app.express.use((req, res, next) => {

app.static("web");

app.post("/play/link", (req, res) => {
app.post("/play/url", (req, res) => {
req.parseBody((err, fields) => {
if (!fields.url)
return res.redirect("/");

play.playFile(fields.url, () => {
play.playUrl(fields.url, () => {
res.redirect(play.httpPath);
});
});

+ 1
- 1
web/index.html Ver arquivo

@@ -8,7 +8,7 @@
</head>
<body>
<div id="parts">
<form class="part" method="post" action="/play/link">
<form class="part" method="post" action="/play/url">
<div class="name">URL:</div>
<input type="url" name="url" autocomplete="off">
<button>Play</button>

+ 2
- 2
web/style.css Ver arquivo

@@ -8,7 +8,7 @@
}

#parts .part {
border-bottom: 1px solid #eee;
border-bottom: 1px solid #ccc;
padding: 20px 10px;
padding-top: 17px;
}
@@ -28,5 +28,5 @@

#parts .part input,
#parts .part button {
height: 25px;
height: 28px;
}

Carregando…
Cancelar
Salvar