mirror of https://github.com/calzoneman/sync.git
Fix #566
Refactored the ffprobe stream-selection logic to handle rejected files better: * Streams tagged as a non-default disposition are not considered * If a file has any video stream, the audio stream will be ignored This should prevent videos from being misreported as invalid audio codecs, etc.
This commit is contained in:
parent
a96b85fa5b
commit
7448429341
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.14.3",
|
"version": "3.14.4",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
@ -113,6 +113,20 @@ function readOldFormat(buf) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAlternateDisposition(stream) {
|
||||||
|
if (!stream.disposition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in stream) {
|
||||||
|
if (key !== "default" && stream.disposition[key]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function reformatData(data) {
|
function reformatData(data) {
|
||||||
var reformatted = {};
|
var reformatted = {};
|
||||||
|
|
||||||
|
@ -127,24 +141,54 @@ function reformatData(data) {
|
||||||
reformatted.title = data.format.tags ? data.format.tags.title : null;
|
reformatted.title = data.format.tags ? data.format.tags.title : null;
|
||||||
var container = data.format.format_name.split(",")[0];
|
var container = data.format.format_name.split(",")[0];
|
||||||
|
|
||||||
data.streams.forEach(function (stream) {
|
var isVideo = false;
|
||||||
|
var audio = null;
|
||||||
|
for (var i = 0; i < data.streams.length; i++) {
|
||||||
|
const stream = data.streams[i];
|
||||||
|
|
||||||
|
// Trash streams with alternate dispositions, e.g. `attached_pic` for
|
||||||
|
// embedded album art on MP3s (not a real video stream)
|
||||||
|
if (isAlternateDisposition(stream)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (stream.codec_type === "video" &&
|
if (stream.codec_type === "video" &&
|
||||||
acceptedCodecs.hasOwnProperty(container + "/" + stream.codec_name)) {
|
!audioOnlyContainers.hasOwnProperty(container)) {
|
||||||
|
isVideo = true;
|
||||||
|
if (acceptedCodecs.hasOwnProperty(container + "/" + stream.codec_name)) {
|
||||||
reformatted.vcodec = stream.codec_name;
|
reformatted.vcodec = stream.codec_name;
|
||||||
if (!reformatted.title && stream.tags) {
|
reformatted.medium = "video";
|
||||||
|
reformatted.type = [container, reformatted.vcodec].join("/");
|
||||||
|
|
||||||
|
if (stream.tags && stream.tags.title) {
|
||||||
reformatted.title = stream.tags.title;
|
reformatted.title = stream.tags.title;
|
||||||
}
|
}
|
||||||
} else if (stream.codec_type === "audio") {
|
|
||||||
reformatted.acodec = stream.codec_name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (reformatted.vcodec && !(audioOnlyContainers.hasOwnProperty(container))) {
|
return reformatted;
|
||||||
reformatted.type = [container, reformatted.vcodec].join("/");
|
}
|
||||||
reformatted.medium = "video";
|
} else if (stream.codec_type === "audio" && !audio &&
|
||||||
} else if (reformatted.acodec) {
|
acceptedAudioCodecs.hasOwnProperty(stream.codec_name)) {
|
||||||
reformatted.type = [container, reformatted.acodec].join("/");
|
audio = {
|
||||||
reformatted.medium = "audio";
|
acodec: stream.codec_name,
|
||||||
|
medium: "audio"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (stream.tags && stream.tags.title) {
|
||||||
|
audio.title = stream.tags.title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override to make sure video files with no valid video streams but some
|
||||||
|
// acceptable audio stream are rejected.
|
||||||
|
if (isVideo) {
|
||||||
|
return reformatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audio) {
|
||||||
|
for (var key in audio) {
|
||||||
|
reformatted[key] = audio[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reformatted;
|
return reformatted;
|
||||||
|
@ -273,10 +317,6 @@ exports.query = function (filename, cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.medium === "video") {
|
if (data.medium === "video") {
|
||||||
if (!acceptedCodecs.hasOwnProperty(data.type)) {
|
|
||||||
return cb("Unsupported video codec " + data.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
title: data.title || "Raw Video",
|
title: data.title || "Raw Video",
|
||||||
duration: data.duration,
|
duration: data.duration,
|
||||||
|
@ -286,10 +326,6 @@ exports.query = function (filename, cb) {
|
||||||
|
|
||||||
cb(null, data);
|
cb(null, data);
|
||||||
} else if (data.medium === "audio") {
|
} else if (data.medium === "audio") {
|
||||||
if (!acceptedAudioCodecs.hasOwnProperty(data.acodec)) {
|
|
||||||
return cb("Unsupported audio codec " + data.acodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
title: data.title || "Raw Audio",
|
title: data.title || "Raw Audio",
|
||||||
duration: data.duration,
|
duration: data.duration,
|
||||||
|
@ -299,9 +335,8 @@ exports.query = function (filename, cb) {
|
||||||
|
|
||||||
cb(null, data);
|
cb(null, data);
|
||||||
} else {
|
} else {
|
||||||
return cb("Parsed metadata did not contain a valid video or audio " +
|
return cb("File did not contain an acceptable codec. See " +
|
||||||
"stream. Either the file is invalid or it has a format " +
|
"https://git.io/va9g9 for details.");
|
||||||
"unsupported by this server's version of ffmpeg.");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2064,6 +2064,7 @@ function queueMessage(data, type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var text = data.msg;
|
var text = data.msg;
|
||||||
|
text = text.replace(/(https?:[^ ]+)/g, "<a href='$1' target='_blank'>$1</a>");
|
||||||
if (typeof data.link === "string") {
|
if (typeof data.link === "string") {
|
||||||
text += "<br><a href='" + data.link + "' target='_blank'>" +
|
text += "<br><a href='" + data.link + "' target='_blank'>" +
|
||||||
data.link + "</a>";
|
data.link + "</a>";
|
||||||
|
|
Loading…
Reference in New Issue