summaryrefslogtreecommitdiffdownload
Diffstat
-rw-r--r--java/org/encours/tools/VideoMaker.java61
-rwxr-xr-xtools/make_video_page.pl162
2 files changed, 192 insertions, 31 deletions
diff --git a/java/org/encours/tools/VideoMaker.java b/java/org/encours/tools/VideoMaker.java
index dd24182..82ad7c7 100644
--- a/java/org/encours/tools/VideoMaker.java
+++ b/java/org/encours/tools/VideoMaker.java
@@ -126,6 +126,7 @@ public class VideoMaker {
int xpos = (int)(laserState.x * currentImage.getWidth() - dotSize*0.5f);
int ypos = (int)(laserState.y * currentImage.getHeight() - dotSize*0.5f);
Graphics2D g = currentImage.createGraphics();
+ g.clipRect(0,0,currentImage.getWidth(),currentImage.getHeight());
g.setColor(laserColor[numLaser % laserColor.length]);
g.fillOval(xpos,ypos,dotSize,dotSize);
}
@@ -155,22 +156,47 @@ public class VideoMaker {
ffmpegCommand = "ffmpeg";
if (pass>0) ffmpegCommand += " -pass "+pass;
- ffmpegCommand += " -v 1 -y -f image2pipe -vcodec ppm -r "+inputFrameRate+":1 -i -";
+ ffmpegCommand += " -v 1 -y -f image2pipe -s 1024x768 -vcodec ppm -r "+inputFrameRate+":1 -i -";
if (pass!=1) ffmpegCommand += " -i "+ args[1];
// FLV settings
if (filename.toLowerCase().endsWith("flv")) {
if (pass!=1) ffmpegCommand += " -acodec libmp3lame -ab 32k -ar 22050";
- ffmpegCommand += " -r 10 -s 512x384 -vcodec flv -g 200 -qscale 5";
+// ffmpegCommand += " -r 10 -s 512x384 -vcodec flv -g 200 -qscale 5";
+
+ ffmpegCommand += " -r 10 -s 640x480 -vcodec flv -g 200 -qscale 5";
+
// Vorbis/Theora by default
} else {
- if (pass!=1) ffmpegCommand += " -acodec libvorbis -ab 16k -ar 16000";
- ffmpegCommand += " -r 10 -s 640x480 -vcodec libtheora -g 50 -qscale 8";
-// ffmpegCommand += " -r 10 -s 512x384 -vcodec libtheora -g 30 -qscale 7";
+// OK GOOD
+// if (pass!=1) ffmpegCommand += " -acodec libvorbis -ab 32k -ar 16000";
+
+
+// Test for flac/png/avi file
+ if (pass!=1) ffmpegCommand += " -acodec flac -ar 16000";
+ ffmpegCommand += " -r 10 -s 640x480 -vcodec png -g 128 -qscale 6";
+
+// OK if libtheora present
+// ffmpegCommand += " -r 10 -s 640x480 -vcodec libtheora -g 50 -qscale 8";
+// smaller files, ok in mplayer but not in firefox
+// ffmpegCommand += " -r 10 -s 640x480 -vcodec libtheora -g 128 -qscale 6";
+// OLD ffmpegCommand += " -r 10 -s 512x384 -vcodec libtheora -g 30 -qscale 7";
}
if (pass==1) ffmpegCommand += " -f rawvideo -y /dev/null";
else ffmpegCommand += " "+ filename;
+
+
+ // hack
+ if (filename.toLowerCase().endsWith("ogv")) {
+
+// ffmpegCommand = "ffmpeg2theora --optimize -x 640 -y 480 -f image2pipe --inputfps 10 -v 6 -K 128 -o " + filename + " -";
+
+//ffmpegCommand = "ffmpeg2theora --inputfps 10 -f image2pipe -o " + filename + " -";
+ }
+
+
+
try {
System.out.println("Executing ffmpeg: "+ ffmpegCommand);
ffmpeg = Runtime.getRuntime().exec(ffmpegCommand);
@@ -207,7 +233,7 @@ public class VideoMaker {
}
}.start();
-
+
try {
while (true) {
int tstamp = recFile.getInt();
@@ -300,14 +326,14 @@ public class VideoMaker {
String basename = new File(args[2]).getName();
String filename = null;
- System.out.println("Generating the ogg/theora replay...");
+ System.out.println("Generating the png/avi replay...");
try {
- filename = new File(args[2],basename+".ogv").getCanonicalPath();
+ filename = new File(args[2],basename+".avi").getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
- vm.process(args,1,filename);
+ vm.process(args,0,filename);
while (true) {
try {
Thread.sleep(5000);
@@ -316,8 +342,17 @@ public class VideoMaker {
}
break;
}
-
- vm.process(args,2,filename);
+return;
+/*
+
+ System.out.println("Generating the ogg/theora replay...");
+ try {
+ filename = new File(args[2],basename+".ogv").getCanonicalPath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ vm.process(args,0,filename);
while (true) {
try {
Thread.sleep(5000);
@@ -377,7 +412,7 @@ public class VideoMaker {
} catch (InterruptedException e) {
e.printStackTrace();
}
-
- }
+*/
+ }
}
diff --git a/tools/make_video_page.pl b/tools/make_video_page.pl
index d4d98f4..93d48f2 100755
--- a/tools/make_video_page.pl
+++ b/tools/make_video_page.pl
@@ -1,7 +1,12 @@
#!/usr/bin/perl
-if ($#ARGV!=0) {
- print "Argument needed: one directory containing ogv and/or flv videos, where to generate the replay.html page\n";
+if ($#ARGV<0) {
+print <<HELPEND;
+Arguments needed:
+- Required: One directory containing ogv and/or flv videos, where to generate the replay.html page
+- Optional: A record file containing events. If there is a ".rec" file in the target directory then it will be used by default. If no file is found the replay page will not contain an HTML5 index for the video.
+- Optional: A text file containing the titles for the index. If the directory contains a file 'titles.txt' then these titles will be used by default. If no file is found then the titles will be extracted from the PDF, and a 'titles.txt' will be generated. Edit this file and re-run the command if needed.
+HELPEND
exit(1);
}
@@ -16,8 +21,65 @@ $toolsdir =~ s,/?[^/]*/*$,,;
system("cp $toolsdir/flvplayer/player_flv_maxi.swf $dir/flvplayer.swf");
system("cp $toolsdir/cortado/cortado-ovt-stripped-0.5.1.jar $dir/cortado.jar");
+# Process events
+if ($#ARGV>0) {
+ $eventfile = $ARGV[1];
+ open(EVENTS,"<$eventfile");
+ @events=<EVENTS>;
+ close(EVENTS);
+ if ($#events<0) {
+ print "Invalid event file: $ARGV[1]\n";
+ exit(1);
+ }
+ @titles=();
+ # load or generate the titles list
+ if ($#ARGV>1) {
+ $titlefile = $ARGV[2];
+ open(TITLE,"<$titlefile");
+ @titles=<TITLE>;
+ close(TITLE);
+ } else {
+ open(TITLE,"<$dir/titles.txt");
+ @titles=<TITLE>;
+ close(TITLE);
+ }
+ if ($#titles<0) {
+ `pdfinfo $dir/slides.pdf|grep Pages` =~ /Pages: *(.*)/;
+ $numPages=$1;
+ for $p (1..$numPages) {
+ @doctext=`pdftotext -f $p -l $p $dir/slides.pdf -`;
+ # would be nice here: recognize a real title from garbage
+ push @titles, $doctext[0];
+ }
+ open(TITLE,">$dir/titles.txt");
+ print TITLE @titles;
+ close(TITLE);
+ }
+ # there may still be an error, ex: no slides.pdf file
+ if ($#titles<0) {
+ print "Titles could not be loaded or generated\n";
+ exit(1);
+ }
+ # run through the events list for page change timings
+ %timings=(1=>0);
+ for $ev (@events) {
+ @evparam=split(" ", $ev);
+ if ($evparam[1]==10) {
+ $pagenum=$evparam[2];
+ # ignore going back, take only the first time a page is loaded
+ if (! exists $timings{$pagenum}) {
+ # convert to seconds
+ $timings{$pagenum}=$evparam[0] / 1000;
+ }
+ }
+ }
+}
+
chdir($dir);
+
+
+
for $fname (glob("*.flv")) {
$fname =~ s/\.flv//;
$dirfiles{$fname} = $fname;
@@ -49,42 +111,106 @@ if ($l =~ /Content-Duration: ([0-9]+):([0-9][0-9]):([0-9][0-9])\.([0-9][0-9][0-9
open REPLAY, ">replay.html";
-print REPLAY <<ENDOFHTML1;
+print REPLAY <<ENDOFHTML;
<html>
<head>
<title>Encours presentation video replay</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ENDOFHTML
+if ($#titles>=0) {
+print REPLAY <<ENDOFHTML;
+<style type="text/css">
+<!--
+ul {list-style:none inside; padding-left:1em;}
+-->
+</style>
+<script type="text/javascript">
+function seekvideo(id,time) {
+ var needflv=false;
+ try {
+ if (document.getElementById(id)!=null) {
+ document.getElementById(id).currentTime = time;
+ document.getElementById(id).play();
+ } else needflv=true;
+ } catch (err) {
+ needflv=true;
+ }
+ if (needflv) try {
+ if (document.getElementById(id+"flv")!=null) {
+ document.getElementById(id+"flv").SetVariable("player:jsSetPosition", time);
+ document.getElementById(id+"flv").SetVariable("player:jsPlay", "");
+ }
+ } catch (err) {
+ }
+}
+</script>
+ENDOFHTML
+}
+print REPLAY <<ENDOFHTML;
</head>
<body>
-ENDOFHTML1
+ENDOFHTML
if (-e $ogvfile) {
-print REPLAY <<ENDOFHTML2;
-<video src="$ogvfile" controls>
+print REPLAY <<ENDOFHTML;
+<table><tr><td style="vertical-align:top;padding:1em">
+<video id="replay" src="$ogvfile" controls>
+ENDOFHTML
+}
+
+if (-e $flvfile) {
+print REPLAY <<ENDOFHTML;
+<object id="replayflv" type="application/x-shockwave-flash" data="flvplayer.swf" width="640" height="480">
+ <param name="movie" value="flvplayer.swf" />
+ <param name="FlashVars" value="flv=$flvfile&autoload=1" />
+ENDOFHTML
+}
+
+if (-e $ogvfile) {
+print REPLAY <<ENDOFHTML;
<applet code="com.fluendo.player.Cortado.class" archive="cortado.jar" width="640" height="480">
<param name="url" value="$ogvfile"/>$lenparam
<param name="framerate" value="10"/>
<param name="autoPlay" value="false"/>
-ENDOFHTML2
+You need either an HTML5 compliant browser, flash, or java installed, to see the video.
+</applet>
+ENDOFHTML
+} elsif (-e $flvfile) {
+print REPLAY "You need flash installed to see the video.\n";
}
if (-e $flvfile) {
-print REPLAY <<ENDOFHTML3;
-<object type="application/x-shockwave-flash" data="flvplayer.swf" width="512" height="384">
- <param name="movie" value="flvplayer.swf" />
- <param name="FlashVars" value="flv=$flvfile&autoload=1" />
+print REPLAY <<ENDOFHTML;
</object>
-ENDOFHTML3
+ENDOFHTML
}
+
if (-e $ogvfile) {
-print REPLAY <<ENDOFHTML4;
-</applet>
+print REPLAY <<ENDOFHTML;
</video>
-<p><a href="$ogvfile">Download the video for offline view</a></p>
-ENDOFHTML4
+<p style="margin-top:2em"><a href="$ogvfile">Download the video for offline view</a></p>
+ENDOFHTML
+if (-r "slides.pdf") {
+print REPLAY "<p><a href=\"slides.pdf\">Download the slides as PDF</a></p>\n";
+}
+print REPLAY <<ENDOFHTML;
+</td>
+<td>
+ENDOFHTML
+if ($#titles>=0) {
+ print REPLAY "<div style=\"border-left:1px solid black\"><ul>";
+ for $page ( sort { $a <=> $b } keys %timings )
+ {
+ print REPLAY "<li><a href=\"javascript:seekvideo('replay',$timings{$page})\">$page: $titles[$page-1]</a></li>\n";
+ }
+ print REPLAY "</ul></div>";
+}
+print REPLAY <<ENDOFHTML;
+</td></tr></table>
+ENDOFHTML
} elsif (-e $flvfile) {
print REPLAY "<p><a href=\"$flvfile\">Download the video for offline view</a></p>"
}
-print REPLAY <<ENDOFHTML5;
+print REPLAY <<ENDOFHTML;
</body>
<html>
-ENDOFHTML5
+ENDOFHTML