mirror of https://github.com/calzoneman/sync.git
Preflight raw file requests to get better error messages
This commit is contained in:
parent
cd0cc69fd8
commit
c4add8f142
155
lib/ffmpeg.js
155
lib/ffmpeg.js
|
@ -1,6 +1,9 @@
|
||||||
var Logger = require("./logger");
|
var Logger = require("./logger");
|
||||||
var Config = require("./config");
|
var Config = require("./config");
|
||||||
var spawn = require("child_process").spawn;
|
var spawn = require("child_process").spawn;
|
||||||
|
var https = require("https");
|
||||||
|
var http = require("http");
|
||||||
|
var urlparse = require("url");
|
||||||
|
|
||||||
var USE_JSON = true;
|
var USE_JSON = true;
|
||||||
|
|
||||||
|
@ -21,6 +24,47 @@ var audioOnlyContainers = {
|
||||||
"mp3": true
|
"mp3": true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function testUrl(url, cb, redirected) {
|
||||||
|
var data = urlparse.parse(url);
|
||||||
|
if (!/https?:/.test(data.protocol)) {
|
||||||
|
return cb("Video links must start with http:// or https://");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.hostname) {
|
||||||
|
return cb("Invalid link");
|
||||||
|
}
|
||||||
|
|
||||||
|
var transport = (data.protocol === "https:") ? https : http;
|
||||||
|
data.method = "HEAD";
|
||||||
|
var req = transport.request(data, function (res) {
|
||||||
|
req.abort();
|
||||||
|
|
||||||
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
||||||
|
if (redirected) {
|
||||||
|
return cb("Too many redirects. Please provide a direct link to the "
|
||||||
|
"file");
|
||||||
|
}
|
||||||
|
return testUrl(res.headers['location'], cb, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.statusCode !== 200) {
|
||||||
|
return cb("HTTP " + res.statusCode + " " + res.statusMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!/^audio|^video/.test(res.headers['content-type'])) {
|
||||||
|
return cb("Server did not return an audio or video file");
|
||||||
|
}
|
||||||
|
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on("error", function (err) {
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
req.end();
|
||||||
|
}
|
||||||
|
|
||||||
function readOldFormat(buf) {
|
function readOldFormat(buf) {
|
||||||
var lines = buf.split("\n");
|
var lines = buf.split("\n");
|
||||||
var tmp = { tags: {} };
|
var tmp = { tags: {} };
|
||||||
|
@ -149,64 +193,69 @@ exports.query = function (filename, cb) {
|
||||||
"or HTTPS");
|
"or HTTPS");
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.ffprobe(filename, function (err, data) {
|
testUrl(filename, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code && err.code === "ENOENT") {
|
return cb(err);
|
||||||
return cb("Failed to execute `ffprobe`. Set ffmpeg.ffprobe-exec to " +
|
}
|
||||||
"the correct name of the executable in config.yaml. If " +
|
|
||||||
"you are using Debian or Ubuntu, it is probably avprobe.");
|
|
||||||
} else if (err.message) {
|
|
||||||
if (err.message.match(/protocol not found/i))
|
|
||||||
return cb("Link uses a protocol unsupported by this server's ffmpeg");
|
|
||||||
|
|
||||||
var m = err.message.match(/(http error .*)/i);
|
exports.ffprobe(filename, function (err, data) {
|
||||||
if (m) return cb(m[1]);
|
if (err) {
|
||||||
|
if (err.code && err.code === "ENOENT") {
|
||||||
|
return cb("Failed to execute `ffprobe`. Set ffmpeg.ffprobe-exec " +
|
||||||
|
"to the correct name of the executable in config.yaml. " +
|
||||||
|
"If you are using Debian or Ubuntu, it is probably " +
|
||||||
|
"avprobe.");
|
||||||
|
} else if (err.message) {
|
||||||
|
if (err.message.match(/protocol not found/i))
|
||||||
|
return cb("Link uses a protocol unsupported by this server's " +
|
||||||
|
"version of ffmpeg");
|
||||||
|
|
||||||
Logger.errlog.log(err.stack || err);
|
Logger.errlog.log(err.stack || err);
|
||||||
|
return cb("Unable to query file data with ffmpeg");
|
||||||
|
} else {
|
||||||
|
Logger.errlog.log(err.stack || err);
|
||||||
|
return cb("Unable to query file data with ffmpeg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = reformatData(data);
|
||||||
|
} catch (e) {
|
||||||
|
Logger.errlog.log(e.stack || e);
|
||||||
return cb("Unable to query file data with ffmpeg");
|
return cb("Unable to query file data with ffmpeg");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.medium === "video") {
|
||||||
|
if (!acceptedCodecs.hasOwnProperty(data.type)) {
|
||||||
|
return cb("Unsupported video codec " + data.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
title: data.title || "Raw Video",
|
||||||
|
duration: data.duration,
|
||||||
|
bitrate: data.bitrate,
|
||||||
|
codec: data.type
|
||||||
|
};
|
||||||
|
|
||||||
|
cb(null, data);
|
||||||
|
} else if (data.medium === "audio") {
|
||||||
|
if (!acceptedAudioCodecs.hasOwnProperty(data.acodec)) {
|
||||||
|
return cb("Unsupported audio codec " + data.acodec);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
title: data.title || "Raw Audio",
|
||||||
|
duration: data.duration,
|
||||||
|
bitrate: data.bitrate,
|
||||||
|
codec: data.acodec
|
||||||
|
};
|
||||||
|
|
||||||
|
cb(null, data);
|
||||||
} else {
|
} else {
|
||||||
Logger.errlog.log(err.stack || err);
|
return cb("Parsed metadata did not contain a valid video or audio " +
|
||||||
return cb("Unable to query file data with ffmpeg");
|
"stream. Either the file is invalid or it has a format " +
|
||||||
|
"unsupported by this server's version of ffmpeg.");
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
try {
|
|
||||||
data = reformatData(data);
|
|
||||||
} catch (e) {
|
|
||||||
Logger.errlog.log(e.stack || e);
|
|
||||||
return cb("Unable to query file data with ffmpeg");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.medium === "video") {
|
|
||||||
if (!acceptedCodecs.hasOwnProperty(data.type)) {
|
|
||||||
return cb("Unsupported video codec " + data.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
title: data.title || "Raw Video",
|
|
||||||
duration: data.duration,
|
|
||||||
bitrate: data.bitrate,
|
|
||||||
codec: data.type
|
|
||||||
};
|
|
||||||
|
|
||||||
cb(null, data);
|
|
||||||
} else if (data.medium === "audio") {
|
|
||||||
if (!acceptedAudioCodecs.hasOwnProperty(data.acodec)) {
|
|
||||||
return cb("Unsupported audio codec " + data.acodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
|
||||||
title: data.title || "Raw Audio",
|
|
||||||
duration: data.duration,
|
|
||||||
bitrate: data.bitrate,
|
|
||||||
codec: data.acodec
|
|
||||||
};
|
|
||||||
|
|
||||||
cb(null, data);
|
|
||||||
} else {
|
|
||||||
return cb("Parsed metadata did not contain a valid video or audio stream. " +
|
|
||||||
"Either the file is invalid or it has a format unsupported by " +
|
|
||||||
"this server's version of ffmpeg.");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue