Video Calculator

Discuss and share scripts and script files...
Post Reply
Muroph
Posts: 561
Joined: 21 Aug 2007 16:13

Video Calculator

Post by Muroph »

A bit of background info:
I do a lot of video conversions, and often i need to calculate the parameters (bitrate, resolution, etc) for these conversions.
However, even after hours of hard work, I couldn't find an all-in-one tool to do it for me.
So I decided to write my own using a familiar language, xy script.
This was intended to be a simple script for my personal use only, but it's been so useful to me that i decided to share it.

Video Calculator v6

This script used to be a simple bitrate calculator, but it got a lot more features over time.

What it can do:
-Calculate video duration, bitrate or size.
-Calculate new resolution based on current or specified aspect ratio (current AR calculated from original resolution).
-Calculate image aspect ratio (you can even give a name to them).
Since v2:
-Remember last input.
Since v3:
-Round resolution to closest multiple of "x". If "x" is not specified, use (configurable) default value.

Changes in v6:
-Small changes to the input syntax.
-Rewriten to make use of "if" and "while" blocks.

Simply run the script, fill the parameters for the desired operation and hit enter.
And make sure you don't use any ridiculous values.
If you need help, just post your problem here.

It's kinda big, but I won't post it as a file attachment.

Code: Select all

// Video Calculator v6
//
//     Settings
//   $sep
// set the separator between parameters.
// never use comma(s), slash(es), or a single dot.
// changing the separator *might* break the script.
// the only way to know is testing.
// default = "-"
//
//   $delta
// this is used to compare the calculated aspect ratio with those in the $ratios list.
// a match will happen if the difference betwen the calculated ratio and the named ratio is smaller than $delta.
// lower values give more precision, but if it's too low the script will probably never match anything.
// higher values will match more often, but they are more likely to match the wrong name.
// i'm still testing to see what is the best value for this setting.
// for now i'll leave the default at "0.03" (it's enough to separate 3:2 from 14:9).
// 
//   $ratios
//   $names
// comma-separated list of aspect ratios and their names.
// put the ratio in the $ratio list and the name you want for it in the $names list.
// the ratio and it's name must be in the same position in the list.
// if there are 2 or more succesful matches, the one closest to the end of the list will overwrite the others.
// the default lists match some common aspect ratios.
//
//   $temppath
// path used to store variables.
//
//   $defresdiv
// set the default divisor for output resolution.
// any calculated resolution will be rounded to the closest multiple of this value.
// unless, of course, you specify otherwise in the input dialog.
// the default value is "1" (calculated resolution is not changed).
//
"Video Calculator"
  global $input,$sep,$delta,$ratios,$names,$defresdiv;
  //the settings
  $sep = "-";
  $delta = "0.03";
  $ratios = "1.33,1.50,1.56,1.66,1.78";
  $names = "4:3,3:2,14:9,5:3,16:9";
  $temppath = "%temp%";
  $defresdiv = 16;
  //script start
  getkey $lastinput, lastinput, general, "$temppath\videocalc.tmp";
  $tips=<<<TIPS
Use * to select the output (only one!)

Duration, Bitrate or Size:
<hh,nn,ss>$sep<kbps>$sep<MB>
Note: "hh," or "hh,nn," are optional

Resize using current aspect ratio:
<orig_width>,<orig_height>$sep<new_width>,<new_height>[,<divisor>]
Use * only on <new_width> or <new_height>

Change/calculate aspect ratio:
<width>,<height>[,<divisor>]$sep<ratio>
Enter <ratio> as a decimal or a proportion (e.g. 1.33 == 4/3)
TIPS;
  $input = input("Video Calculator", "$tips", $lastinput, s);
  setkey $input, lastinput, general, "$temppath\videocalc.tmp";
  replace $input, $input, " ", ""; //remove spaces
  $test = gettoken($input, 3, "$sep"); //find type of operation
  sub ($test)?(_dbs):(_res);

"_dbs" //get duration, bitrate and size from input, then see which one we have to calculate
  global $input,$dur,$bit,$size,$sep;
  $dur = gettoken($input, 1, "$sep");
  $bit = gettoken($input, 2, "$sep");
  $size = gettoken($input, 3, "$sep");
  if("$dur"=="*"){sub _duration;}
  elseif("$bit"=="*"){sub _bitrate;}
  elseif("$size"=="*"){sub _size;}
  else{sub _invalid;}

"_res" //get resolutions, divisor and aspect ratio, then decide what to calculate
  global $input,$origw,$origh,$neww,$newh,$ar,$sep,$resdiv,$defresdiv;
  $original = gettoken($input, 1, "$sep");
  $new = gettoken($input, 2, "$sep");
  $origw = gettoken($original,1,",");
  $origh = gettoken($original,2,",");
  $resdiv = gettoken($original,3,",");
  $neww = gettoken($new,1,",");
  $newh = gettoken($new,2,",");
  $resdiv = ($resdiv)?($resdiv):(gettoken($new,3,","));
  $resdiv=($resdiv)?($resdiv):($defresdiv);
  $ar = eval($new);
  if("$new"=="*"){sub _ar;}
  elseif("$newh"=="*"){sub _newheight;}
  elseif("$origw"=="*"){sub _arwidth;}
  elseif("$origh"=="*"){sub _arheight;}
  elseif("$neww"=="*"){sub _newwidth;}
  else{sub _invalid;}
  //sub ("$new"=="*")?(_ar):(("$newh"=="*")?(_newheight):(("$origw"=="*")?(_arwidth):(("$origh"=="*")?(_arheight):(("$neww"=="*")?(_newwidth):(_invalid)))));

"_duration" //calculate clip duration for given bitrate and file size
  global $bit,$size,$round;
  $sec = ($size*8192/$bit);//calculate total seconds
  $min = ($sec/60);//minutes
  $hrs = ($min/60);//and hours
  $round = "$sec,3"; sub _round; $sec=$round;
  $min = gettoken("$min.", 1, ","); //discard redundant time
  $hrs = gettoken("$hrs.", 1, ",");
  $sec2 = ($sec-$min*60);
  $round = "$sec2,3"; sub _round; $sec2 = $round;
  $min = ($min-$hrs*60);
  strlen $test, $sec2; //fix leading zeros
  $sec2 = ($test==1)?(0.$sec2):($sec2);
  strlen $test, $min;
  $min = ($test==1)?(0.$min):($min);
  input("Clip duration in hrs:min:sec (Click OK to see total seconds)", ,"$hrs:$min:$sec2");
  input("Clip duration in seconds", ,"$sec"); //done!

"_getduration" //calculate total of seconds based on duration input
  global $dur,$total;
  $thrs = gettoken($dur, 1, ",");
  $tmin = gettoken($dur, 2, ",");
  $tsec = gettoken($dur, 3, ",");
  if($tmin==""){ //fix if "hh.nn" wasn't entered
	$tsec = $thrs;
	$tmin = 0;
	$thrs = 0;}
  elseif($tsec==""){ //fix if "hh" wasn't entered
	$tsec = $tmin;
	$tmin = $thrs;
	$thrs = 0;}
  $total = ($tsec+60*$tmin+3600*$thrs); //total seconds

"_bitrate" //calculate bitrate based on duration and file size
  global $size,$total,$round;
  sub _getduration;
  $bitrate = ($size*8192/$total); //this will also round down the result
  $round = "$bitrate,0"; sub _round; $bitrate = $round; //this will also round the result
  input("Clip bitrate in Kbps", ,"$bitrate"); //done!

"_size" //calculate file size based on duration and bitrate
  global $bit,$total,$round;
  sub _getduration;
  $size = ($bit*$total/8192);
  $round = "$size,2"; sub _round; $size = $round; //leave only two decimals
  input("File size in MB", ,"$size"); //done!
  
"_newwidth" //calculate new width for desired height, using current aspect ratio
  global $origw,$origh,$neww,$newh,$ar,$round,$resdiv,$newheight,$newwidth;
  $newwidth = ($origw/$origh*$newh);
  $newheight = $newh;
  if($resdiv>1){sub _resdiv;}
  //sub ($resdiv>1)?(_resdiv):(_nothing);
  $round = "$newwidth,0"; sub _round; $newwidth = $round;
  input("New clip resolution  (width,height)", ,"$newwidth,$newheight"); //done!

"_newheight" //vice-versa, again using the current aspect ratio
  global $origw,$origh,$neww,$newh,$round,$resdiv,$newheight,$newwidth;
  $newheight = ($origh/$origw*$neww);
  $newwidth = $neww;
  if($resdiv>1){sub _resdiv;}
  //sub ($resdiv>1)?(_resdiv):(_nothing);
  $round = "$newheight,0"; sub _round; $newheight = $round;
  input("New clip resolution (width,height)", ,"$newwidth,$newheight"); //done!

"_arwidth" //calculate width using specified aspect ratio
  global $origh,$ar,$round,$resdiv,$newheight,$newwidth;
  $newwidth = ($ar*$origh);
  $newheight = $origh;
  if($resdiv>1){sub _resdiv;}
  //sub ($resdiv>1)?(_resdiv):(_nothing);
  $round = "$newwidth,0"; sub _round; $newwidth = $round;
  input("New clip resolution (width,height)", ,"$newwidth,$newheight"); //done! 

"_arheight" //calculate height using specified aspect ratio
  global $origw,$ar,$round,$resdiv,$newheight,$newwidth;
  $newheight = (1/$ar*$origw);
  $newwidth = $origw;
  if($resdiv>1){sub _resdiv;}
  //sub ($resdiv>1)?(_resdiv):(_nothing);
  $round = "$newheight,0"; sub _round; $newheight = $round;
  input("New clip resolution (width,height)", ,"$newwidth,$newheight"); //done! 

"_ar" //calculate aspect ratio of given resolution
  global $origw,$origh,$ar,$modar,$delta,$names,$maxcount,$round;
  $ar = ($origw/$origh); //calculate ratio
  regexreplace $test, $names, "[^,]", ""; //start comparison loop
  strlen $maxcount, $test;
  $count = 0;
  while($count<=$maxcount){
	$workar = gettoken("$ratios", ($count+1),","); //get current name and ratio from the list
	$workname = gettoken("$names", ($count+1),",");
	$modar = (((-$delta<($ar-$workar))==(($ar-$workar)<$delta))==1)?($workname):($modar);  //compare with calculated aspect ratio using $delta
	$count++;}
  $round = "$ar,2"; sub _round; $ar = $round; //leave only two decimals
  input(($modar)?("Aspect ratio matched $modar"):("Aspect ratio is:"), ,"$ar:1"); //done!

"_resdiv"
  global $resdiv,$newwidth,$newheight,$round;
  $round=($newwidth/$resdiv).",0"; sub _round;
  $newwidth=($round*$resdiv);
  $round=($newheight/$resdiv).",0"; sub _round;
  $newheight=($round*$resdiv);

"_round" //global $round; $round="<value_or_variable_to_round>,<output_decimal_places>"; sub _round; <output_variable>=$round;
  global $round;
  $roundval = gettoken($round,1,","); //get parameters
  $roundto = gettoken($round,2,",");
  $roundint = gettoken($roundval,1,"."); //separate decimal part
  $rounddec = gettoken($roundval,2,".");
  if($roundto>0){
	substr $outdec, $rounddec,,$roundto; //separate removed decimals
	substr $remdec, $rounddec, $roundto;
	if("0.$remdec">"0.5"){ //test to round down the decimals
		incr $outdec;}
	elseif("0.$remdec"=="0.5"){
		$outdec = (gettoken(($outdec/2),2, "."))?($outdec+1):($outdec);}
	strlen $countdec, $outdec; //fix trailing zeroes
	$outdec = "$outdec".strrepeat("0",($roundto-$countdec));}
  elseif($roundto==0){
	if("0.$rounddec">"0.5"){ //test to round down the decimals
		incr $roundint;}
	elseif("0.$$rounddec"=="0.5"){
		$roundint = (gettoken(($roundint/2),2, "."))?($roundint+1):($roundint);}}
  $round = "$roundint".($roundto>0)?(".$outdec"):(""); //output to $round

"_invalid"
  msg "Invalid input parameters";

//"_nothing"
Last edited by Muroph on 09 Jun 2009 04:16, edited 5 times in total.
My shared scripts:
TeraCopy Integration, Tag Manager, Comments Menu, Text Replacer, Image and Media Tools, Checksum Calculator, Video Calculator
only 5 URLs are allowed on the sig...

Muroph
Posts: 561
Joined: 21 Aug 2007 16:13

Re: Video Calculator

Post by Muroph »

Updated to v2:

-Fixed a bug.
-Remember last input used.
-New sub-script to round numbers. Follows math conventions (at least those i could remember).
My shared scripts:
TeraCopy Integration, Tag Manager, Comments Menu, Text Replacer, Image and Media Tools, Checksum Calculator, Video Calculator
only 5 URLs are allowed on the sig...

admin
Site Admin
Posts: 66075
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Video Calculator

Post by admin »

Wow, again and again I'm surprised what you folks do with xy scripting. Some of you are really into it. I'd like to know: Is there any particular thing you miss in scripting, something that would make your scripting life much easier?

Muroph
Posts: 561
Joined: 21 Aug 2007 16:13

Re: Video Calculator

Post by Muroph »

Another update.
This time to v3.

-Round resolution to closest multiple of "x". If "x" is not specified, use (configurable) default value.
Sometimes I have to round the resolution to a certain divisor in order to use an image filter.
Now i don't have to do it by hand.

I don't have any other (useful) ideas for a v4. Yet. :)

admin wrote:Wow, again and again I'm surprised what you folks do with xy scripting. Some of you are really into it. I'd like to know: Is there any particular thing you miss in scripting, something that would make your scripting life much easier?
hmm...
maybe having a few more commands converted to functions.
this way we could put them directly inside other commands/functions/comparisons and discard lots of temp variables.
however, this would mean having to review and rewrite many scripts :| .
My shared scripts:
TeraCopy Integration, Tag Manager, Comments Menu, Text Replacer, Image and Media Tools, Checksum Calculator, Video Calculator
only 5 URLs are allowed on the sig...

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Video Calculator

Post by TheQwerty »

admin wrote:Wow, again and again I'm surprised what you folks do with xy scripting. Some of you are really into it. I'd like to know: Is there any particular thing you miss in scripting, something that would make your scripting life much easier?
1) Loops. Recursion is sloppy and prone to stack overflows.
2) Real logic blocks. Having to sub out everything can be painful, and often requires a lot of unnecessary use of globals.
3) Ability to retrieve current state of XY's config. (For instance I want to detect if the catalog or tree is visible, the only way to do so is Save the configuration and then read it).
4) User functions. With globals you can get by but it would be nice to have actual user functions.
5) A lot more commands / functions to control XY (open/rename/lock/home/iconify tabs,
6) Ability to easily create submenus, so that they actually show as submenus, open in the appropriate place, don't chase the cursor around (I prefer they open at my cursor to the left corner), and can be easily closed to return to the main menu.

Should I keep going? :P

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Video Calculator

Post by jacky »

Yep, conditions, loops, user functions and arrays are probably on top of my list as well.

Of course, things like onEvent actions or even improvements to existing functions could be great, too -- e.g. report() to support an extra optional param for items list...
Proud XYplorer Fanatic

admin
Site Admin
Posts: 66075
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Video Calculator

Post by admin »

TheQwerty wrote:
admin wrote:Wow, again and again I'm surprised what you folks do with xy scripting. Some of you are really into it. I'd like to know: Is there any particular thing you miss in scripting, something that would make your scripting life much easier?
1) Loops. Recursion is sloppy and prone to stack overflows.
2) Real logic blocks. Having to sub out everything can be painful, and often requires a lot of unnecessary use of globals.
3) Ability to retrieve current state of XY's config. (For instance I want to detect if the catalog or tree is visible, the only way to do so is Save the configuration and then read it).
4) User functions. With globals you can get by but it would be nice to have actual user functions.
5) A lot more commands / functions to control XY (open/rename/lock/home/iconify tabs,
6) Ability to easily create submenus, so that they actually show as submenus, open in the appropriate place, don't chase the cursor around (I prefer they open at my cursor to the left corner), and can be easily closed to return to the main menu.

Should I keep going? :P
Ah yes, this is was I expected to hear. :) I just was wondering how it's possible that folks write so large and involved scripts without screaming for loops and logic blocks.

fishgod
Posts: 231
Joined: 03 Feb 2008 00:40
Location: Sankt Augustin (near Bonn), Germany

Re: Video Calculator

Post by fishgod »

admin wrote:Ah yes, this is was I expected to hear. :) I just was wondering how it's possible that folks write so large and involved scripts without screaming for loops and logic blocks.
I tried to be more constructive in this forum instead of screaming for features while you where absent :D.
Its also possible to convert everly loop and logical block to recursions and xy-syntax :)

But hell yeah, loops and logical block would be another milestone in scripting.
Operating System: Win10 x64 / Win11 x64 / almost allways newest XY-beta
totally XYscripting-addicted

serendipity
Posts: 3360
Joined: 07 May 2007 18:14
Location: NJ/NY

Re: Video Calculator

Post by serendipity »

OK, apart from what TheQwerty mentioned which is a bigger part of scripting I have some smaller requests for current commands/functions:
1) getinfo can show get more infos like extended info of special files like images, audios and videos. (Any reason why extended info in menu File>To clipboard is less detailed than the one in preview mode?)
Also getinfo could give number of items in the current list and position of current intem in the list.
2) replace could support wildcards and inversions.

Will think of more :idea:

admin
Site Admin
Posts: 66075
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Video Calculator

Post by admin »

serendipity wrote:Will think of more :idea:
Thanks, but I'm not out of ideas. My lists are full. I just asked that question because I was surprised about what people can do without logic blocks and loops. I personally would not do scripts > 20 lines without those syntax features... :wink: Especially using recursions as a replacement for loops gives me pains. :mrgreen:

jacky
XYwiki Master
Posts: 3106
Joined: 23 Aug 2005 22:25
Location: France
Contact:

Re: Video Calculator

Post by jacky »

admin wrote:I personally would not do scripts > 20 lines without those syntax features... :wink: Especially using recursions as a replacement for loops gives me pains. :mrgreen:
Yeah, but if such a script filled with bad recursions works fine & saves you 15 minutes a day, I can use those 15 minutes to relax & work on such pains, waiting for the next version of script engine... ;) 8)
Proud XYplorer Fanatic

admin
Site Admin
Posts: 66075
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Video Calculator

Post by admin »

serendipity wrote:Any reason why extended info in menu File>To clipboard is less detailed than the one in preview mode?
Historical reason, aka "It's always been like that." :)

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Video Calculator

Post by TheQwerty »

jacky wrote:Of course, things like onEvent actions
Oh yes, I completely forgot about oEA!
admin wrote:Ah yes, this is was I expected to hear. :) I just was wondering how it's possible that folks write so large and involved scripts without screaming for loops and logic blocks.
You've given us enough tools to get by sufficiently, and really it's not too terribly painful once you adjust. However, each time I script around the lack of loops and logic blocks, I do indeed curse you. :P I know it's on your list though, and will eventually happen, so there's no point pestering.

admin
Site Admin
Posts: 66075
Joined: 22 May 2004 16:48
Location: Win8.1, Win10, Win11, all @100%
Contact:

Re: Video Calculator

Post by admin »

TheQwerty wrote:You've given us enough tools to get by sufficiently, and really it's not too terribly painful once you adjust. However, each time I script around the lack of loops and logic blocks, I do indeed curse you. :P I know it's on your list though, and will eventually happen, so there's no point pestering.
I hope the cursing reduces a bit from v7.90.0145 onwards... :wink:

Post Reply