Overview:
This script imports several columns, showing details about video/movie files, from File Explorer into Directory Opus, and generates some others based on them:
- Length (Duration)
- Relative Length (Duration as a bar graph)
- Dimensions (Width x Height in a single column)
- Definition (a string like "4K" or "Full HD")
- Frame Width
- Frame Height
- Frame Rate
While Opus already has its own internal columns showing some of these details, you may find the Explorer columns work better for you, depending on the types of files and state of video codecs/splitters on your machine.
It's also useful if you want to disable the Movie viewer plugin in Opus, since the built-in columns depend on it.
Before using this script, you might want to check if there are already built-in columns which work for you and, if not, also check if File Explorer itself can do a better job. If neither program can display the data you need then you may need to investigate video codecs/splitters to get things working in either. (That's beyond the scope of this post.)
Grouping by the Dimensions column will split the files into groups based on the Definition column:
- 8K
- 4K
- Quad HD
- Full HD
- HD Ready
- DVD
- Low
- Unspecified
Grouping by the Definition column also groups in the same way, of course.
You can edit the script to add or modify the definition groups or their names.
Installation and Usage:
Requires Directory Opus Pro 12.7.3 beta or above.
- Download: Video_Frame_Columns.js.txt (6.6 KB)
- Open Settings > Preferences / Toolbars / Scripts.
- Drag Video_Frame_Columns.js.txt to the list of scripts.
Several new column will now be available, categorised under:
- Script > Video Frame Columns
You can display, sort and group using the column the same as you would normal built-in columns. For example, right-click the column header, or use the Folder Options dialog.
You can also refer to the column in commands which you can place on toolbar buttons, menu items, hotkeys, etc.
This command will add the Frame Height column and then sort by it:
Set COLUMNSADD="scp:Video Frame Columns/FrameHeight"
Set SORTBY="scp:Video Frame Columns/FrameHeight"
To use the column for searching, use Tools > Find Files, select the Advanced tab, and set up one or more Script column clauses to match (or exclude) the things you are interested in:
History:
2.0 (26/Mar/2018):
- Requires Opus 12.7.3 beta or above.
- Now populates all columns for each file at once, which greatly speeds things up.
- Added Length column.
- Added Relative Length column.
- Added Definition column (8K, 4K, Full HD, etc.).
- Added Dimensions column (combined width and height in a single column, with proper sorting; groups by Definition).
- Framerate is now only shown to two decimal places, and always uses 2 to keep things aligned.
1.0 (03/Mar/2018):
- Initial version.
Script code:
The script code from the download above is reproduced below. This is for people browsing the forum for scripting techniques. You do not need to care about this code if you just want to use the script.
// Video Frame Columns
// This is a script for Directory Opus.
// Adds Explorer's "Length", "Frame Width", "Frame Height" and "Frame Rate" columns to Opus.
function OnInit(initData)
{
initData.name = "Video Frame Columns";
initData.version = "2.0";
initData.copyright = "(c) 2018 Leo Davidson";
initData.url = "https://resource.dopus.com/t/video-width-height-and-framerate-columns/28147";
initData.desc = "Brings Explorer's Length, Frame Width, Frame Height, and Frame Rate columns into Opus.";
initData.default_enable = true;
initData.min_version = "12.7.3";
var col;
var props;
props = DOpus.FSUtil.GetShellPropertyList("System.Media.Duration", "r");
if (props.count == 1)
{
var prop = props(0);
col = initData.AddColumn();
col.name = "Length";
col.multicol = true;
col.method = "OnCol";
col.label = prop.display_name;
col.justify = "right";
col.autogroup = true;
col.autorefresh = 1;
col.userdata = prop.pkey;
// col.type = "string";
var prop = props(0);
col = initData.AddColumn();
col.name = "LengthRelative";
col.multicol = true;
col.method = "OnCol";
col.label = "Relative Length";
col.justify = "left";
col.autogroup = true;
col.userdata = prop.pkey;
col.type = "graphrel0";
col.graph_threshold = -1;
}
propsHeight = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameHeight", "r");
if (propsHeight.count == 1)
{
var prop = propsHeight(0);
col = initData.AddColumn();
col.name = "FrameHeight";
col.multicol = true;
col.method = "OnCol";
col.label = prop.display_name;
col.justify = "right";
col.autogroup = true;
col.autorefresh = 1;
col.userdata = prop.pkey;
col.type = "number";
}
propsWidth = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameWidth", "r");
if (propsWidth.count == 1)
{
var prop = propsWidth(0);
col = initData.AddColumn();
col.name = "FrameWidth";
col.multicol = true;
col.method = "OnCol";
col.label = prop.display_name;
col.justify = "right";
col.autogroup = true;
col.autorefresh = 1;
col.userdata = prop.pkey;
col.type = "number";
}
if (propsHeight.count == 1 && propsWidth.count == 1)
{
var groupOrder = "8K;4K;Quad HD;Full HD;HD Ready;DVD;Low";
col = initData.AddColumn();
col.name = "Definition";
col.multicol = true;
col.method = "OnCol";
col.label = "Definition";
col.justify = "right";
col.autogroup = false;
col.grouporder = groupOrder;
col.userdata = DOpus.Create.Vector(propsHeight(0).pkey+"", propsWidth(0).pkey+"");
// col.type = "string";
col = initData.AddColumn();
col.name = "Dimensions";
col.multicol = true;
col.method = "OnCol";
col.label = "Dimensions";
col.justify = "right";
col.autogroup = false;
col.grouporder = groupOrder;
col.userdata = DOpus.Create.Vector(propsHeight(0).pkey+"", propsWidth(0).pkey+"");
// col.type = "string";
}
props = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameRate", "r");
if (props.count == 1)
{
var prop = props(0);
col = initData.AddColumn();
col.name = "FrameRate";
col.multicol = true;
col.method = "OnCol";
col.label = prop.display_name;
col.justify = "right";
col.autogroup = true;
col.autorefresh = 1;
col.userdata = prop.pkey;
col.type = "double";
}
}
function OnCol(scriptColData)
{
try
{
var fileItem = scriptColData.item;
var width;
var height;
var triedWidth = false;
var triedHeight = false;
for (var e = new Enumerator(scriptColData.columns); !e.atEnd(); e.moveNext())
{
var colName = e.item();
var colData = scriptColData.columns(colName);
if (colName == "Definition" || colName == "Dimensions")
{
if (!triedHeight)
{
height = fileItem.shellprop(colData.userdata(0));
triedHeight = true;
}
if (!triedWidth)
{
width = fileItem.shellprop(colData.userdata(1));
triedWidth = true;
}
if (typeof(height) == "number" && typeof(width) == "number")
{
var definition;
// If you add or modify definitions, search for
// "grouporder" above and update the orderings as well.
if (width >= 7680 || height >= 4320)
{
definition = "8K";
}
else if (width >= 3840 || height >= 2160)
{
definition = "4K";
}
else if (width >= 2560 || height >= 1440)
{
definition = "Quad HD";
}
else if (width >= 1920 || height >= 1080)
{
definition = "Full HD";
}
else if (width >= 1280 || height >= 720)
{
definition = "HD Ready";
}
else if (width >= 640 || height >= 480)
{
definition = "DVD";
}
else
{
definition = "Low"
}
if (colName == "Definition")
{
colData.value = definition;
colData.group = definition;
}
else
{
colData.value = width + " x " + height;
colData.sort = DOpus.Create.Vector(width, height);
colData.group = definition;
}
}
else
{
colData.value = ""; // Ensure we set a value so we don't get asked again for this column.
}
}
else
{
if (colName == "FrameHeight")
{
if (!triedHeight)
{
height = fileItem.shellprop(colData.userdata);
triedHeight = true;
}
colData.value = height;
}
else if (colName == "FrameWidth")
{
if (!triedWidth)
{
width = fileItem.shellprop(colData.userdata)
triedWidth = true;
}
colData.value = width;
}
else
{
colData.value = fileItem.shellprop(colData.userdata);
}
if (typeof(colData.value) == "number")
{
if (colName == "FrameRate")
{
colData.value = (colData.value /= 1000).toFixed(2);
}
else if (colName == "Length")
{
var seconds = colData.value / 10000000;
colData.sort = seconds;
var hours = Math.floor(seconds / 3600);
seconds %= 3600;
var minutes = Math.floor(seconds / 60);
seconds = Math.floor(seconds%60);
colData.value = hours + ":" + ZeroPad(minutes,2) + ":" + ZeroPad(seconds,2);
}
else if (colName == "LengthRelative")
{
colData.value /= 10000000;
}
}
else
{
colData.value = ""; // Ensure we set a value so we don't get asked again for this column.
}
}
}
}
catch (e)
{
scriptColData.value = "<Error>";
return;
}
}
function ZeroPad(n, digits)
{
var s = n + "";
while (s.length < digits)
{
s = "0" + s;
}
return s;
}