Files

423 lines
13 KiB
PHP
Raw Permalink Normal View History

<?php
/**
* Add movies on a file system to the DB
*
* Pre-requsisions:
* mplayer:
* Test if installed with this command: mplayer -v
* If not installed use this command (Ubuntu) to install: sudo apt install mplayer
*
* Please change following variables
*
* movie_dirs -- list of directories to search for a new files
* update_missing -- if set to TRUE, the movie with a file in DB but not on a disk will be set as wanted
* update_moved -- if set to TRUE, if file was moved to a different location on a disk, the location in a DB will be updated to a new path
* clean_file_name -- is a substring in a name of the file you want to be removed when setting movie name
* skip_folders -- a list of subfolders to be skipped
*
* @package pages
* @author Alexander Mondshain <alex_mond@yahoo.com>
* @author Alexander Mondshain <klaus_edwin@hotmail.com>
* @version $Id: videoadd.php,v 1.3 2018/09/23 13:02:11 kec2 Exp $
*/
chdir('..');
require './core/functions.php';
// Movies on the file system.
// File name is key and full path is value.
$moviesFS = array();
// duplicate file on file system.
// File name is key and full path is value.
$doubles = array();
// NOTE : as a minimum change the following movie_dirs variable to point to a movie directory $movieDirs = array("/moviedir1","/moviedir2);
$movieDirs = array();
$movieExts = '(avi|mpg|bin|mpeg|ogm|bin|mkv|m2ts|iso)';
$cleanFileName = '(.avi|.mkv|.iso|.m2ts|XVID|XviD|XViD|Xvid|CD1)';
$skipFolders = '/^\.|^CVS|^lost|^photos|^music|^staff/';
// NOTE:update_missing, update missing files and associeted movies as wanted
// NOTE:update_moved. update moved files with a new file location
$update_missing = false;
$update_moved = false;
/**
* Check if MPlayer is installed.
*
* @return boolean True if it is installed.
*/
function isMPlayerInstalled()
{
$out = null;
$ret = - 1;
@exec("mplayer -v", $out, $ret);
return $ret == '0';
}
/**
* If a movies consits of multiple file then all but one will be removed.
* fx. Thor_CD1.avi, Thor_CD2.avi and Thor_CD3.avi => Thor_CD1.avi.
*/
function removeCDNumbers($moviesFS)
{
foreach ($moviesFS as $movie) {
$filePathParts = preg_split("/\//", $movie);
$fileName = end($filePathParts);
if (preg_match("/CD2/i", $movie)) {
unset($moviesFS[$fileName]);
} else if (preg_match("/CD3/i", $movie)) {
unset($moviesFS[$fileName]);
} else if (preg_match("/CD4/i", $movie)) {
unset($moviesFS[$fileName]);
}
}
return $moviesFS;
}
function getFileSizeLinux($file)
{
$out = null;
$ret = - 1;
@exec("stat -c %s \"$file\"", $out, $ret);
if ($ret != '0') {
return FALSE;
} else {
return ($out[0]);
}
}
function getFileTimeLinux($file)
{
$out = null;
$ret = - 1;
@exec("stat -c %Y \"$file\"", $out, $ret);
if ($ret != '0') {
return FALSE;
} else {
return ($out[0]);
}
}
/**
*
* Get all movie files requrcily starting from \$dir.
*
* @param String $dir
* The starting point.
* @param String $ext
* Files with these file extensions are or included in the result.
* @param String $skip
* Directories to skip.
*/
function recurseDir($dir, $ext, $skip)
{
// echo "In DIR $dir<br>";
global $moviesFS, $doubles;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
// Exclude all dot file, CVS and lost+found directories
if (preg_match($skip, $file)) {
continue;
}
// If the file is a movie, we add it to the list
if (preg_match("/\.$ext$/", $file)) {
if (isset($moviesFS[$file])) {
array_push($doubles, $moviesFS[$file]);
array_push($doubles, "$dir/$file");
} else {
$moviesFS[$file] = "$dir/$file";
}
}
// If this is a directory we search it
if (is_dir("$dir/$file")) {
recurseDir("$dir/$file", $ext, $skip);
}
}
closedir($dh);
}
}
/**
* Get combined file size of a movies with multiple files.
* fx. Thor_CD1.avi (100k), Thor_CD2.avi (200k) and Thor_CD3.avi (150k) => 450k.
*
* @param string $filePath
* Path to the first file.
* @return integer The size of the file(s).
*/
function getFileSize($filePath)
{
$fileSize = getFileSizeLinux($filePath);
if (preg_match("/CD1/i", $filePath)) {
$newfile = preg_replace("/(CD)(\d)/i", '${1}2', $filePath);
$fileSize += getFileSizeLinux($newfile);
$newfile = preg_replace("/(CD)(\d)/i", '${1}3', $filePath);
$fileSize += getFileSizeLinux($newfile);
$newfile = preg_replace("/(CD)(\d)/i", '${1}4', $filePath);
$fileSize += getFileSizeLinux($newfile);
}
return $fileSize;
}
/**
* Get metadata of a movie.
* Data include video codec, audio codec, video width and video height.
* MPlayer is used to retrive these data.
*
* @param String $filePath
* File path to the movie.
* @return array An assosiative array with keys: videoCodec, audioCodec, videoHeight and videoWidth.
*/
function getMetadata($filePath)
{
$metadata = array();
$command = "mplayer -vo null -ao null -frames 3 -identify \"$filePath\"";
// echo "command: ".$command."<br>";
$output = array();
$return_var = 0;
$match = array();
exec($command, $output, $return_var);
// parse mplayer output
foreach ($output as $line) {
trim($line);
if (preg_match("/ID_VIDEO_CODEC=(.*)/", $line, $match)) {
$videoCodec = strtolower($match[1]);
switch ($videoCodec) {
case 'ffh264':
$metadata['videoCodec'] = 'H.264';
break;
case 'ffvc1':
$metadata['videoCodec'] = 'VC1';
break;
case '0x10000001':
$metadata['videoCodec'] = 'MPEG1';
break;
case 'ffmpeg2':
$metadata['videoCodec'] = 'MPEG2';
break;
case '0x10000002':
$metadata['videoCodec'] = 'MPEG2';
break;
case 'mpg4':
$metadata['videoCodec'] = 'MPEG4';
break;
case 'div3':
$metadata['videoCodec'] = 'DivX3';
break;
case 'div4':
$metadata['videoCodec'] = 'DivX4';
break;
case 'divx':
$metadata['videoCodec'] = 'DivX4';
break;
case 'dx50':
$metadata['videoCodec'] = 'DivX5';
break;
case 'xvid':
$metadata['videoCodec'] = 'XviD';
break;
default:
$metadata['videoCodec'] = 'Unknown';
echo 'Unknown Video Codec: ' . $match[1] . '<br>';
}
} else if (preg_match("/ID_AUDIO_CODEC=(.*)/", $line, $match)) {
$audioCodec = strtolower($match[1]);
switch ($audioCodec) {
case 'fftruehd':
$metadata['audioCodec'] = 'Dolby TrueHD';
break;
case 'ffdca':
$metadata['audioCodec'] = 'DTS-HD Master Audio';
break;
case 'ffac3':
$metadata['audioCodec'] = 'AC-3';
break;
case 'a52':
$metadata['audioCodec'] = 'AC3';
break;
case 'pcm':
$metadata['audioCodec'] = 'Uncompressed PCM';
break;
case 'dvdpcm':
$metadata['audioCodec'] = 'Uncompressed DVD/VOB LPCM';
break;
case 'mad':
$metadata['audioCodec'] = 'MP3';
break;
case 'mp3':
$metadata['audioCodec'] = 'MP3';
break;
case 'ffvorbis':
$metadata['audioCodec'] = 'Vorbis';
break;
case 'ffwmav1':
$metadata['audioCodec'] = 'WMA1';
break;
case 'ffwmav2':
$metadata['audioCodec'] = 'WMA2';
break;
default:
$metadata['audioCodec'] = 'Unknown';
echo 'Unknown Audio Codec: ' . $match[1] . '<br>';
}
} else if (preg_match("/ID_VIDEO_WIDTH=(.*)/", $line, $match)) {
$metadata['videoWidth'] = $match[1];
} else if (preg_match("/ID_VIDEO_HEIGHT=(.*)/", $line, $match)) {
$metadata['videoHeight'] = $match[1];
}
}
return $metadata;
}
?>
<html>
<head>
<title>Add and move files</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="description" content="VideoDB" />
<link rel="stylesheet" href="../<?php echo $config['style'] ?>"
type="text/css" />
</head>
<body>
<?php
if (!isMPlayerInstalled()) {
echo '<h1 style="color:red;">mplayer is not installed! Please install it.</h1><br>';
exit();
}
if (count($movieDirs) == 0) {
echo '<h1 style="color:red;">PLEASE edit the script and set at least one folder in \$movie_dirs variable </h1><br>';
exit();
}
// get all files. Result is in $moviesFS and $doubles;
foreach ($movieDirs as $dir) {
recurseDir($dir, $movieExts, $skipFolders);
}
// Get all movies that are not on the whishlist (50) or inserted by this tool (51)
$SELECT = 'SELECT id, filename FROM ' . TBL_DATA . ' WHERE mediatype < 50 ORDER BY filename';
$rows = runSQL($SELECT);
echo '<h3>Scanning...</h3>';
echo '<b>Total movie files found on disk:</b> ' . sizeof($moviesFS) . '<br>';
echo '<b>Total movie files found in DB:</b> ' . count($rows) . '<br><br>';
echo '<h3>Comparing results.</h3>';
foreach ($rows as $row) {
$filePathParts = preg_split("/\//", $row['filename']);
$fileName = end($filePathParts);
$id = $row['id'];
// The path does not match the path found in the database
if ($moviesFS[$fileName] != $row['filename']) {
if (! isset($moviesFS[$fileName])) {
echo "<b>MISSING</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
if ($update_missing) {
$UPDATE = "UPDATE " . TBL_DATA . " SET mediatype='" . MEDIA_WISHLIST . "' WHERE id='{$id}'";
runSQL($UPDATE);
}
} else {
echo "<b>MOVED</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
if ($update_moved) {
$UPDATE = "UPDATE " . TBL_DATA . " SET filename='" . escapeSQL($moviesFS[$fileName]) . "' WHERE id='{$id}'";
runSQL($UPDATE);
}
}
} else {
unset($moviesFS[$fileName]);
}
}
echo '<br><b>New files found:</b> ' . sizeof($moviesFS) . '<br>';
asort($moviesFS);
$moviesFS = removeCDNumbers($moviesFS);
echo '<b>New files found with no CD[2-3-4]:</b> ' . sizeof($moviesFS) . '<br>';
// remove all movies added last time and not updated with real information
// mediatype 51 indicates that the movie was inserted/modified by this tool.
$UPDATE = "DELETE FROM " . TBL_DATA . " WHERE mediatype='51'";
runSQL($UPDATE);
echo '<h3>Data on movies to add.</h3>';
echo "<table class='collapse'>
<tr>
<th>File Name</th>
<th>Title</th>
<th>File Size</th>
<th>Audio Codec</th>
<th>Video Codec</th>
<th>Video Width</th>
<th>Video Height</th>
<th>File Date</th>
</tr>";
$currentUserId = get_current_user_id();
foreach ($moviesFS as $movie) {
$filePathParts = preg_split("/\//", $movie);
$fileName = end($filePathParts);
$title = preg_replace($cleanFileName, '', $fileName);
$title = str_replace('_', ' ', $title);
$filePath = $moviesFS[end($filePathParts)];
$fileSize = (int) getFileSize($filePath);
$fileDate = getFileTimeLinux($filePath);
$metadata = getMetadata($filePath);
$audioCodec = $metadata['audioCodec'];
$videoCodec = $metadata['videoCodec'];
$videoWidth = (int) $metadata['videoWidth'];
$videoHeight = (int) $metadata['videoHeight'];
echo "<tr>
<td>$filePath</td>
<td>$title</td>
<td>$fileSize</td>
<td>$audioCodec</td>
<td>$videoCodec</td>
<td>$videoWidth</td>
<td>$videoHeight</td>
<td>$fileDate</td>
</tr>";
$UPDATE = "INSERT " . TBL_DATA . " SET filename='" . escapeSQL($filePath) . "',
mediatype = 51,
title = '$title',
filesize = $fileSize,
audio_codec = '$audioCodec',
video_codec = '$videoCodec',
video_width = $videoWidth,
video_height = $videoHeight,
owner_id = $currentUserId,
filedate = FROM_UNIXTIME($fileDate)";
runSQL($UPDATE);
}
echo '</table>';
$SELECT = "SELECT id, title FROM " . TBL_DATA . " WHERE mediatype='51' ORDER BY title";
$rows = runSQL($SELECT);
echo '<br><br><h3><New movies added (click to edit):</h3>';
foreach ($rows as $row) {
echo "<a href='../edit.php?id={$row['id']}'>{$row['title']}</a><br>";
}
?>
<h3>All Done</h3>
</body>
</html>