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 Config = require("./config");
|
||||
var spawn = require("child_process").spawn;
|
||||
var https = require("https");
|
||||
var http = require("http");
|
||||
var urlparse = require("url");
|
||||
|
||||
var USE_JSON = true;
|
||||
|
||||
|
@ -21,6 +24,47 @@ var audioOnlyContainers = {
|
|||
"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) {
|
||||
var lines = buf.split("\n");
|
||||
var tmp = { tags: {} };
|
||||
|
@ -149,64 +193,69 @@ exports.query = function (filename, cb) {
|
|||
"or HTTPS");
|
||||
}
|
||||
|
||||
exports.ffprobe(filename, function (err, data) {
|
||||
testUrl(filename, function (err) {
|
||||
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 ffmpeg");
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
var m = err.message.match(/(http error .*)/i);
|
||||
if (m) return cb(m[1]);
|
||||
exports.ffprobe(filename, function (err, data) {
|
||||
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");
|
||||
}
|
||||
|
||||
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 {
|
||||
Logger.errlog.log(err.stack || err);
|
||||
return cb("Unable to query file data with ffmpeg");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
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 a new issue