- Add videodb PHP/MySQL media collection manager (Blu-ray, DVD, CD) - Dockerfile: PHP 8.1 + Apache with GD/mysqli/exif extensions - docker-compose.yml: app on port 6761 + MySQL 8.0 with health checks - docker-entrypoint.sh: auto-generates config.inc.php from env vars, waits for MySQL, initializes DB schema idempotently - init-db.php: CLI schema installer using app's own prefix_query() logic - Persistent volumes for DB, cache, and cover images Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
325 lines
8.9 KiB
Perl
325 lines
8.9 KiB
Perl
#!/usr/bin/perl
|
|
|
|
##
|
|
# Add video files from local disc
|
|
#
|
|
# @package videoDB
|
|
# @author Andreas Gohr <a.gohr@web.de>
|
|
#
|
|
# TODO check paths for correctness
|
|
##
|
|
|
|
# path to md4sum
|
|
# Get it from http://www-tet.ee.tu-berlin.de/solyga/linux/
|
|
#
|
|
# If you don't want md4 sums (time consuming) set it to a
|
|
# blank string
|
|
$md4sum = ''; #/usr/local/bin/md4sum';
|
|
|
|
# If you want md4 sums: in which custom field should it be
|
|
# stored? In VideoDB it should have 'ed2k' as type
|
|
#$md4field = 'custom2';
|
|
|
|
# If you want a download link to the file: in which custom
|
|
# field should it be stored? In VideoDB it should have
|
|
# 'url' as type
|
|
#$urlfield = 'custom1';
|
|
|
|
# path to the eject tool,
|
|
#found this not real useful when you can rub the script to process a directory,
|
|
#but if you going to us a cdrom you un comment it it.
|
|
#$eject = '/usr/bin/eject';
|
|
|
|
# path to mplayer (only version 0.90 was tested, 1.0rc1 works too)
|
|
$mplayer = '/usr/bin/mplayer';
|
|
|
|
# cdrom to use (reads it from commandline)
|
|
$device = $ARGV[ 0 ];
|
|
# alter "/writer" to the directory you have videos in to process.
|
|
$device = "/writer" unless (defined($device));
|
|
|
|
# do the mount ?
|
|
$do_mount = 0;
|
|
|
|
# remove articles
|
|
$remove_article = 1;
|
|
|
|
# if you use the multiuser feature you may want to give an
|
|
# owner of the movies to add here - if you don't need it just
|
|
# set it to a blank string
|
|
$owner_id = 1;
|
|
|
|
# allowed suffixes
|
|
$suffix_re = 'avi|ogm|ogg|bin|mpe?g|ra?m|mov|asf|wmv|mp4|mkv';
|
|
|
|
# Database stuff
|
|
$driver = "mysql";
|
|
$database = "VideoDB";
|
|
$prefix = ""; // enter your DB prefix like videodb. in here
|
|
$hostname = "server";
|
|
$user = "www";
|
|
$password = "leech";
|
|
|
|
################################################################################
|
|
use DBI;
|
|
|
|
#Connect to database
|
|
$dsn = "DBI:$driver:database=$database;host=$hostname";
|
|
$dbh = DBI->connect($dsn, $user, $password);
|
|
|
|
#quote this only once:
|
|
$owner = $dbh->quote($owner);
|
|
|
|
if (-f $device)
|
|
{
|
|
$plain = $device;
|
|
$plain =~ s#.*/([^/]+)$#\1#i;
|
|
add($device,$plain);
|
|
}
|
|
else
|
|
{
|
|
|
|
# mount
|
|
($do_mount) && system("$eject -t $device");
|
|
($do_mount) && system("mount $device");
|
|
|
|
#work
|
|
&readfiles($device);
|
|
|
|
#umount
|
|
($do_mount) && system("umount $device");
|
|
($do_mount) && system("$eject $device");
|
|
}
|
|
|
|
#disconnect
|
|
$dbh->disconnect();
|
|
|
|
#
|
|
###############################################################################
|
|
|
|
sub readfiles($)
|
|
{
|
|
my $path = $_[ 0 ];
|
|
|
|
opendir(ROOT, $path);
|
|
my @files = readdir(ROOT);
|
|
closedir(ROOT);
|
|
|
|
my ($file, $ffile);
|
|
foreach $file (@files)
|
|
{
|
|
$ffile = "$path/$file";
|
|
|
|
next if ($file =~ /^\.|\.\.$/); #skip upper dirs
|
|
if (-d $ffile)
|
|
{
|
|
readfiles($ffile);
|
|
}
|
|
|
|
if ($ffile =~ /\.($suffix_re)$/i)
|
|
{
|
|
&add($ffile, $file); #add it
|
|
print STDERR "$ffile\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
sub add($$)
|
|
{
|
|
my $ffile = $_[ 0 ]; #full path
|
|
my $file = $_[ 1 ]; #file only
|
|
|
|
# get filestatistics
|
|
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($ffile);
|
|
|
|
# get md4
|
|
my $md4;
|
|
if ($md4sum ne '')
|
|
{
|
|
$md4 = `$md4sum "$ffile"`;
|
|
$md4 =~ s/\s.*$//;
|
|
}
|
|
|
|
# get videoinfos
|
|
my ($audio_codec, $video_codec, $video_width, $video_height, $runtime);
|
|
print qq($mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null);
|
|
my @out = `$mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null` if ($mplayer);
|
|
foreach my $line (@out)
|
|
{
|
|
next unless ($line =~ m/^ID_/);
|
|
chomp($line);
|
|
if ($line =~ m/^ID_VIDEO_FORMAT=(.*)/)
|
|
{
|
|
$video_codec = $1;
|
|
$video_codec = 'MPEG1' if ($video_codec eq '0x10000001');
|
|
$video_codec = 'MPEG2' if ($video_codec eq '0x10000002');
|
|
$video_codec = 'MPEG4' if ($video_codec eq 'MPG4');
|
|
#FIXME id's of other mpegs??
|
|
$video_codec = 'DivX3' if ($video_codec eq 'DIV3');
|
|
$video_codec = 'DivX3' if ($video_codec eq 'div3');
|
|
$video_codec = 'DivX4' if ($video_codec eq 'DIV4');
|
|
$video_codec = 'DivX4' if ($video_codec eq 'DIVX');
|
|
$video_codec = 'DivX4' if ($video_codec eq 'divx');
|
|
$video_codec = 'DivX5' if ($video_codec eq 'DX50');
|
|
$video_codec = 'XviD' if ($video_codec eq 'XVID');
|
|
#FIXME aliases of other codecs?
|
|
#Add more 20/1/2015 by LinuxHam couple extra codecs to help get data needed
|
|
$video_codec = 'H264' if ($video_codec eq 'ffh264');
|
|
$video_codec = 'avc1' if ($video_codec eq 'ffh264');
|
|
$video_codec = 'MP4V' if ($video_codec eq 'ffodivx');
|
|
}
|
|
elsif ($line =~ m/^ID_VIDEO_WIDTH=(.*)/)
|
|
{
|
|
$video_width = $1;
|
|
}
|
|
elsif ($line =~ m/^ID_VIDEO_HEIGHT=(.*)/)
|
|
{
|
|
$video_height = $1;
|
|
}
|
|
elsif ($line =~ m/^ID_AUDIO_CODEC=(.*)/)
|
|
{
|
|
$audio_codec = $1;
|
|
$audio_codec = 'MP3' if ($audio_codec eq 'mad');
|
|
$audio_codec = 'MP3' if ($audio_codec eq 'mp3');
|
|
$audio_codec = 'AC3' if ($audio_codec eq 'a52');
|
|
$audio_codec = 'Vorbis' if ($audio_codec eq 'ffvorbis');
|
|
$audio_codec = 'PCM' if ($audio_codec eq 'pcm');
|
|
$audio_codec = 'WMA2' if ($audio_codec eq 'ffwmav2');
|
|
$audio_codec = 'WMA1' if ($audio_codec eq 'ffwmav1'); # just a guess, needs confirmation
|
|
#Add more 20/1/2015 by LinuxHam, couple extra codecs to help get data needed
|
|
$audio_codec = '8192' if ($audio_codec eq 'ffac3');
|
|
$audio_codec = 'MP4A' if ($audio_codec eq 'ffaac');
|
|
$audio_codec = '85' if ($audio_codec eq 'ffmp3float');
|
|
}
|
|
elsif ($line =~ m/^ID_LENGTH=(.*)/)
|
|
{
|
|
$runtime = $1;
|
|
$runtime = sprintf("%d", $runtime / 60);
|
|
}
|
|
}
|
|
|
|
# get titles
|
|
my ($lang, $title, $subtitle, $istv) = &guessnames($file);
|
|
|
|
# prepare for inserts
|
|
$file = $dbh->quote($file);
|
|
$size = $dbh->quote($size);
|
|
$audio_codec = $dbh->quote($audio_codec);
|
|
$video_codec = $dbh->quote($video_codec);
|
|
$video_width = $dbh->quote($video_width);
|
|
$video_height = $dbh->quote($video_height);
|
|
$runtime = $dbh->quote($runtime);
|
|
$lang = $dbh->quote($lang);
|
|
$title = $dbh->quote($title);
|
|
$subtitle = $dbh->quote($subtitle);
|
|
$md4 = $dbh->quote($md4);
|
|
$ffile = $dbh->quote($ffile);
|
|
|
|
# insert
|
|
$INSERT = "INSERT INTO ".$prefix."videodata
|
|
SET filename = $file,
|
|
filesize = $size,
|
|
audio_codec = $audio_codec,
|
|
video_codec = $video_codec,
|
|
video_width = $video_width,
|
|
video_height = $video_height,
|
|
language = $lang,
|
|
title = $title,
|
|
subtitle = $subtitle,
|
|
runtime = $runtime,
|
|
mediatype = 4,
|
|
istv = $istv,
|
|
filedate = FROM_UNIXTIME($mtime),
|
|
created = NOW(),
|
|
owner_id = $owner_id";
|
|
if ($md4sum ne '')
|
|
{
|
|
$INSERT .= ", $md4field = $md4";
|
|
}
|
|
|
|
if ($urlfield ne '')
|
|
{
|
|
$INSERT .= ", $urlfield = $ffile";
|
|
}
|
|
$dbh->do($INSERT);
|
|
|
|
#print "$file \n$title - $subtitle\n\n";
|
|
}
|
|
|
|
sub guessnames($)
|
|
{
|
|
my $episode = "";
|
|
my $istv = 0;
|
|
|
|
my $file = $_[ 0 ]; #file only
|
|
|
|
# try to get language
|
|
# backdrafts: es matches german word, de probably some french stuff
|
|
my $lang = "";
|
|
$lang = "german" if ($file =~ m/\b(german|deutsch|ger|de)\b/i);
|
|
$lang = "english" if ($file =~ m/\b(english|eng|en)\b/i);
|
|
$lang = "french" if ($file =~ m/\b(french|français|fra|fr)\b/i);
|
|
$lang = "spanish" if ($file =~ m/\b(spanish|español|es)\b/i);
|
|
|
|
# remove add. info
|
|
$file =~ s/\(.*\)//;
|
|
|
|
#remove common trash and suffixes
|
|
$file =~ s/(\[[^\]]\]|bin|cd\d|dvd\d|divx|xvid|[ms]?vcd|dvdscr|dvdrip|shareconnector|eselfilme)//gi;
|
|
$file =~ s/\.($suffix_re)$//gi;
|
|
|
|
# get episode Number
|
|
if ($file =~ s/(s\d+e\d+)/-/i)
|
|
{
|
|
$episode = $1;
|
|
}
|
|
elsif ($file =~ s/(\d+x\d+)/-/i)
|
|
{
|
|
$episode = $1;
|
|
}
|
|
|
|
# change dots to underscores
|
|
$file =~ s/\./_/g;
|
|
|
|
# change underscores to spaces
|
|
$file =~ s/_/ /g;
|
|
|
|
# split title and subtitle and cleanup
|
|
my @parts = split ("-", $file, 2);
|
|
my $title = $parts[ 0 ];
|
|
my $subtitle = $parts[ 1 ];
|
|
$title =~ s/^[\s-]*//g;
|
|
$title =~ s/[\s-]*$//g;
|
|
$subtitle =~ s/^[\s-]*//g;
|
|
$subtitle =~ s/[\s-]*$//g;
|
|
|
|
if ($episode)
|
|
{
|
|
$subtitle = "[$episode] $subtitle";
|
|
$istv = 1;
|
|
}
|
|
|
|
if ($remove_article)
|
|
{
|
|
unless ($title =~ s/^(for the)\b(.*)$/$2, $1/i)
|
|
{
|
|
unless ($title =~ s/^(for a)\b(.*)$/$2, $1/i)
|
|
{
|
|
unless ($title =~ s/^(for)\b(.*)$/$2, $1/i)
|
|
{
|
|
unless ($title =~ s/^(the)\b(.*)$/$2, $1/i)
|
|
{
|
|
unless ($title =~ s/^(a)\b(.*)$/$2, $1/i)
|
|
{
|
|
($title =~ s/^(der|die|das)\b(.*)$/$2, $1/i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
chomp ($title);
|
|
|
|
return ($lang, $title, $subtitle, $istv);
|
|
}
|