Jump to content



Photo

Batch file to run command on joining video files?


  • Please log in to reply
24 replies to this topic

#1 nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 17:11

I have a lot of movies that are 2 files and I want to join them into one file using Avidemux. Right now I've written a batch script to make it a little faster to join the 2 files like I put below. I have to update the "moviefinal" value, save the files, then run it. I have to do this each time with each movie though.


---------------------------
set avidexmuxprog="C:\Programs\avidemux\avidemux.exe"

set moviefinal=The 40 Year Old Virgin

set moviefile1=%moviefinal% - CD1
set moviefile2=%moviefinal% - CD2

%avidexmuxprog% --load "T:\Video\Movies\%moviefile1%.avi" --append "T:\Video\Movies\%moviefile2%.avi" --force-smart --save "C:\_COMBINED_AVI\%moviefinal%.avi" --quit

:end
---------------------------


I've tried putting this into a "for" loop, but the (set) doesn't like spaces in the names and using quotes messes it up too.



---------------------------
set avidexmuxprog="C:\Programs\avidemux\avidemux.exe"

set movie1="The Figher"
set movie2="The Fifth Element"

FOR /f "delims=," %%G IN (%movie1%,%movie2%) DO (%avidexmuxprog% --load "c:\test\%%G - CD1.avi" --append "c:\test\%%G - CD2.avi" --force-smart --save "c:\test\final\%%G.avi" --quit)

:end
---------------------------

Is there a way, in batch to have it automatically detect a file with the same name, but with the CD1/CD2 and then run the command for each file set that it finds in a directory?

I'm not too advanced in batch, but hoping there's a way to automate the entire process so I don't have to keep manually typing in the name.


#2 LUTZIFER

LUTZIFER

    Resident Evil

  • Joined: 09-January 02
  • Location: Vancouver Island, BC CANADA
  • OS: Windows 8.1 Pro
  • Phone: Google Nexus 4

Posted 30 December 2012 - 17:15

I use a program called... Ultra Video Joiner. Almost use it at least once a day, for years.
Works awesome and joins even big or multiple files super fast.
Couldn't do without it.

#3 OP nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 17:25

I looked into that program and it doesn't provide any better options than that of Avidemux. I still have to manually join the files.

I have about 100 or more movies that are (movie-Cd1.avi and movie-Cd2.avi) and want to join them into one file. Avidemux works very well, but have to manually choose 2 files to join, then rinse and repeat 100+ times.

#4 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 December 2012 - 17:58

While it is certainly possible to do what you want in Batch, its really a pain. I recommend that you use a more suitable scripting language, of which there are many.

For example, I wrote a new version of your script in Perl that does what you requested. It is much nicer than its equivalent in Batch, and took me only a couple of minutes to write and test. All you should need to do is modify the @MOVIES_TO_CONVERT variable to list the movies you need to convert. Also, you can download ActivePerl for Windows if you don't already have Perl installed on your system.

#!/usr/bin/perl

use strict;

# Array of movies to convert
my @MOVIES_TO_CONVERT = ('The Figher', 'The Fifth Element', 'Robinhood Men In Tights');

# Directory where the split AVI files are stored
my $MOVIE_IN_PATH = 'T:\Video\Movies';

# Directory where the combined AVI files will be stored
my $MOVIE_OUT_PATH = 'C:\_COMBINED_AVI';

# Full path to the avidemux executable
my $AVIDEMUX = 'C:\Programs\avidemux\avidemux.exe';

for my $movie (@MOVIES_TO_CONVERT)
{
	my $convert_cmd = "\"$AVIDEMUX\" --load \"$MOVIE_IN_PATH\\$movie - CD1.avi\" --append \"$MOVIE_IN_PATH\\$movie - CD2.avi\" --force-smart --save \"$MOVIE_OUT_PATH\\$movie.avi\" --quit";
	print "$convert_cmd\n";
	die "Unable to convert $movie!\n" if (system "$convert_cmd");
}

If you save the script as avijoin.pl, or something else with the .pl file extension, ActivePerl should let you double-click to run it.

#5 OP nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 18:09

