Video length, dimensions, framerate, definition columns

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

200dpi_wc10903_dopus

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;
}
8 Likes

Many thanks for this script.

Is it possible to add another column : Definition
If frame width :
480 => DVD
720 => HD Ready
1080 => Full HD
2160 => 4K
4320 => 8K

[Note: A version of this functionality is now built in to the script in the root post.]

The following code has been tested and works

function OnInit(initData)
{
	initData.name = "Video Frame Columns";
	initData.version = "1.1";
	initData.copyright = "(c) 2018 Leo Davidson , updated by vijay saraff";
	initData.url = "https://resource.dopus.com/t/video-width-height-and-framerate-columns/28147";
	initData.desc = "Brings Explorer's Frame Width, Frame Height, and Frame Rate columns into Opus.";
	initData.default_enable = true;
	initData.min_version = "12.7";

	var col;
	var props;

	props = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameHeight", "r");
	if (props.count == 1)
	{
		var prop = props(0);
		col = initData.AddColumn();
		col.name = "FrameHeight";
		col.method = "OnCol";
		col.label = prop.display_name;
		col.justify = "right";
		col.autogroup = true;
		col.userdata = prop.pkey;
		col.type = "number";
	}
	props = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameWidth", "r");
	if (props.count == 1)
	{
		var prop = props(0);
		col = initData.AddColumn();
		col.name = "FrameWidth";
		col.method = "OnCol";
		col.label = prop.display_name;
		col.justify = "right";
		col.autogroup = true;
		col.userdata = prop.pkey;
		col.type = "number";
		//definition column
		col = initData.AddColumn();
		col.name = "Definition";
		col.method = "OnCol";
		col.label = "Definition";
		col.justify = "right";
		col.autogroup = true;
		col.userdata = prop.pkey;
		//col.type - "text";

	}

	props = DOpus.FSUtil.GetShellPropertyList("System.Video.FrameRate", "r");
	if (props.count == 1)
	{
		var prop = props(0);
		col = initData.AddColumn();
		col.name = "FrameRate";
		col.method = "OnCol";
		col.label = prop.display_name;
		col.justify = "right";
		col.autogroup = true;
		col.userdata = prop.pkey;
		col.type = "double";
	}
	
}

function OnCol(scriptColData)
{
	try
	{
		scriptColData.value = scriptColData.item.shellprop(scriptColData.userdata);
		DOpus.Output(scriptColData.col + " raw value:" + scriptColData.value);
		if (scriptColData.col == "FrameRate" && typeof(scriptColData.value) == "number")
		{
			scriptColData.value /= 1000;
		}
		if (scriptColData.col == "Definition" && typeof(scriptColData.value) == "number")
		{
			//DOpus.Output(scriptColData.col + " raw value:" + scriptColData.value);
			if (scriptColData.value >= 3840) {
				scriptColData.value = "4K";
			} else if ( scriptColData.value >= 1920) {
				scriptColData.value = "Full HD";
			} else if ( scriptColData.value >= 720) {
				scriptColData.value = "HD Ready";
			} else if ( scriptColData.value >= 640) {
				scriptColData.value = "DVD";
			} else {
				scriptColData.value = ""
			}		
		}
	}
	catch (e)
	{
		scriptColData.value = "<Error>";
		return;
	}
}
1 Like

Many many thanks for your help

You are welcome! Though you should add 8K to the definition column as well.

Root post updated with v2.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 Like

I can get duration with mkv but not with mp4 or ts. Is there a way to make that happen. Most my files are ts and mp4. I updated to the beta version and under scripts it says ok now. Thanks.

  • Does duration show up for the same files in Explorer?

    If it doesn't work there either then something is wrong with the mp4 codecs/splitters on your system, or there's a problem related to the files themselves (e.g. something is blocking them from being opened, or they're not really mp4 and have the wrong extension).

  • Are you definitely looking at the Duration / Length column which the script provides, and not the one built-in to Opus?

Sorry I made the mistake of not using the correct duration. It works great now.

Thank you for this, it works great.

Sorry if this is a bit unrelated, but is there any way to get the "Video Codec" to work with more file types, or is there another label that's compatible with more file types? Seems like it fails with a lot of containers (.mkv, .mp4, .m4v).

Is there a column in Explorer that shows the information you need for your files? I can add it to the script if there is.

We'll probably also improve the internal Video Codec column in the future, but that'll take longer. Adding more columns to the script can be done very quickly.

1 Like

In Explorer, "Video Compression" almost always returns a value (if not always; a few of my files don't but that could just be my messed up videos). But the values are alphanumeric strings. They might correlate with codecs, I wasn't able to find much documentation at a glance.

@Leo

Could you please add Audio tracks column from Explorer as I cannot figure out how to add it myself

onedot3

Explorer doesn't have an Audio Tracks column here. It must be something added by a third-party component. It should be possible to import it, but I can't tell you the column/property names to use as it doesn't exist here and I don't know where it comes from.

Edit:

Hello,

I keep getting occasional errors with this script:

 13/05/2019 23:54 Video Frame Columns:  Object doesn't support this property or method (0x800a01b6)
 13/05/2019 23:54 Video Frame Columns:  Error at line 259, position 3
 13/05/2019 23:54 Video Frame Columns:  Object doesn't support this property or method (0x800a01b6)
 13/05/2019 23:54 Video Frame Columns:  Error at line 259, position 3

Any ideas why?

No, from a look at that line in the code. Can you give more detail on how to reproduce what you're seeing? Are there particular files, folders or actions that trigger it?

Is it possible to see the total duration of the videos in a folder?

I have several folders with videos inside and I would like to know the total duration of the videos that are inside each folder.

Yes, you can add that to the status bar, under Preferences / Display. It’s included in one of the sample configurations in the menu on the right.

Thanks for the reply, I have tested it and it works correctly.

Is it possible to do this in the column for folders?

Could be done using a separate script column.

I am not sure how performant it would be, though. Extracting video duration is quite slow, and doing it for all files under multiple folders would be very slow. You would probably want some kind of caching system, which a script could do but which is also much more complicated.