Browse Source

now automatically finds subtitles

master
mortie 7 years ago
parent
commit
f1cef0cc1a
9 changed files with 110 additions and 21 deletions
  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 View File

{ {
"tmpdir": "tmp"
"tmpdir": "tmp",
"subtitles": "en"
} }

+ 30
- 3
js/play/index.js View File

var fs = require("fs");
var pathlib = require("path");
var player = require("./player"); var player = require("./player");
var httpStream = require("./http-stream"); var httpStream = require("./http-stream");
var torrentStreamer = require("./torrent-streamer"); var torrentStreamer = require("./torrent-streamer");
var subtitleFinder = require("./subtitle-finder");


exports.httpPath = player.httpPath; exports.httpPath = player.httpPath;


player.init(app, conf); player.init(app, conf);
httpStream.init(app, conf); httpStream.init(app, conf);
torrentStreamer.init(app, conf); torrentStreamer.init(app, conf);
subtitleFinder.init(app, conf);
} }


exports.playFile = function(path, cb) { 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) { exports.playTorrent = function(magnet, cb) {
torrentStreamer.stream(magnet, err => {

// Stream torrent
torrentStreamer.stream(magnet, (err, filesize, filename) => {
if (err) if (err)
return cb(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 View File

return child != null; return child != null;
} }


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


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

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

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


lchild.running = true; lchild.running = true;


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

+ 53
- 0
js/play/subtitle-finder.js View File

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 View File

var torrentStream = require("torrent-stream"); var torrentStream = require("torrent-stream");


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


var engine; var engine;
var conf; var conf;
return engine.destroy(() => return engine.destroy(() =>
{ engine = null; exports.stream(magnet, cb) }); { 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", () => { engine.on("ready", () => {
var file = null; var file = null;
file.select(); file.select();


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


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

return rs; return rs;
} }


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



+ 1
- 0
package.json View File

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

+ 2
- 2
server.js View File



app.static("web"); app.static("web");


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


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

+ 1
- 1
web/index.html View File

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

+ 2
- 2
web/style.css View File

} }


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


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

Loading…
Cancel
Save