added convert daemon

git-svn-id: http://yolanda.mister-muffin.de/svn@77 7eef14d0-6ed0-489d-bf55-20463b2d70db
This commit is contained in:
josch 2007-10-17 12:55:35 +00:00
parent 1b40d46482
commit 15ad6bca36
4 changed files with 181 additions and 20 deletions

172
trunk/gnutube_daemon.pl Executable file
View file

@ -0,0 +1,172 @@
#!/usr/bin/perl -w
use Proc::Daemon;
use DBI;
use Digest::SHA;
$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
my $sth = $dbh->prepare(qq{select id from videos where status = 0 limit 1}) or interrupt $dbh->errstr;
$sth->execute() or interrupt $dbh->errstr;
my ($id) = $sth->fetchrow_array();
$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";
#write status 2 to database
$sth = $dbh->prepare(qq{update videos set status = ? where id = ?}) or interrupt $dbh->errstr;
$sth->execute(2, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
}
elsif ($info =~ /I\/O error occured/)
{
appendlog $id, "file not found";
#write status 3 to database
$sth = $dbh->prepare(qq{update videos set status = ? where id = ?}) or interrupt $dbh->errstr;
$sth->execute(3, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
}
elsif ($info =~ /Unknown format/ or $info =~ /could not find codec parameters/)
{
appendlog $id, "file is no video";
#write status 4 to database
$sth = $dbh->prepare(qq{update videos set status = ? where id = ?}) or interrupt $dbh->errstr;
$sth->execute(4, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
}
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";
#write status 5 to database
$sth = $dbh->prepare(qq{update videos set status = ? where id = ?}) or interrupt $dbh->errstr;
$sth->execute(5, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
}
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";
#write status 2 to database
$sth = $dbh->prepare(qq{update videos set status = ? where id = ?}) or interrupt $dbh->errstr;
$sth->execute(2, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
}
else
{
#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";
$filesize = -s "$gnutube_root/tmp/$id";
#fill database
$sth = $dbh->prepare(qq{update videos set
status = ?,
hash = ?,
filesize = ?,
duration = time_to_sec( ? ),
width = ?,
height = ?,
fps = ?
where id = ?}) or interrupt $dbh->errstr;
$sth->execute(1, $sha, $filesize, $duration, $width, $height, $fps, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
#TODO move video
}
else #encode video
{
#TODO uncomment the following line
#exec "ffmpeg2theora --optimize --videobitrate 1000 --audiobitrate 64 --sharpness 0 --endtime 10 --output $gnutube_root/videos/$id $gnutube_root/tmp/$id 2>&1";
appendlog $id, $audio, $video, $width, $height, $fps, $duration, $sha;
#fill database
$sth = $dbh->prepare(qq{update videos set
status = ?,
hash = ?,
filesize = ?,
duration = time_to_sec( ? ),
width = ?,
height = ?,
fps = ?
where id = ?}) or interrupt $dbh->errstr;
$sth->execute(1, $sha, $filesize, $duration, $width, $height, $fps, $id) or interrupt $dbh->errstr;
$sth->finish() or interrupt $dbh->errstr;
#TODO delete temp file
}
}
}
}
}
else
{
sleep 10;
}
}

View file

@ -45,10 +45,15 @@ $dbh->do(qq{create table
id int auto_increment not null, id int auto_increment not null,
title varchar(255) not null, title varchar(255) not null,
caption text not null, caption text not null,
userid varchar(255) not null, userid int not null,
hash char(64) not null, hash char(64) not null,
status int not null, status int not null,
timestamp datetime not null, timestamp datetime not null,
filesize int not null,
duration float not null,
width smallint not null,
height smallint not null,
fps float not null,
primary key (id), primary key (id),
fulltext (title, caption) fulltext (title, caption)
) )

View file

@ -25,31 +25,15 @@ if($userid)
#connect to db #connect to db
my $dbh = DBI->connect("DBI:mysql:$database:$host", $dbuser, $dbpass) or die $dbh->errstr; my $dbh = DBI->connect("DBI:mysql:$database:$host", $dbuser, $dbpass) or die $dbh->errstr;
#video status: #make new entry for video into the databse
# 0 - new entry - nothing done yet
# 1 - successfully uploaded
# 2 - successfully converted
# 3 - error: was not a valid video/format
# 4 - error: video is a duplicate
#do query
my $sth = $dbh->prepare(qq{insert into videos (title, caption, userid, status, timestamp) values ( ?, ?, ?, 0, now())}) or die $dbh->errstr; my $sth = $dbh->prepare(qq{insert into videos (title, caption, userid, status, timestamp) values ( ?, ?, ?, 0, now())}) or die $dbh->errstr;
#execute it
$sth->execute($query->param("title"), $query->param("caption"), $userid) or die $dbh->errstr; $sth->execute($query->param("title"), $query->param("caption"), $userid) or die $dbh->errstr;
#finish query
$sth->finish() or die $dbh->errstr; $sth->finish() or die $dbh->errstr;
#prepare query #get the id of the inserted db entry
$sth = $dbh->prepare(qq{select last_insert_id() }) or die $dbh->errstr; $sth = $dbh->prepare(qq{select last_insert_id() }) or die $dbh->errstr;
#execute it
$sth->execute() or die $dbh->errstr; $sth->execute() or die $dbh->errstr;
#save the resulting username
my ($id) = $sth->fetchrow_array() or die $dbh->errstr; my ($id) = $sth->fetchrow_array() or die $dbh->errstr;
#finish query
$sth->finish() or die $dbh->errstr; $sth->finish() or die $dbh->errstr;
#save uploaded file into temppath #save uploaded file into temppath

View file

@ -355,7 +355,7 @@
<div class="uploadform"> <div class="uploadform">
<form method="post" enctype="multipart/from-data"> <form method="post" enctype="multipart/form-data">
<xsl:attribute name="action"> <xsl:attribute name="action">
<xsl:value-of select="$site_strings/str[@id='page_uploader']" /> <xsl:value-of select="$site_strings/str[@id='page_uploader']" />
</xsl:attribute> </xsl:attribute>