That's awesome orangekiller. I've always wanted to mess with perl more and played with it a little in Debian before. This also gives me good examples to learn from. I'll get Active Perl and try it out since I'm in Windows.

#6 OP nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 18:19

Another question for you Orange, what would this look like as a VBS script? Do you know VBS? Just looking for something else to learn from since I'm in a Windows environment and wanted to start messing with VBS instead of batch. I learn best from understand code in scripts that I'm actually trying to use in real life instead of a test book.

I'm installing ActivePerl now and trying out that script on 2 movies.

#7 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 December 2012 - 18:54

Another question for you Orange, what would this look like as a VBS script? Do you know VBS? Just looking for something else to learn from since I'm in a Windows environment and wanted to start messing with VBS instead of batch. I learn best from understand code in scripts that I'm actually trying to use in real life instead of a test book.

I'm installing ActivePerl now and trying out that script on 2 movies.


Personally I prefer Perl because of its easy syntax and excellent cross-platform support. While I do know a little VBS, I generally try to avoid it. The best Windows-specific scripting language is AutoIt, in my opinion. It has excellent documentation, a great community, a featureful standard library, built-in WIN32 API integration, and any AutoIt script may be "compiled" to an executable so that it can be run on systems that don't have AutoIt installed.

If you are just getting started with these languages, I have a couple of book recommendations for you. Learning To Script with AutoIt V3 is an excellent AutoIt tutorial, probably the best available. Whether you are a novice or expert, that is the tutorial to read when you are first starting with AutoIt. If you are fairly new to programming in general, not just learning a new language, I definitely recommend that you read Beginning Perl. It is an excellent introduction to programming, and covers programming basics, good practices, and the Perl language all-in-one. (Disclosure: Since I am a competent C/C++ developer, I only skimmed the book, but read Perl for C Programmers when I learned Perl.)

#8 LUTZIFER

LUTZIFER

    Resident Evil

  • Joined: 09-January 02
  • Location: Vancouver Island, BC CANADA
  • OS: Windows 8.1 Pro
  • Phone: Google Nexus 4

Posted 30 December 2012 - 19:21

I looked into that program and it doesn't provide any better options than that of Avidemux. I still have to manually join the files.

I have about 100 or more movies that are (movie-Cd1.avi and movie-Cd2.avi) and want to join them into one file. Avidemux works very well, but have to manually choose 2 files to join, then rinse and repeat 100+ times.

Ohhh, yeah I see what you mean. That would take awhile alright.
Years ago before I found out about Ultra Video Joiner, I just never downloaded anything that was in more than one part, meaning I didn't get the best quality files.
After I got the program, I downloaded everything and joined them right away. Most were 2 parts, but some 3 and 4. Mostly porn to be honest, lol. : )

#9 OP nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 19:27

I should have joined these files a long time ago. Was lazy because XBMC detects them and plays 2 files together just fine as long as they are like CD1 and CD2 and so on.

Wanted to get more extensive and use a new media manager and looks like I have to change how I format all my movies, but combining them and putting each movie into a sub folder. The media program does this all for me, but doesn't like more than one file for a movie. Was using Ember Media Manager-R, but now going full blown with Media Center Master since EMM/EMM-R isn't being updated really anymore. After playing with Media Center Master, it just seems like a smarter move anyways.

Funny how things work, been trying to do this script and now playing with perl and in the past hour I've been playing with PowerShell which is way cooler than I thought it was at first and found out it's replacing VBS pretty much.

I'm going to play with AutoIT more also. Thanks again Orange.

#10 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 December 2012 - 20:11

I improved the Perl script I posted above. This version is capable of detecting unconverted movies in the input directory and joining them automatically. If you still want to manually control which movies get converted, you can assign their names to the @MOVIES_TO_CONVERT array like before, and the script will use those instead of auto-detection. (Remove the '; #' after the @MOVIES_TO_CONVERT and use the comment as reference if you want manual control.)

#!/usr/bin/perl

use strict;

########################################################################
#						 Configuration Details						#
########################################################################

# Array of movies to convert
my @MOVIES_TO_CONVERT; # = ('The Figher', 'The Fifth Element');

