2007-10-17 12:55:35 +00:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
|
|
use Proc::Daemon;
|
|
|
|
use DBI;
|
|
|
|
use Digest::SHA;
|
2007-10-18 09:41:19 +00:00
|
|
|
use File::Copy;
|
2007-10-17 12:55:35 +00:00
|
|
|
|
|
|
|
$database = 'gnutube';
|
|
|
|
$dbhost = 'localhost';
|
|
|
|
$dbuser = 'root';
|
|
|
|
$dbpass = '';
|
|
|
|
$gnutube_root = '/var/www/gnutube';
|
|
|
|
|
|
|
|
#Proc::Daemon::Init;
|
|
|
|
|
|
|
|
$LOG = "/var/www/gnutube/daemon.log";
|
|
|
|
|
|
|
|
|
|
|
|
sub appendlog
|
|
|
|
{
|
|
|
|
if (open(FILE, ">>$LOG"))
|
|
|
|
{
|
|
|
|
print FILE scalar(localtime)." ".$$." ".join(" ",@_)."\n";
|
|
|
|
close FILE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub interrupt
|
|
|
|
{
|
|
|
|
appendlog(@_);
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
|
|
|
|
$dbh = DBI->connect("DBI:mysql:$database:$dbhost", $dbuser, $dbpass) or interrupt "could not connect to db";
|
|
|
|
|
|
|
|
#video status:
|
|
|
|
# 0 - new entry - nothing done yet
|
|
|
|
# 1 - valid public video
|
|
|
|
# 2 - error: invalid audio and/or video stream
|
|
|
|
# 3 - error: file not found
|
|
|
|
# 4 - error: file is not a video
|
|
|
|
# 5 - error: video is a duplicate
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
#get fresh video id from db
|
2007-10-18 09:53:32 +00:00
|
|
|
my $sth = $dbh->prepare(qq{select id, title, description, userid, timestamp from uploaded where status = 0 limit 1}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute() or interrupt $dbh->errstr;
|
2007-10-18 09:53:32 +00:00
|
|
|
my ($id, $title, $description, $userid, $timestamp) = $sth->fetchrow_array();
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
|
|
|
|
|
|
|
if($id)
|
|
|
|
{
|
|
|
|
$info = `ffplay -stats -an -vn -nodisp $gnutube_root/tmp/$id 2>&1`;
|
|
|
|
|
|
|
|
if($info =~ /ignoring/)
|
|
|
|
{
|
|
|
|
appendlog $id, "invalid stream";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 2 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute(2, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
elsif ($info =~ /I\/O error occured/)
|
|
|
|
{
|
|
|
|
appendlog $id, "file not found";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 3 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute(3, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
elsif ($info =~ /Unknown format/ or $info =~ /could not find codec parameters/)
|
|
|
|
{
|
|
|
|
appendlog $id, "file is no video";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 4 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute(4, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$sha = new Digest::SHA(256);
|
|
|
|
$sha->addfile("$gnutube_root/tmp/$id");
|
|
|
|
$sha = $sha->hexdigest;
|
|
|
|
|
|
|
|
#check if this hash is already in database
|
|
|
|
my $sth = $dbh->prepare(qq{select id from videos where hash = ? limit 1}) or interrupt $dbh->errstr;
|
|
|
|
$sth->execute($sha) or interrupt $dbh->errstr;
|
|
|
|
my ($resultid) = $sth->fetchrow_array();
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
|
|
|
|
|
|
|
#if so, then video is a duplicate
|
|
|
|
if($resultid)
|
|
|
|
{
|
|
|
|
appendlog "$id, video already uploaded: $resultid";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 5 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute(5, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
($container, $duration) = $info =~ /Input \#0, (\w+),.+?\n.+?Duration: (\d{2}:\d{2}:\d{2}\.\d)/;
|
|
|
|
|
|
|
|
#these two regexes have to be applied seperately because nobody knows which stream (audio or video) comes first
|
|
|
|
($audio) = $info =~ /Audio: (\w+)/;
|
|
|
|
($video, $width, $height, $fps) = $info =~ /Video: (\w+),.+?(\d+)x(\d+),.+?(\d+\.\d+) fps/;
|
|
|
|
|
|
|
|
if(!$audio or !$video or !$duration)
|
|
|
|
{
|
|
|
|
appendlog $id, "a stream is missing or video is corrupt";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 2 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->execute(2, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-10-17 14:01:28 +00:00
|
|
|
$filesize = -s "$gnutube_root/tmp/$id";
|
|
|
|
|
2007-10-17 12:55:35 +00:00
|
|
|
#check if the upload already is in the right format
|
|
|
|
if ($container eq 'ogg' and $video eq 'theora' and $audio eq 'vorbis')
|
|
|
|
{
|
|
|
|
appendlog $id, "file already is ogg-theora/vorbis";
|
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#write status 1 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
|
|
|
$sth->execute(1, $id) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
|
|
|
|
#add video to videos table
|
2007-10-18 09:53:32 +00:00
|
|
|
$sth = $dbh->prepare(qq{insert into videos (id, title, description, userid, timestamp,
|
2007-10-18 09:41:19 +00:00
|
|
|
hash, filesize, duration, width, height, fps)
|
|
|
|
values (?, ?, ?, ?, ?, ?, ?, time_to_sec( ? ), ?, ?, ?)}) or interrupt $dbh->errstr;
|
2007-10-18 09:53:32 +00:00
|
|
|
$sth->execute($id, $title, $description, $userid, $timestamp, $sha, $filesize, $duration, $width, $height, $fps) or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
|
|
|
|
|
|
|
#move video
|
|
|
|
move "$gnutube_root/tmp/$id", "$gnutube_root/videos/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
else #encode video
|
|
|
|
{
|
2007-10-18 09:41:19 +00:00
|
|
|
system "ffmpeg2theora --optimize --videobitrate 1000 --audiobitrate 64 --sharpness 0 --endtime 10 --output $gnutube_root/videos/$id $gnutube_root/tmp/$id 2>&1";
|
2007-10-17 12:55:35 +00:00
|
|
|
appendlog $id, $audio, $video, $width, $height, $fps, $duration, $sha;
|
2007-10-18 09:41:19 +00:00
|
|
|
|
|
|
|
#write status 1 to uploaded table
|
|
|
|
$sth = $dbh->prepare(qq{update uploaded set status = ? where id = ?}) or interrupt $dbh->errstr;
|
|
|
|
$sth->execute(1, $id) or interrupt $dbh->errstr;
|
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
|
2007-10-18 09:41:19 +00:00
|
|
|
#add video to videos table
|
2007-10-18 09:53:32 +00:00
|
|
|
$sth = $dbh->prepare(qq{insert into videos (id, title, description, userid, timestamp,
|
2007-10-18 09:41:19 +00:00
|
|
|
hash, filesize, duration, width, height, fps)
|
|
|
|
values (?, ?, ?, ?, ?, ?, ?, time_to_sec( ? ), ?, ?, ?)}) or interrupt $dbh->errstr;
|
2007-10-18 09:53:32 +00:00
|
|
|
$sth->execute($id, $title, $description, $userid, $timestamp, $sha, $filesize, $duration, $width, $height, $fps) or interrupt $dbh->errstr;
|
2007-10-17 12:55:35 +00:00
|
|
|
$sth->finish() or interrupt $dbh->errstr;
|
2007-10-18 09:41:19 +00:00
|
|
|
|
|
|
|
#delete temp file
|
|
|
|
unlink "$gnutube_root/tmp/$id";
|
2007-10-17 12:55:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sleep 10;
|
|
|
|
}
|
|
|
|
}
|