Managing a huge collection of digital movie files (avi, mpg, etc.) can be a pain especially if you don’t want the hassle of using a program like iTunes or Windows Media Centre/Player. Here’s a PHP script that will:
- Extract movie titles from the movie file names,
- Attempt to lookup movie information for those movies in the IMDB database, and
- Sort the movies into genre, actor, director, rating, title, and release date folders. (actually links to the movies)
Getting Started
Just to be clear. This process requires that the name of the movie be in the filename somewhere.
Examples that will work:
- The Chronicles of Narnia The Voyage of the Dawn Treader (2010) DVDRip XviD-MAXSPEED www.torentz.3xforum.ro.avi
- The.Social.Network.(2010).BDRip.XviD.AC3.CaLLiOpeD.avi
Examples that won’t work well:
- dvdrip.avi
- 001.mpg
Install PHP
You will need to download and install PHP on your computer to run the script. Here are a few of my notes from installing PHP on my Windows 7 laptop:
- Download the x86 Thread Safe installer from here: http://windows.php.net/download/
- Run the installer
- Accept all defaults but don’t setup any Web Server integration.
Pick Your Movie Folder
Once that is done you will need to identify the main folder on your computer that contains all movie files. (it’s fine if they are in subfolders). In my case all of my movies are on my removable network harddrive: \\MYBOOKLIVE\Public\Shared Videos\MovieFiles
Download PHP Script
Now you need to copy this script and save it to your desktop as sort_files.php
<!--?php </p-->
<?php
// Configuration
// This is the directory where all of the movie files are.
// The "By Genre", "By Year", "By Actor", etc. folders will be
// created at the same level as this folder (side by side)
$movie_dir = '\\\\MYBOOKLIVE\\Public\\Shared Videos\\MovieFiles';
// List of symbols to remove from filenames
$omit_symbols = array(
"$", "&", "(", ")", "-", "[", "]", "."
);
// List of words to remove from filenames
$omit_words = array(
".com", ".net", "2Ch", "3D", "405p", "480P", "480p", "576P", "576p", "AC3", "AC3-5",
"AC3-AMIABLE", "AC3-Arcon", "AC3-CHD", "AC3-CaLLiOpeD", "AC3-CaLLioPE_MoNTEDiaZ", "AC3-DplaneT",
"AC3-ELEKTRI4KA", "AC3-FR", "AC3-IMAGiNE", "AC3-LEGi0N", "AC3-MAGNAT","AC3-MAGNET",
"AC3-MECK90", "AC3-MODULE", "AC3-NYDIC", "AC3-OpeD", "AC3-OpeD-NFO","AC3-PRoDJi",
"AC3-SANTi", "AC3-T0XiCiNK", "AC3-TDP", "AC3-TMR", "AC3-TRD", "AC3-TSTeam",
"AC3-TiMPE", "AC3-ViSiON", "AC3-VoMiT", "AC3-WHiiZz", "AC3-dev", "AC3-lOVE",
"AC3-lOVE-FR", "AC3-lOVE-French", "AC3-lOVE_full", "AC3-lOVE_short", "AMIABLE",
"ARROW", "Abandoned", "Ac3", "Ac3-Blackjesus", "BDRiP", "BDRip", "BLUNTROLA",
"BRRip", "CD1", "CD1-OdbC", "CD2", "CD2-OdbC", "COCAIN", "CaLLiOpeD", "D-Z0N3",
"D-Z0N3-FRE", "D-Z0N3-French", "D-z0n3", "DEViSE", "DMT", "DTS", "DVDRiP",
"DVDRip", "DVDRip-ALLiANCE", "DVDrip", "DVSKY", "Desdemona-A", "DivX",
"DivX-Filmikz", "DivX-MDX", "DivX3LM-SMB", "DivX5", "DivX5-aXXo", "ELEKTRI4KA",
"EXTENDED", "FHW", "FR", "FS", "HDRip", "HDTVRip", "HLS", "HQ", "Hive-CM8",
"I2OCK", "I2OCK-French", "II-All", "ISWE", "LiMTED", "LiMiTED",
"LiMiTED-ALLiANCE", "NEW", "NeDiVx", "Okeeffe", "OlFa", "OpeD", "PDTV", "PROD",
"PROPER", "PRoDJi", "REPACK", "RERip", "RETAIL", "STV", "SUBS-TSTeam", "TOTDE",
"TVRip", "TWiST", "TeamSKY-CD1", "TeamSKY-CD2", "UNCUT", "UNRATED", "Upload3r",
"VH", "WS", "X264", "X264-BARC0DE", "XVID", "XVID-lOVE", "XViD",
"XViD-ALLiANCE", "XViD-ARROW", "XViD-AVCDVD", "XViD-BESTDiVX", "XViD-DEPRAViTY",
"XViD-DiAMOND", "XViD-DiVERSE", "XViD-EP1C", "XViD-EPiSODE", "XViD-FAiTH",
"XViD-HLS", "XViD-LARCENY", "XViD-LPD", "XViD-MisFitZ", "XViD-NEDiVX",
"XViD-SAPHiRE", "XViD-TheWretched", "XViD-VH-PROD", "XViD-VOMiT", "XViD-aAF",
"XViD-iKA", "XViD-iMBT", "XviD", "XviD-AEN", "XviD-AFG", "XviD-ALLiANCE",
"XviD-AMIABLE", "XviD-AMiABLE", "XviD-ARCHiViST", "XviD-ARROW", "XviD-ARiGOLD",
"XviD-AVCDVD", "XviD-AbSurdity", "XviD-Absurdity", "XviD-BLUNTROLA",
"XviD-BREAKME", "XviD-BeStDivX", "XviD-CM8", "XviD-COSMiC", "XviD-CULTXViD",
"XviD-CoWRY", "XviD-D3Si", "XviD-DASH", "XviD-DASH-CD1", "XviD-DASH-CD2",
"XviD-DEFACED", "XviD-DEPRAViTY", "XviD-DEViSE", "XviD-DMT", "XviD-DOCUMENT",
"XviD-DOMiNO", "XviD-DVF", "XviD-DVSKY", "XviD-DiAMOND", "XviD-DiVERSE",
"XviD-DoNE", "XviD-ELiXER", "XviD-EP1C", "XviD-ESPiSE", "XviD-EVO",
"XviD-EtraTorrentRG", "XviD-FLAiTE", "XviD-FOX", "XviD-FR", "XviD-FRAGMENT",
"XviD-FiCO", "XviD-FiCO-CD1", "XviD-FiCO-CD2", "XviD-FiHViD", "XviD-GAYGAY",
"XviD-HAGGiS", "XviD-HEARTME", "XviD-HNR", "XviD-JBS", "XviD-KRONOS",
"XviD-KaTa", "XviD-Kata", "XviD-Kata-CD1", "XviD-Kata-CD2", "XviD-LAP",
"XviD-LARCENY", "XviD-LKRG", "XviD-LMG", "XviD-LPD", "XviD-LTRG", "XviD-LUMiX",
"XviD-Larceny", "XviD-M00DY", "XviD-MASSiVE", "XviD-MDCTeam", "XviD-MisFitZ",
"XviD-MoH", "XviD-NARCRONiCS", "XviD-NEDiVX", "XviD-NODLABS", "XviD-NOiR",
"XviD-NYDIC", "XviD-NeDiVx", "XviD-Noir", "XviD-OpeD", "XviD-PROMiSE",
"XviD-PUKKA", "XviD-QCF", "XviD-RCDiVX", "XviD-RUBY", "XviD-ReenCoTRiN",
"XviD-Rogue", "XviD-Rx", "XviD-SAM", "XviD-SANTi", "XviD-SAPHiRE",
"XviD-SPRiNTER", "XviD-STB", "XviD-SUNSPOT", "XviD-ShitBusters", "XviD-SiC",
"XviD-SomeTV", "XviD-TA", "XviD-TASTE", "XviD-TDP", "XviD-THC", "XviD-TMRC",
"XviD-TRD", "XviD-TRD-English H", "XviD-TST", "XviD-TWIZTED", "XviD-TWiST",
"XviD-TWiZTED", "XviD-TheWretched", "XviD-TiMPE", "XviD-UNKNOWN",
"XviD-UNSKiLLED", "XviD-UNVEiL", "XviD-UniverSalAbsurdity", "XviD-VAMPS",
"XviD-VH-PROD", "XviD-VH-PROD-subs-english", "XviD-VOMiT", "XviD-ViP3R",
"XviD-ViSiON", "XviD-VoMiT", "XviD-WASTE", "XviD-X", "XviD-ZMG", "XviD-aAF",
"XviD-amiable", "XviD-espise", "XviD-iGUANA", "XviD-iLG", "XviD-iMAGiNE",
"XviD-iMBT", "XviD-imbt-trd", "XviD-lOVE", "XviD-ph2", "XviD-qcf", "XviD-w666",
"Xvid", "Xvid-TFE", "Yatterman", "[DivXForever]", "[EN]", "[TheRostrum",
"[sharethefiles", "_", "avi", "cd1", "cd2", "divx", "dp", "fake", "iMBT",
"iNTERNAL", "idx", "mkv", "mp4", "net)", "net]", "nfo", "of", "ojos", "on",
"or", "osloskop", "png", "rar", "srt", "srt_1", "sub", "the", "to", "txt",
"vodo", "vs", "with", "x264", "x264-APAX", "x264-D-Z0N3", "x264-SHiTTy",
"x264-ShitBusters", "x264-ShitBusters-FR", "x264-VODO", "xvid"
);
$output_dir = dirname($movie_dir);
// Pulled this from: http://tycoontalk.freelancer.com/php-forum/41811-list-files-in-directory-sub-directories.html
// Recursively searches through a directory and all subdirectories for files
function ListFiles($dir) {
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "\\" . $file)) {
$inner_files = ListFiles($dir . "\\" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "\\" . $file);
}
}
}
closedir($dh);
return $files;
}
}
// Iterate through the list of movies and attempt to find info
// using the imdb API (http://www.imdbapi.com/)
foreach (ListFiles($movie_dir) as $movie){
$file_name = basename($movie);
$query_name = $file_name;
foreach ($omit_words as $omit_word){
$query_name = str_replace($omit_word, "", $query_name);
}
foreach ($omit_symbols as $omit_symbol){
$query_name = str_replace($omit_symbol, " ", $query_name);
}
$query_name = trim($query_name);
echo "Searching IMDB for: $query_name \n";
$jsonurl = "http://www.imdbapi.com/?t=" . $file_name;
$json = file_get_contents($jsonurl,0,null,null);
$json_output = json_decode($json);
// Get movie information based on filename
$title = "Unknown";
$year = "Unknown";
$genres = array("Unknown");
$actors = array("Unknown");
$rated = "Unknown";
$rating = "Unknown";
$plot = "Unknown";
$director = "Unknown";
if ($json_output->Response != "Parse Error"){
$title = $json_output->Title;
$year = $json_output->Year;
$genres = explode(",", $json_output->Genre);
$actors = explode(",", $json_output->Actors);
$rated = $json_output->Rated;
$rating = $json_output->Rating;
$plot = $json_output->Plot;
$director = $json_output->Director;
}
// Create rating folders and create hard links
// in each folder
$dir_by_rating = $output_dir . "\\By Rating";
if (!file_exists($dir_by_rating)) {
mkdir($dir_by_rating);
}
if ($rating == "Unknown"){
$dir_rating = $dir_by_rating . "\\" + $rating;
} else {
$dir_rating = $dir_by_rating . "\\" . floor($rating);
}
if (!file_exists($dir_rating)) {
mkdir($dir_rating);
}
chdir ($dir_rating);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
// Create name folders and create hard links
// in each folder
$dir_by_name = $output_dir . "\\By Name";
if (!file_exists($dir_by_name)) {
mkdir($dir_by_name);
}
$dir_name = $dir_by_name . "\\" . strtoupper(substr($title,0,1));
if (!file_exists($dir_name)) {
mkdir($dir_name);
}
chdir ($dir_name);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
// Create genre folders and create hard links
// in each folder
$dir_by_genre = $output_dir . "\\By Genre";
if (!file_exists($dir_by_genre)) {
mkdir($dir_by_genre);
}
foreach ($genres as $genre){
$dir_genre = $dir_by_genre . "\\" . trim($genre);
if (!file_exists($dir_genre)) {
mkdir($dir_genre);
}
chdir ($dir_genre);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
}
// Create actor folders and create hard links
// in each folder
$dir_by_actor = $output_dir . "\\By Actor";
if (!file_exists($dir_by_actor)) {
mkdir($dir_by_actor);
}
foreach ($actors as $actor){
$dir_actor = $dir_by_actor . "\\" . trim($actor);
if (!file_exists($dir_actor)) {
mkdir($dir_actor);
}
chdir ($dir_actor);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
}
// Create year folders and create hard links
// in each folder
$dir_by_year = $output_dir . "\\By Year";
if (!file_exists($dir_by_year)) {
mkdir($dir_by_year);
}
$dir_year = $dir_by_year . "\\" . trim($year);
if (!file_exists($dir_year)) {
mkdir($dir_year);
}
chdir ($dir_year);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
// Create director folders and create hard links
// in each folder
$dir_by_director = $output_dir . "\\By Director";
if (!file_exists($dir_by_director)) {
mkdir($dir_by_director);
}
$dir_director = $dir_by_director . "\\" . trim($director);
if (!file_exists($dir_director)) {
mkdir($dir_director);
}
chdir ($dir_director);
if (!file_exists($file_name)) {
link($movie, $file_name);
}
}
?>
Modify the Script
You will need to update the $movie_dir variable with the location of your movie directory.
Run the Script
- Open a command prompt
- Change directory to where your script is saved
- Type
php sort_movies.php - It will take a few minutes (depending on how many movies you have) before you see any output in the console window.
- For about 1000 movies it took about an hour to run
The script will create a pile of folders next to your movie folder like this:
- Your Movie Folder
- By Genre
- Comedy
- Action
- Etc…
- By Actor
- Patrick Stewart
- William Shatner
- Etc…
- By Director
- George Lucas
- Etc…
- By Year
- 1979
- 1980
- Etc…
In each of these folders the program will create links to movies that fit into those categories. These links look like real files but are in fact “hard links” like you find on Unix systems. The real movie file remains in your movie directory and you can safely delete this links at any time.
Have fun and let me know if you make any improvements.