# Directory where the split AVI files are stored
my $MOVIE_IN_PATH = 'T:\Video\Movies';

# Directory where the combined AVI files will be stored
my $MOVIE_OUT_PATH = 'C:\_COMBINED_AVI';

# Full path to the avidemux executable
my $AVIDEMUX = 'C:\Programs\avidemux\avidemux.exe';

########################################################################
#							   Functions							  #
########################################################################

# Return an array of all the AVI files in the specified directory.
sub get_avis_in_directory
{
	my $dh; # Directory handle
	my $dir; # Current directory
	my @avis; # Array of file names to return

	opendir ($dh, $dir = shift) or die "Failed to open directory $dir: $!\n";
	while (readdir $dh)
	{
		next if (/^\.{1,2}/);
		$_ = $dir . "\\" . $_;
		push (@avis, $_) if (-f $_ and /.*\.avi$/i);
	}
	closedir $dh;

	return (@avis);
}

########################################################################
#							  Entry Point							 #
########################################################################

die "Input directory $MOVIE_IN_PATH does not exist!\n" unless (-d $MOVIE_IN_PATH);
die "Output directory $MOVIE_OUT_PATH does not exist!\n" unless (-d $MOVIE_OUT_PATH);

# This variable represents the actual names and paths of movies to be converted.
# It will either be built from the files specified in @MOVIES_TO_CONVERT manually, or
# built dynamically based on the files in the source and destination paths.
my @movies_formatted; # Array of hashes of movies to convert

if ($#MOVIES_TO_CONVERT == -1)
{
	my @in_avis; # Array of AVI files in the input directory
	my @out_avis; # Array of AVI files in the ouput directory

	@in_avis = get_avis_in_directory ($MOVIE_IN_PATH);
	@out_avis = get_avis_in_directory ($MOVIE_OUT_PATH);

	for my $in_avi (@in_avis)
	{
		if ($in_avi =~ /.*-[ ]*CD[ ]*1\.avi$/i)
		{
			my $rec; # Temporary hash variable
			my $name; # Name of the move we are processing
			$name = (split (/[ ]*-[ ]*CD[ ]*1/i, $in_avi))[0];
			$name = (split (/$MOVIE_IN_PATH[\\\/]{1}/i, $name))[1];

			for my $in_avi_2 (@in_avis)
			{
				if ($in_avi_2 =~ /^$MOVIE_IN_PATH\\$name[ ]*-[ ]*CD[ ]*2\.avi$/i)
				{
					$rec->{'part2'} = $in_avi_2;
					last;
				}
			}

			if (defined $rec->{'part2'})
			{
				for my $out_avi (@out_avis)
				{
					if ($out_avi =~ /$name\.avi$/i)
					{
						$rec->{'output'} = $out_avi;
						last;
					}
				}

				unless (defined $rec->{'output'})
				{
					$rec->{'part1'} = $in_avi;
					$rec->{'output'} = "$MOVIE_OUT_PATH\\$name.avi";
					push (@movies_formatted, $rec);
				}
			}
		}
	}
}
else
{
	my $rec; # Temporary hash variable

	for my $name (@MOVIES_TO_CONVERT)
	{
		$rec = {};
		$rec->{'part1'} = "$MOVIE_IN_PATH\\$name - CD1.avi";
		$rec->{'part2'} = "$MOVIE_IN_PATH\\$name - CD2.avi";
		$rec->{'output'} = "$MOVIE_OUT_PATH\\$name.avi";
		push (@movies_formatted, $rec);
	}
}

for my $movie (@movies_formatted)
{
	my $convert_cmd = "\"$AVIDEMUX\" --load \"" . $movie->{'part1'} . "\" --append \"" . $movie->{'part2'} . "\" --force-smart --save \"" . $movie->{'output'} . "\" --quit";
	print "$convert_cmd\n";
	die "Unable to convert $movie!\n" if (system "$convert_cmd");
}

Edit: If you copy/paste the code into a descent text editor with a monospaced font, such as Notepad++, it should look nicer.

#11 xendrome

xendrome

    In God We Trust; All Others We Monitor

  • Tech Issues Solved: 9
  • Joined: 05-December 01
  • OS: Windows 8.1 Pro x64

Posted 30 December 2012 - 20:14

Freemake Video Converter will also join videos and it's easy/free

#12 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 December 2012 - 20:29

Funny how things work, been trying to do this script and now playing with perl and in the past hour I've been playing with PowerShell which is way cooler than I thought it was at first and found out it's replacing VBS pretty much.

I'm going to play with AutoIT more also. Thanks again Orange.


I agree that PowerShell is really neat. Its definitely an improvement over both Batch and VBS, but it still pales in comparison to BASH in my opinion. I definitely have to give Microsoft credit for getting it so close to right. PowerShell is the most usable shell/scripting language I have used that Microsoft produced. If you are interested in learning more about it, I definitely recommend the book Windows PowerShell in Action. It was authored by one of the PowerShell core developers and explains the influences and reasoning behind many of their design choices. Not only does it teach PowerShell well, but it helped me to understand the PowerShell mentality more than any of the other PowerShell resources I read.

When it comes to AutoIt, on the one hand I almost wish Microsoft would officially adopt it as their VBS replacement, and on the other hand I'm glad they haven't. AutoIt feels very much like a VBS replacement. Its syntax is similar, yet the language is more powerful. It is simple to use and integrates with Windows very well. It smoothed the rough spots of VBS while polishing what made it great. All-around I think its an excellent language/platform. Although AutoIt would certainly get more support if Microsoft officially adopted it, I'm afraid that Microsoft would kill it. They have a nasty habit of promoting some new language or technology as the-best-thing-since-sliced-bread one year, then abandoning it never-to-be-mentioned-again the next. Therefore, while its not Microsoft's blessed scripting language for Windows, AutoIt is probably safer and more stable that way. I highly recommend it.

#13 OP nicedreams

nicedreams

    Solstis Solutions

  • Joined: 02-November 01
  • Location: Arizona, USA

Posted 30 December 2012 - 20:54

Thanks again for the info. While looking at your perl code, it kind of helped me understand using batch a little more.

I took my original batch code with the FOR loop and put the names of the movies that are 2 files in a separate text file.
FOR /f "delims=|" %%G IN (filelist.txt) DO (%avidexmuxprog% --load "c:\test\%%G - CD1.avi" --append "c:\test\%%G - CD2.avi" --force-smart --save "c:\test\final\%%G.avi" --quit)

It's working so far, but have to manually enter all names. I haven't tested, but wondering if using | instead of , is why it's working now regardless of delims=, like I had before to separate the names.

I'm looking at that new perl script that is more automated and playing with that too. Learning so much and it's fun. lol
Even though now I have many options of getting this done, I'm trying to make the perl, batch, and powershell work for the hell of it.

#14 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 December 2012 - 21:04

I'm looking at that new perl script that is more automated and playing with that too. Learning so much and it's fun. lol
Even though now I have many options of getting this done, I'm trying to make the perl, batch, and powershell work for the hell of it.


I'm glad that I was able to help. Automating the same task in different languages is an excellent way to learn the syntax, strengths, and weaknesses of each. The same basic algorithm that I used in the latter Perl script shouldn't be too difficult to implement in PowerShell. (Technically, you could try it in Batch too, but I'm not enough of a masochist to advocate that.)

#15 hshah

hshah

    Neowinian

  • Joined: 12-January 13

Posted 12 January 2013 - 22:43

xorangekiller - I installed ActivePerl and set the file paths of the source, destination and Avidemux but when I run the films.pl file (where I have copied your script) a command window flashes up and ends up doing nothing :(

If it helps, I wrote a small hello word script (with the help of Google) and that outputs fine to the command line.

/Edit: On purpose I entered an invalid source and destination path and that does give me the following errors:

Input directory T:\Video\Movies does not exist!
Output directory C:\_COMBINED_AVI does not exist!

But as soon as they are right, the script does nothing:
C:\>perl films.pl

C:\>




Click here to login or here to register to remove this ad, it's free!