initial commit

This commit is contained in:
Al Beano 2016-07-18 14:14:40 +01:00
commit 68534d1122
5 changed files with 225 additions and 0 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# checkzones
Static webapp to check the quality of a particular frame based on a mediainfo output.
Thanks to F00D and JamesRustles for helping with the logic of this.
[Try it](http://lb.soupwhale.com/checkzones)

6
bootstrap.css vendored Normal file

File diff suppressed because one or more lines are too long

21
checkzones.css Normal file
View File

@ -0,0 +1,21 @@
.container {
padding-top: 20px;
}
html, body, .container, .col-md-6 {
height: 100%;
}
#mediainfo {
height: calc(100% - 54px);
}
#frames, #check {
width: calc(50% - 1px);
display: inline;
}
#results {
height: calc(100% - 20px);
background-color: white;
}

165
checkzones.js Normal file
View File

@ -0,0 +1,165 @@
var errors = {
"mediainfo" : "Couldn't parse mediainfo. Check that it is a valid video mediainfo which contains zones.",
"frames" : "Please check that the frame count you entered is correct, and the mediainfo is valid.",
"check" : "Could not parse the list of frames to check. Please check it.",
"unknown" : "An unknown error occured.",
};
function getBaseRate(settings) {
for (var i = 0; i < settings.length; i++) {
var setting = settings[i];
if (/^crf=/.test(setting)) {
return ["crf", setting.replace(/^crf=/, "")];
} else if (/^bitrate=/.test(setting)) {
return ["bitrate", setting.replace(/^bitrate=/, "")];
}
}
};
function parseZones(zones, base, numframes) {
numframes = parseInt(numframes);
var frames = new Array(numframes);
for (var i = 0; i < zones.length; i++) {
var zone = zones[i].split(",");
if (parseInt(zone[1]) > numframes) {
return null;
}
if (/^crf=/.test(zone[2])) {
var crf = zone[2].replace(/^crf=/, "");
frames.fill(["crf", crf], parseInt(zone[0]), parseInt(zone[1])+1);
} else if (/^b=/.test(zone[2])) {
var b = zone[2].replace(/^b=/, "");
frames.fill(["b", b], parseInt(zone[0]), parseInt(zone[1])+1);
}
}
// fill in all the unfilled frames
for (var i = 0; i < frames.length; i++) {
if (!frames[i]) {
frames[i] = base;
}
}
return frames;
};
function checkZones(mediainfo, numframes, check) {
// Extract encode settings
var lines = mediainfo.split('\n');
var settings;
for (var i = 0; i < lines.length; i++) {
if (/^Encoding\ settings\ :\ /.test(lines[i])) {
// This is the line we want
settings = lines[i].replace(/^Encoding\ settings\ :\ /, "").split(" / ");
}
}
if (!settings) {
return errors["mediainfo"];
}
// Find base CRF or bitrate
var base = getBaseRate(settings);
if (!base) {
return errors["mediainfo"];
}
var frames;
for (var i = 0; i < settings.length; i++) {
var setting = settings[i];
if (/^zones=/.test(setting)) {
frames = parseZones(setting.replace(/^zones=/, "").split("/"), base, numframes);
}
}
if (!frames) {
return errors["frames"];
}
// Check input
var to_check = check.split(",");
for (var i = 0; i < to_check.length; i++) {
if (/^[0-9]+$/.test(to_check[i])) {
to_check[i] = parseInt(to_check[i]);
} else {
return errors["check"];
}
}
// Check each frame
var results = {
frames : {},
zones : {},
};
for (var i = 0; i < to_check.length; i++) {
var frame = to_check[i];
results["frames"][frame] = frames[frame][0] + "=" + frames[frame][1];
}
// Calculate percentages
var frequencies = new Object;
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
if (frame[0] != base[0] || frame[1] != base[1]) {
// does the frequencies object already have an entry for this rate?
if (frequencies[frame[0] + "=" + frame[1]]) {
// yes
frequencies[frame[0] + "=" + frame[1]]++;
} else {
// no
frequencies[frame[0] + "=" + frame[1]] = 1;
}
}
}
for (var rate in frequencies) {
if (!frequencies.hasOwnProperty(rate)) continue;
results["zones"][rate] = parseInt(frequencies[rate]) / parseInt(numframes) * 100;
}
// sorting
var rates = new Array;
for (var rate in results["zones"]) {
if (!results["zones"].hasOwnProperty(rate)) continue;
rates.push(rate);
}
rates.sort(
function(a, b) {
c = [a, b].map(
function(x) {
return parseFloat(x.replace(/^(crf|b)=/, ""));
}
);
return c[0] - c[1];
}
);
// Build report
var output;
if (base[0] === "crf") {
output = "Base CRF: " + base[1];
} else if (base[0] === "bitrate") {
output = "Base bitrate: " + base[0];
}
output += "\n\n";
for (var frame in results["frames"]) {
if (!results["frames"].hasOwnProperty(frame)) continue;
output += "Frame " + frame + ": " + results["frames"][frame] + "\n";
}
output += "\n";
for (var zone in results["zones"]) {
if (!results["zones"].hasOwnProperty(zone)) continue;
output += zone + ": " + parseFloat(results["zones"][zone]).toFixed(3) + "% (" + frequencies[zone] + " frames)\n";
}
return output;
};
function update() {
var mediainfo = document.getElementById("mediainfo").value;
var frames = document.getElementById("frames").value;
var check = document.getElementById("check").value;
document.getElementById("results").value = checkZones(mediainfo, frames, check);
};

27
index.html Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf8">
<link rel="stylesheet" href="bootstrap.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" href="checkzones.css" type="text/css">
<title>
Zone checker
</title>
</head>
<body>
<!--
Mediainfo zone checker by albino
https://neetco.de/albino/checkzones
-->
<div class="container">
<div class="col-md-6">
<textarea id="mediainfo" placeholder="Paste your mediainfo here..." class="form-control" onchange="update();" onpaste="update();" onkeyup="update();"></textarea>
<input type="number" class="form-control" id="frames" placeholder="Number of frames" onchange="update();" onpaste="update();" onkeyup="update();"><input type="text" class="form-control" id="check" placeholder="Frames to check (comma separated)" onchange="update();" onpaste="update();" onkeyup="update();">
</div>
<div class="col-md-6">
<textarea id="results" placeholder="Results..." readonly class="form-control"></textarea>
</div>
</div>
<script src="checkzones.js" type="text/javascript"></script>
</body>
</html>