Moved email stuff to zutil and moved transoced to its own package
This commit is contained in:
parent
05048442a1
commit
7cac4e155c
20 changed files with 518 additions and 537 deletions
|
|
@ -61,7 +61,7 @@
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>transcoder</servlet-name>
|
<servlet-name>transcoder</servlet-name>
|
||||||
<servlet-class>zall.ZalleryTranscoder</servlet-class>
|
<servlet-class>zall.transcoder.ZalleryTranscoder</servlet-class>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
|
|
||||||
3
Zallery.iml
Normal file → Executable file
3
Zallery.iml
Normal file → Executable file
|
|
@ -11,8 +11,7 @@
|
||||||
<src_folder value="file://$MODULE_DIR$/src" expected_position="0" />
|
<src_folder value="file://$MODULE_DIR$/src" expected_position="0" />
|
||||||
</src_description>
|
</src_description>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||||
<output url="file://$MODULE_DIR$/build/classes" />
|
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
|
|
||||||
14
build.xml
14
build.xml
|
|
@ -23,10 +23,10 @@
|
||||||
<!--classpath included when building-->
|
<!--classpath included when building-->
|
||||||
<path id="classpath.build">
|
<path id="classpath.build">
|
||||||
<fileset dir="${libDir}">
|
<fileset dir="${libDir}">
|
||||||
<include name="**/*.jar"/>
|
<include name="**/*.jar" />
|
||||||
</fileset>
|
</fileset>
|
||||||
<fileset dir="${libExpDir}">
|
<fileset dir="${libExpDir}">
|
||||||
<include name="**/*.jar"/>
|
<include name="**/*.jar" />
|
||||||
</fileset>
|
</fileset>
|
||||||
<pathelement location="${buildDir}" />
|
<pathelement location="${buildDir}" />
|
||||||
</path>
|
</path>
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<!--clean all build paths-->
|
<!--clean all build paths-->
|
||||||
<target name="clean">
|
<target name="clean">
|
||||||
<delete includeemptydirs="true" failonerror="false">
|
<delete includeemptydirs="true" failonerror="false">
|
||||||
<fileset dir="${outputRoot}" includes="**/*"/>
|
<fileset dir="${outputRoot}" includes="**/*" />
|
||||||
</delete>
|
</delete>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
@ -56,10 +56,10 @@
|
||||||
|
|
||||||
<target name="package" depends="build">
|
<target name="package" depends="build">
|
||||||
<war destfile="${releaseDir}/Zallery.war" webxml="WebContent/WEB-INF/web.xml">
|
<war destfile="${releaseDir}/Zallery.war" webxml="WebContent/WEB-INF/web.xml">
|
||||||
<fileset dir="WebContent"/>
|
<fileset dir="WebContent" />
|
||||||
<fileset dir="${srcDir}"/>
|
<!-- <fileset dir="${srcDir}"/> -->
|
||||||
<lib dir="WebContent/WEB-INF/lib"/>
|
<lib dir="WebContent/WEB-INF/lib" />
|
||||||
<classes dir="${buildDir}"/>
|
<classes dir="${buildDir}" />
|
||||||
</war>
|
</war>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ import zall.bean.Folder;
|
||||||
import zall.bean.Image;
|
import zall.bean.Image;
|
||||||
import zall.bean.Media;
|
import zall.bean.Media;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
import zall.util.Email;
|
import zall.util.ZalleryEmail;
|
||||||
|
import zutil.net.smtp.Email;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -54,7 +55,7 @@ public class Zallery extends HttpServlet{
|
||||||
WEBSITE_URL = (String)context.lookup("java:comp/env/WEBSITE_URL");
|
WEBSITE_URL = (String)context.lookup("java:comp/env/WEBSITE_URL");
|
||||||
if( WEBSITE_URL.charAt(WEBSITE_URL.length()-1) != '/')
|
if( WEBSITE_URL.charAt(WEBSITE_URL.length()-1) != '/')
|
||||||
WEBSITE_URL += "/";
|
WEBSITE_URL += "/";
|
||||||
Email.setServer( (String)context.lookup("java:comp/env/SMTP_HOST") );
|
ZalleryEmail.setSMTPHost( (String)context.lookup("java:comp/env/SMTP_HOST") );
|
||||||
DATA_PATH = (String)context.lookup("java:comp/env/DATA_PATH");
|
DATA_PATH = (String)context.lookup("java:comp/env/DATA_PATH");
|
||||||
|
|
||||||
LogUtil.setLevel("zall", Level.FINEST);
|
LogUtil.setLevel("zall", Level.FINEST);
|
||||||
|
|
@ -93,7 +94,7 @@ public class Zallery extends HttpServlet{
|
||||||
if( action.equalsIgnoreCase("verfemail") ){
|
if( action.equalsIgnoreCase("verfemail") ){
|
||||||
User verfuser = User.load(db, Long.parseLong(request.getParameter("id")));
|
User verfuser = User.load(db, Long.parseLong(request.getParameter("id")));
|
||||||
if( verfuser.verifyEmail(request.getParameter("hash")) ){
|
if( verfuser.verifyEmail(request.getParameter("hash")) ){
|
||||||
ZalleryAjax.sendEmailNewUserToAdmin(verfuser, db);
|
ZalleryEmail.sendNewUserRegistrationToAdmin(verfuser, db);
|
||||||
verfuser.save(db);
|
verfuser.save(db);
|
||||||
msgs.add(MessageType.INFO, "Your email has been successfully verified.");
|
msgs.add(MessageType.INFO, "Your email has been successfully verified.");
|
||||||
msgs.add(MessageType.WARNING, "The account is waiting account activation by an admin.");
|
msgs.add(MessageType.WARNING, "The account is waiting account activation by an admin.");
|
||||||
|
|
|
||||||
42
src/zall/ZalleryAjax.java
Normal file → Executable file
42
src/zall/ZalleryAjax.java
Normal file → Executable file
|
|
@ -19,8 +19,8 @@ import zall.action.*;
|
||||||
import zall.action.media.*;
|
import zall.action.media.*;
|
||||||
import zall.action.user.*;
|
import zall.action.user.*;
|
||||||
import zall.bean.*;
|
import zall.bean.*;
|
||||||
import zall.util.Email;
|
import zutil.net.smtp.Email;
|
||||||
import zall.util.Email.ContentType;
|
import zutil.net.smtp.Email.ContentType;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -57,7 +57,7 @@ public class ZalleryAjax extends HttpServlet{
|
||||||
|
|
||||||
protected void registerAction(ZalleryAction action){
|
protected void registerAction(ZalleryAction action){
|
||||||
if(actions == null)
|
if(actions == null)
|
||||||
actions = new HashMap<String,ZalleryAction>();
|
actions = new HashMap<>();
|
||||||
actions.put(action.getActionId().toLowerCase(), action);
|
actions.put(action.getActionId().toLowerCase(), action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ public class ZalleryAjax extends HttpServlet{
|
||||||
/**
|
/**
|
||||||
* @param out is the PrintStream that will be used, no output will be generated if it is null
|
* @param out is the PrintStream that will be used, no output will be generated if it is null
|
||||||
*/
|
*/
|
||||||
public void doGet(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws ServletException{
|
private void doGet(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws ServletException{
|
||||||
DBConnection db = null;
|
DBConnection db = null;
|
||||||
try {
|
try {
|
||||||
String actionStr = request.getParameter("action").toLowerCase();
|
String actionStr = request.getParameter("action").toLowerCase();
|
||||||
|
|
@ -126,38 +126,4 @@ public class ZalleryAjax extends HttpServlet{
|
||||||
if(db != null) db.close();
|
if(db != null) db.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void sendEmailVerification(User user) throws IOException{
|
|
||||||
// Email
|
|
||||||
Email smtpEmail = new Email("admin@koc.se", user.getEmail());
|
|
||||||
smtpEmail.setNiceFrom("Koc.se Admin");
|
|
||||||
smtpEmail.setSubject("Registration at "+Zallery.getWebsiteName());
|
|
||||||
smtpEmail.setContentType(ContentType.HTML);
|
|
||||||
smtpEmail.setMessage("You receive this message because you have requested an account" +
|
|
||||||
"<br>at "+Zallery.getWebsiteName()+". Please click the link to verify your email address: " +
|
|
||||||
"<p><a href='"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"'>"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"</a>" +
|
|
||||||
"<p> You will have to wait for an admin to activate your account after you have verified your email.");
|
|
||||||
smtpEmail.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendEmailNewUserToAdmin(User newuser, DBConnection db) throws SQLException, IOException{
|
|
||||||
// Email the admin about new user
|
|
||||||
Email email = new Email("admin@koc.se", "admin@koc.se");
|
|
||||||
email.setNiceFrom("Koc.se Admin");
|
|
||||||
email.setSubject("New user activation request at "+Zallery.getWebsiteName());
|
|
||||||
email.setContentType(ContentType.HTML);
|
|
||||||
email.setMessage("A new user has registered for an account at " +
|
|
||||||
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteName()+"</a>:" +
|
|
||||||
"<p>Email: <b>" + newuser.getEmail() + "</b>" +
|
|
||||||
"<br>Name: <b>" + newuser.getName() + "</b>" +
|
|
||||||
"<br>Facebook: <a href='http://www.facebook.com/profile.php?id="+newuser.getFacebookUid()+"'>"+newuser.getFacebookUid()+"</a>");
|
|
||||||
List<User> admins = User.loadSuperUsers(db);
|
|
||||||
for(User admin : admins){
|
|
||||||
if( admin.isEmailVerified() ){
|
|
||||||
email.setTo( admin.getEmail() );
|
|
||||||
email.send();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,364 +0,0 @@
|
||||||
package zall;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.servlet.ServletConfig;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
|
|
||||||
import com.xuggle.mediatool.IMediaReader;
|
|
||||||
import com.xuggle.mediatool.IMediaWriter;
|
|
||||||
import com.xuggle.mediatool.MediaToolAdapter;
|
|
||||||
import com.xuggle.mediatool.ToolFactory;
|
|
||||||
import com.xuggle.mediatool.event.AudioSamplesEvent;
|
|
||||||
import com.xuggle.mediatool.event.IAddStreamEvent;
|
|
||||||
import com.xuggle.mediatool.event.IAudioSamplesEvent;
|
|
||||||
import com.xuggle.mediatool.event.IVideoPictureEvent;
|
|
||||||
import com.xuggle.mediatool.event.VideoPictureEvent;
|
|
||||||
import com.xuggle.xuggler.IAudioResampler;
|
|
||||||
import com.xuggle.xuggler.IAudioSamples;
|
|
||||||
import com.xuggle.xuggler.ICodec;
|
|
||||||
import com.xuggle.xuggler.IStreamCoder;
|
|
||||||
import com.xuggle.xuggler.IVideoPicture;
|
|
||||||
import com.xuggle.xuggler.IVideoResampler;
|
|
||||||
import com.xuggle.xuggler.video.ConverterFactory;
|
|
||||||
import com.xuggle.xuggler.video.IConverter;
|
|
||||||
|
|
||||||
import zall.bean.Media.Size;
|
|
||||||
import zall.bean.Video;
|
|
||||||
import zutil.StringUtil;
|
|
||||||
import zutil.db.DBConnection;
|
|
||||||
import zutil.log.LogUtil;
|
|
||||||
|
|
||||||
|
|
||||||
public class ZalleryTranscoder extends HttpServlet{
|
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
// Media Queue
|
|
||||||
private static Queue<Video> transcodingQueue;
|
|
||||||
private static TranscoderThread worker;
|
|
||||||
|
|
||||||
public void init( ServletConfig config ){
|
|
||||||
try{
|
|
||||||
transcodingQueue = new LinkedList<Video>();
|
|
||||||
worker = new TranscoderThread();
|
|
||||||
worker.start();
|
|
||||||
|
|
||||||
// get untranscoded videos
|
|
||||||
DBConnection db = null;
|
|
||||||
try {
|
|
||||||
db = Zallery.getDB();
|
|
||||||
List<Video> incomplete = Video.loadUntransoded( db );
|
|
||||||
synchronized (transcodingQueue) {
|
|
||||||
transcodingQueue.addAll( incomplete );
|
|
||||||
transcodingQueue.notify();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.log(Level.SEVERE, null, e);
|
|
||||||
}finally{
|
|
||||||
if( db != null ) db.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e){
|
|
||||||
logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy( ){
|
|
||||||
worker.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static Video getProcessingVideo(){
|
|
||||||
return worker.currentVideo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Queue<Video> getQueue(){
|
|
||||||
return transcodingQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a video to the transcoding queue
|
|
||||||
*
|
|
||||||
* @param video is the video to transcode
|
|
||||||
*/
|
|
||||||
public static void addVideo(Video video) {
|
|
||||||
if( transcodingQueue == null ){
|
|
||||||
logger.severe("ZalleryTranscoder not initialized!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( !transcodingQueue.contains(video) && worker.currentVideo != video ){
|
|
||||||
synchronized (transcodingQueue){
|
|
||||||
transcodingQueue.add( video );
|
|
||||||
transcodingQueue.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the class that is doing the actual work of transcoding videos
|
|
||||||
*
|
|
||||||
* @author Ziver
|
|
||||||
*/
|
|
||||||
private static class TranscoderThread extends Thread{
|
|
||||||
private boolean stop;
|
|
||||||
protected long startTime;
|
|
||||||
protected Video currentVideo;
|
|
||||||
|
|
||||||
|
|
||||||
public void run(){
|
|
||||||
logger.info("ZalleryTranscoder thread started.");
|
|
||||||
try {
|
|
||||||
while( true ){
|
|
||||||
// Get video to transcode
|
|
||||||
while( !transcodingQueue.isEmpty() ){
|
|
||||||
currentVideo = transcodingQueue.poll();
|
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
logger.info("Starting transcoding video(id:"+currentVideo.getId()+")");
|
|
||||||
|
|
||||||
File originalFile = currentVideo.getFile( Size.ORIGINAL );
|
|
||||||
File mediumFile = currentVideo.getFile( Size.MEDIUM );
|
|
||||||
File smallFile = currentVideo.getFile( Size.SMALL );
|
|
||||||
|
|
||||||
///////////// Start Transcoding
|
|
||||||
// create a media reader
|
|
||||||
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() );
|
|
||||||
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
|
|
||||||
reader.addListener(new ProgressListener(reader));
|
|
||||||
|
|
||||||
VideoTranscoderListener converter = new VideoTranscoderListener(640, 360);
|
|
||||||
reader.addListener(converter);
|
|
||||||
|
|
||||||
// create a media writer
|
|
||||||
IMediaWriter writer = ToolFactory.makeWriter(mediumFile.getPath(), reader);
|
|
||||||
converter.addListener(writer);
|
|
||||||
|
|
||||||
// create a media viewer with stats enabled for debugging
|
|
||||||
// add a viewer to the reader, to see the decoded media
|
|
||||||
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
|
|
||||||
//reader.addListener(mediaViewer);
|
|
||||||
//writer.addListener(mediaViewer);
|
|
||||||
|
|
||||||
// read and decode packets from the source file and
|
|
||||||
// and dispatch decoded audio and video to the writer
|
|
||||||
while (reader.readPacket() == null);
|
|
||||||
|
|
||||||
// Incomplete transcoding
|
|
||||||
if( reader.isOpen() ){
|
|
||||||
logger.severe("Transcoding incomplete, removing incomplete files!");
|
|
||||||
reader.close();
|
|
||||||
mediumFile.delete();
|
|
||||||
smallFile.delete();
|
|
||||||
if( stop )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
logger.info("Done transcoding video(id:"+currentVideo.getId()+") time: "+StringUtil.formatTimeToString(System.currentTimeMillis()-startTime));
|
|
||||||
currentVideo.setTranscoded(true);
|
|
||||||
try{
|
|
||||||
DBConnection db = Zallery.getDB();
|
|
||||||
currentVideo.save(db);
|
|
||||||
db.close();
|
|
||||||
}catch(Exception e){
|
|
||||||
logger.log(Level.SEVERE, "Unable to save video bean!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentVideo = null;
|
|
||||||
}
|
|
||||||
// Wait for new video to transcode
|
|
||||||
synchronized (transcodingQueue) {
|
|
||||||
transcodingQueue.wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.log(Level.SEVERE, "Transcoding thread has crashed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void abort(){
|
|
||||||
stop = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MyVideoListener extends MediaToolAdapter {
|
|
||||||
private Integer width;
|
|
||||||
private Integer height;
|
|
||||||
|
|
||||||
public MyVideoListener(Integer aWidth, Integer aHeight) {
|
|
||||||
this.width = aWidth;
|
|
||||||
this.height = aHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAddStream(IAddStreamEvent event) {
|
|
||||||
int streamIndex = event.getStreamIndex();
|
|
||||||
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
|
|
||||||
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
|
|
||||||
} else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
|
|
||||||
streamCoder.setWidth(width);
|
|
||||||
streamCoder.setHeight(height);
|
|
||||||
}
|
|
||||||
super.onAddStream(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class VideoTranscoderListener extends MediaToolAdapter{
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
|
|
||||||
public VideoTranscoderListener(int width, int height) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IVideoResampler videoResampler = null;
|
|
||||||
private IAudioResampler audioResampler = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAddStream(IAddStreamEvent event) {
|
|
||||||
int streamIndex = event.getStreamIndex();
|
|
||||||
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
|
|
||||||
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
|
|
||||||
streamCoder.setSampleRate( 44100 );
|
|
||||||
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
|
|
||||||
//streamCoder.setBitRate( 128 );
|
|
||||||
}
|
|
||||||
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
|
|
||||||
streamCoder.setWidth( width );
|
|
||||||
streamCoder.setHeight( height );
|
|
||||||
|
|
||||||
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
|
|
||||||
//streamCoder.setBitRate( 800000 );
|
|
||||||
/*
|
|
||||||
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
|
|
||||||
if (retval<0)
|
|
||||||
throw new RuntimeException("cound not cofigure coder from preset file");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
super.onAddStream(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVideoPicture(IVideoPictureEvent event) {
|
|
||||||
IVideoPicture pic = event.getPicture();
|
|
||||||
if (videoResampler == null) {
|
|
||||||
videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
|
|
||||||
}
|
|
||||||
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
|
|
||||||
videoResampler.resample(out, pic);
|
|
||||||
|
|
||||||
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
|
|
||||||
super.onVideoPicture(asc);
|
|
||||||
out.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAudioSamples(IAudioSamplesEvent event) {
|
|
||||||
IAudioSamples samples = event.getAudioSamples();
|
|
||||||
if (audioResampler == null) {
|
|
||||||
audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
|
|
||||||
}
|
|
||||||
if (event.getAudioSamples().getNumSamples() > 0) {
|
|
||||||
IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
|
|
||||||
audioResampler.resample(out, samples, samples.getNumSamples());
|
|
||||||
|
|
||||||
AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
|
|
||||||
super.onAudioSamples(asc);
|
|
||||||
out.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProgressListener extends MediaToolAdapter {
|
|
||||||
private long currentLength;
|
|
||||||
private long totalLength;
|
|
||||||
private int progress = -1;
|
|
||||||
|
|
||||||
public ProgressListener(IMediaReader reader) {
|
|
||||||
if( !reader.isOpen() )
|
|
||||||
reader.open(); // read container
|
|
||||||
this.totalLength = reader.getContainer().getDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVideoPicture(IVideoPictureEvent event) {
|
|
||||||
currentLength = event.getTimeStamp();
|
|
||||||
|
|
||||||
if( (int)(100*getProgress()) != progress ){
|
|
||||||
progress = (int)(100*getProgress());
|
|
||||||
System.out.print("\n"+(int)(100*getProgress())+"% ");
|
|
||||||
}
|
|
||||||
else System.out.print(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getProcessedLength(){
|
|
||||||
return currentLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTotalLength(){
|
|
||||||
return totalLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getProgress(){
|
|
||||||
if(totalLength > 0)
|
|
||||||
return ((double)currentLength/totalLength);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FrameGrabListener extends MediaToolAdapter {
|
|
||||||
private long totalLength;
|
|
||||||
private long grabAt;
|
|
||||||
private File outputFile;
|
|
||||||
|
|
||||||
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
|
|
||||||
if( !reader.isOpen() )
|
|
||||||
reader.open(); // read container
|
|
||||||
this.totalLength = reader.getContainer().getDuration();
|
|
||||||
this.outputFile = outputFile;
|
|
||||||
setAtProgress(at);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onVideoPicture(IVideoPictureEvent event) {
|
|
||||||
try{
|
|
||||||
long currentLength = event.getTimeStamp();
|
|
||||||
|
|
||||||
if( grabAt > 0 && currentLength > grabAt ){
|
|
||||||
System.out.println("\nScreanshoot!!!");
|
|
||||||
|
|
||||||
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
|
|
||||||
ConverterFactory.XUGGLER_BGR_24);
|
|
||||||
IConverter mVideoConverter = ConverterFactory.createConverter(
|
|
||||||
mConverterType.getDescriptor(),
|
|
||||||
event.getPicture());
|
|
||||||
|
|
||||||
ImageIO.write(
|
|
||||||
mVideoConverter.toImage(event.getPicture()),
|
|
||||||
"png",
|
|
||||||
outputFile);
|
|
||||||
grabAt = -1;
|
|
||||||
}
|
|
||||||
}catch(IOException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAtProgress(double procent){
|
|
||||||
grabAt = (long)(totalLength * procent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
3
src/zall/action/RegisterAction.java
Normal file → Executable file
3
src/zall/action/RegisterAction.java
Normal file → Executable file
|
|
@ -11,6 +11,7 @@ import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import zall.ZalleryAjax;
|
import zall.ZalleryAjax;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
|
import zall.util.ZalleryEmail;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -40,7 +41,7 @@ public class RegisterAction extends ZalleryAction{
|
||||||
user.setPassword( request.getParameter("password") );
|
user.setPassword( request.getParameter("password") );
|
||||||
user.setName( request.getParameter("name") );
|
user.setName( request.getParameter("name") );
|
||||||
user.save(db);
|
user.save(db);
|
||||||
ZalleryAjax.sendEmailVerification( user );
|
ZalleryEmail.sendVerificationEmail( user );
|
||||||
logger.info("Registered new user: "+user.getName()+".");
|
logger.info("Registered new user: "+user.getName()+".");
|
||||||
session.setAttribute("user", user);
|
session.setAttribute("user", user);
|
||||||
if(out != null) out.println("{ \"id\":"+user.getId()+" }");
|
if(out != null) out.println("{ \"id\":"+user.getId()+" }");
|
||||||
|
|
|
||||||
11
src/zall/action/user/ModifyUserAction.java
Normal file → Executable file
11
src/zall/action/user/ModifyUserAction.java
Normal file → Executable file
|
|
@ -11,8 +11,9 @@ import javax.servlet.http.HttpSession;
|
||||||
import zall.Zallery;
|
import zall.Zallery;
|
||||||
import zall.action.ZalleryAction;
|
import zall.action.ZalleryAction;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
import zall.util.Email;
|
import zall.util.ZalleryEmail;
|
||||||
import zall.util.Email.ContentType;
|
import zutil.net.smtp.Email;
|
||||||
|
import zutil.net.smtp.Email.ContentType;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -34,11 +35,7 @@ public class ModifyUserAction extends ZalleryAction{
|
||||||
if( request.getParameter("enable") != null ){
|
if( request.getParameter("enable") != null ){
|
||||||
target_user.setEnabled( true );
|
target_user.setEnabled( true );
|
||||||
// Email the user about the activation
|
// Email the user about the activation
|
||||||
Email email = new Email("admin@koc.se", target_user.getEmail());
|
ZalleryEmail.sendActivationEmail(target_user);
|
||||||
email.setSubject("Account activation at "+Zallery.getWebsiteName());
|
|
||||||
email.setContentType(ContentType.HTML);
|
|
||||||
email.setMessage("Your account has now been activated by an admin. You can now login and use the site. " +
|
|
||||||
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteURL()+"</a>");
|
|
||||||
}
|
}
|
||||||
// Disable user, can not disable one self!
|
// Disable user, can not disable one self!
|
||||||
else if( request.getParameter("disable") != null && !user.equals( target_user ) )
|
else if( request.getParameter("disable") != null && !user.equals( target_user ) )
|
||||||
|
|
|
||||||
4
src/zall/action/user/ModifyUserStatusAction.java
Normal file → Executable file
4
src/zall/action/user/ModifyUserStatusAction.java
Normal file → Executable file
|
|
@ -8,9 +8,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import zall.ZalleryAjax;
|
|
||||||
import zall.action.ZalleryAction;
|
import zall.action.ZalleryAction;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
|
import zall.util.ZalleryEmail;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -50,7 +50,7 @@ public class ModifyUserStatusAction extends ZalleryAction{
|
||||||
target_user.setName( request.getParameter("name") );
|
target_user.setName( request.getParameter("name") );
|
||||||
target_user.save(db);
|
target_user.save(db);
|
||||||
if( !user.isEmailVerified() )
|
if( !user.isEmailVerified() )
|
||||||
ZalleryAjax.sendEmailVerification( target_user );
|
ZalleryEmail.sendVerificationEmail( target_user );
|
||||||
if( out != null )
|
if( out != null )
|
||||||
out.println("{ }");
|
out.println("{ }");
|
||||||
else
|
else
|
||||||
|
|
|
||||||
4
src/zall/action/user/SendVerificationEmailAction.java
Normal file → Executable file
4
src/zall/action/user/SendVerificationEmailAction.java
Normal file → Executable file
|
|
@ -9,9 +9,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import zall.ZalleryAjax;
|
|
||||||
import zall.action.ZalleryAction;
|
import zall.action.ZalleryAction;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
|
import zall.util.ZalleryEmail;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -39,7 +39,7 @@ public class SendVerificationEmailAction extends ZalleryAction{
|
||||||
|
|
||||||
if( target_user != null ){
|
if( target_user != null ){
|
||||||
if( user.isSuperUser() ){
|
if( user.isSuperUser() ){
|
||||||
ZalleryAjax.sendEmailVerification(target_user);
|
ZalleryEmail.sendVerificationEmail(target_user);
|
||||||
|
|
||||||
logger.info("Verification email sent successfully to: "+user.getEmail());
|
logger.info("Verification email sent successfully to: "+user.getEmail());
|
||||||
if( out != null ) out.println("{ }");
|
if( out != null ) out.println("{ }");
|
||||||
|
|
|
||||||
11
src/zall/action/user/VerifyEmailAction.java
Normal file → Executable file
11
src/zall/action/user/VerifyEmailAction.java
Normal file → Executable file
|
|
@ -11,6 +11,7 @@ import javax.servlet.http.HttpSession;
|
||||||
import zall.ZalleryAjax;
|
import zall.ZalleryAjax;
|
||||||
import zall.action.ZalleryAction;
|
import zall.action.ZalleryAction;
|
||||||
import zall.bean.User;
|
import zall.bean.User;
|
||||||
|
import zall.util.ZalleryEmail;
|
||||||
import zall.util.msg.UserMessage;
|
import zall.util.msg.UserMessage;
|
||||||
import zall.util.msg.UserMessage.MessageType;
|
import zall.util.msg.UserMessage.MessageType;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
|
|
@ -25,17 +26,17 @@ public class VerifyEmailAction extends ZalleryAction{
|
||||||
public void handleRequest(DBConnection db, HttpServletRequest request, HttpServletResponse response, HttpSession session,
|
public void handleRequest(DBConnection db, HttpServletRequest request, HttpServletResponse response, HttpSession session,
|
||||||
PrintWriter out, User user, UserMessage msgs) throws SQLException, IOException {
|
PrintWriter out, User user, UserMessage msgs) throws SQLException, IOException {
|
||||||
|
|
||||||
User verfuser = User.load(db, Long.parseLong(request.getParameter("id")));
|
User verifiedUser = User.load(db, Long.parseLong(request.getParameter("id")));
|
||||||
if( verfuser.verifyEmail(request.getParameter("hash")) ){
|
if( verifiedUser.verifyEmail(request.getParameter("hash")) ){
|
||||||
if( verfuser.isEnabled() )
|
if( verifiedUser.isEnabled() )
|
||||||
if(out != null) out.println("{ }");
|
if(out != null) out.println("{ }");
|
||||||
else msgs.add(MessageType.INFO, "Your email has been successfully verified");
|
else msgs.add(MessageType.INFO, "Your email has been successfully verified");
|
||||||
else {
|
else {
|
||||||
ZalleryAjax.sendEmailNewUserToAdmin(verfuser, db);
|
ZalleryEmail.sendNewUserRegistrationToAdmin(verifiedUser, db);
|
||||||
if(out != null) out.println("{ }");
|
if(out != null) out.println("{ }");
|
||||||
else msgs.add(MessageType.INFO, "Your email has been successfully verified, the account is waiting account activation by an admin.");
|
else msgs.add(MessageType.INFO, "Your email has been successfully verified, the account is waiting account activation by an admin.");
|
||||||
}
|
}
|
||||||
verfuser.save(db);
|
verifiedUser.save(db);
|
||||||
}
|
}
|
||||||
else if(out != null) out.println("{ \"error\":\"Invalid email verification hash!\" }");
|
else if(out != null) out.println("{ \"error\":\"Invalid email verification hash!\" }");
|
||||||
else msgs.add(MessageType.ERROR, "Invalid email verification hash!");
|
else msgs.add(MessageType.ERROR, "Invalid email verification hash!");
|
||||||
|
|
|
||||||
7
src/zall/bean/User.java
Normal file → Executable file
7
src/zall/bean/User.java
Normal file → Executable file
|
|
@ -28,7 +28,6 @@ public class User extends DBBean{
|
||||||
protected String email;
|
protected String email;
|
||||||
protected boolean emailVerified;
|
protected boolean emailVerified;
|
||||||
protected String password;
|
protected String password;
|
||||||
protected String facebookUid;
|
|
||||||
// Date
|
// Date
|
||||||
protected Timestamp loginDate;
|
protected Timestamp loginDate;
|
||||||
protected transient Timestamp prevLoginDate;
|
protected transient Timestamp prevLoginDate;
|
||||||
|
|
@ -259,12 +258,6 @@ public class User extends DBBean{
|
||||||
public String getSessionHash() {
|
public String getSessionHash() {
|
||||||
return sessionHash;
|
return sessionHash;
|
||||||
}
|
}
|
||||||
public void setFacebookUid(String uid) {
|
|
||||||
facebookUid = uid;
|
|
||||||
}
|
|
||||||
public String getFacebookUid(){
|
|
||||||
return facebookUid;
|
|
||||||
}
|
|
||||||
public boolean isSuperUser(){
|
public boolean isSuperUser(){
|
||||||
return superUser;
|
return superUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
src/zall/bean/Video.java
Normal file → Executable file
2
src/zall/bean/Video.java
Normal file → Executable file
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.fileupload.FileItem;
|
import org.apache.commons.fileupload.FileItem;
|
||||||
|
|
||||||
import zall.ZalleryTranscoder;
|
import zall.transcoder.ZalleryTranscoder;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.db.bean.DBBean;
|
import zutil.db.bean.DBBean;
|
||||||
import zutil.db.bean.DBBeanSQLResultHandler;
|
import zutil.db.bean.DBBeanSQLResultHandler;
|
||||||
|
|
|
||||||
57
src/zall/transcoder/FrameGrabListener.java
Executable file
57
src/zall/transcoder/FrameGrabListener.java
Executable file
|
|
@ -0,0 +1,57 @@
|
||||||
|
package zall.transcoder;
|
||||||
|
|
||||||
|
import com.xuggle.mediatool.IMediaReader;
|
||||||
|
import com.xuggle.mediatool.MediaToolAdapter;
|
||||||
|
import com.xuggle.mediatool.event.IVideoPictureEvent;
|
||||||
|
import com.xuggle.xuggler.video.ConverterFactory;
|
||||||
|
import com.xuggle.xuggler.video.IConverter;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class FrameGrabListener extends MediaToolAdapter {
|
||||||
|
private long totalLength;
|
||||||
|
private long grabAt;
|
||||||
|
private File outputFile;
|
||||||
|
|
||||||
|
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
|
||||||
|
if( !reader.isOpen() )
|
||||||
|
reader.open(); // read container
|
||||||
|
this.totalLength = reader.getContainer().getDuration();
|
||||||
|
this.outputFile = outputFile;
|
||||||
|
setAtProgress(at);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoPicture(IVideoPictureEvent event) {
|
||||||
|
try{
|
||||||
|
long currentLength = event.getTimeStamp();
|
||||||
|
|
||||||
|
if( grabAt > 0 && currentLength > grabAt ){
|
||||||
|
System.out.println("\nScreanshoot!!!");
|
||||||
|
|
||||||
|
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
|
||||||
|
ConverterFactory.XUGGLER_BGR_24);
|
||||||
|
IConverter mVideoConverter = ConverterFactory.createConverter(
|
||||||
|
mConverterType.getDescriptor(),
|
||||||
|
event.getPicture());
|
||||||
|
|
||||||
|
ImageIO.write(
|
||||||
|
mVideoConverter.toImage(event.getPicture()),
|
||||||
|
"png",
|
||||||
|
outputFile);
|
||||||
|
grabAt = -1;
|
||||||
|
}
|
||||||
|
}catch(IOException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAtProgress(double procent){
|
||||||
|
grabAt = (long)(totalLength * procent);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/zall/transcoder/MyVideoListener.java
Executable file
32
src/zall/transcoder/MyVideoListener.java
Executable file
|
|
@ -0,0 +1,32 @@
|
||||||
|
package zall.transcoder;
|
||||||
|
|
||||||
|
import com.xuggle.mediatool.MediaToolAdapter;
|
||||||
|
import com.xuggle.mediatool.event.IAddStreamEvent;
|
||||||
|
import com.xuggle.xuggler.ICodec;
|
||||||
|
import com.xuggle.xuggler.IStreamCoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class MyVideoListener extends MediaToolAdapter {
|
||||||
|
private Integer width;
|
||||||
|
private Integer height;
|
||||||
|
|
||||||
|
public MyVideoListener(Integer aWidth, Integer aHeight) {
|
||||||
|
this.width = aWidth;
|
||||||
|
this.height = aHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddStream(IAddStreamEvent event) {
|
||||||
|
int streamIndex = event.getStreamIndex();
|
||||||
|
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
|
||||||
|
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
|
||||||
|
} else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
|
||||||
|
streamCoder.setWidth(width);
|
||||||
|
streamCoder.setHeight(height);
|
||||||
|
}
|
||||||
|
super.onAddStream(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
45
src/zall/transcoder/ProgressListener.java
Executable file
45
src/zall/transcoder/ProgressListener.java
Executable file
|
|
@ -0,0 +1,45 @@
|
||||||
|
package zall.transcoder;
|
||||||
|
|
||||||
|
import com.xuggle.mediatool.IMediaReader;
|
||||||
|
import com.xuggle.mediatool.MediaToolAdapter;
|
||||||
|
import com.xuggle.mediatool.event.IVideoPictureEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProgressListener extends MediaToolAdapter {
|
||||||
|
private long currentLength;
|
||||||
|
private long totalLength;
|
||||||
|
private int progress = -1;
|
||||||
|
|
||||||
|
public ProgressListener(IMediaReader reader) {
|
||||||
|
if( !reader.isOpen() )
|
||||||
|
reader.open(); // read container
|
||||||
|
this.totalLength = reader.getContainer().getDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoPicture(IVideoPictureEvent event) {
|
||||||
|
currentLength = event.getTimeStamp();
|
||||||
|
|
||||||
|
if( (int)(100*getProgress()) != progress ){
|
||||||
|
progress = (int)(100*getProgress());
|
||||||
|
System.out.print("\n"+(int)(100*getProgress())+"% ");
|
||||||
|
}
|
||||||
|
else System.out.print(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getProcessedLength(){
|
||||||
|
return currentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalLength(){
|
||||||
|
return totalLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getProgress(){
|
||||||
|
if(totalLength > 0)
|
||||||
|
return ((double)currentLength/totalLength);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/zall/transcoder/VideoTranscoderListener.java
Executable file
76
src/zall/transcoder/VideoTranscoderListener.java
Executable file
|
|
@ -0,0 +1,76 @@
|
||||||
|
package zall.transcoder;
|
||||||
|
|
||||||
|
import com.xuggle.mediatool.MediaToolAdapter;
|
||||||
|
import com.xuggle.mediatool.event.*;
|
||||||
|
import com.xuggle.xuggler.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class VideoTranscoderListener extends MediaToolAdapter {
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
public VideoTranscoderListener(int width, int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IVideoResampler videoResampler = null;
|
||||||
|
private IAudioResampler audioResampler = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddStream(IAddStreamEvent event) {
|
||||||
|
int streamIndex = event.getStreamIndex();
|
||||||
|
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
|
||||||
|
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
|
||||||
|
streamCoder.setSampleRate( 44100 );
|
||||||
|
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
|
||||||
|
//streamCoder.setBitRate( 128 );
|
||||||
|
}
|
||||||
|
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
|
||||||
|
streamCoder.setWidth( width );
|
||||||
|
streamCoder.setHeight( height );
|
||||||
|
|
||||||
|
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
|
||||||
|
//streamCoder.setBitRate( 800000 );
|
||||||
|
/*
|
||||||
|
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
|
||||||
|
if (retval<0)
|
||||||
|
throw new RuntimeException("cound not cofigure coder from preset file");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
super.onAddStream(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoPicture(IVideoPictureEvent event) {
|
||||||
|
IVideoPicture pic = event.getPicture();
|
||||||
|
if (videoResampler == null) {
|
||||||
|
videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
|
||||||
|
}
|
||||||
|
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
|
||||||
|
videoResampler.resample(out, pic);
|
||||||
|
|
||||||
|
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
|
||||||
|
super.onVideoPicture(asc);
|
||||||
|
out.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioSamples(IAudioSamplesEvent event) {
|
||||||
|
IAudioSamples samples = event.getAudioSamples();
|
||||||
|
if (audioResampler == null) {
|
||||||
|
audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
|
||||||
|
}
|
||||||
|
if (event.getAudioSamples().getNumSamples() > 0) {
|
||||||
|
IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
|
||||||
|
audioResampler.resample(out, samples, samples.getNumSamples());
|
||||||
|
|
||||||
|
AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
|
||||||
|
super.onAudioSamples(asc);
|
||||||
|
out.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
199
src/zall/transcoder/ZalleryTranscoder.java
Executable file
199
src/zall/transcoder/ZalleryTranscoder.java
Executable file
|
|
@ -0,0 +1,199 @@
|
||||||
|
package zall.transcoder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.servlet.ServletConfig;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
|
||||||
|
import com.xuggle.mediatool.IMediaReader;
|
||||||
|
import com.xuggle.mediatool.IMediaWriter;
|
||||||
|
import com.xuggle.mediatool.MediaToolAdapter;
|
||||||
|
import com.xuggle.mediatool.ToolFactory;
|
||||||
|
import com.xuggle.mediatool.event.AudioSamplesEvent;
|
||||||
|
import com.xuggle.mediatool.event.IAddStreamEvent;
|
||||||
|
import com.xuggle.mediatool.event.IAudioSamplesEvent;
|
||||||
|
import com.xuggle.mediatool.event.IVideoPictureEvent;
|
||||||
|
import com.xuggle.mediatool.event.VideoPictureEvent;
|
||||||
|
import com.xuggle.xuggler.IAudioResampler;
|
||||||
|
import com.xuggle.xuggler.IAudioSamples;
|
||||||
|
import com.xuggle.xuggler.ICodec;
|
||||||
|
import com.xuggle.xuggler.IStreamCoder;
|
||||||
|
import com.xuggle.xuggler.IVideoPicture;
|
||||||
|
import com.xuggle.xuggler.IVideoResampler;
|
||||||
|
import com.xuggle.xuggler.video.ConverterFactory;
|
||||||
|
import com.xuggle.xuggler.video.IConverter;
|
||||||
|
|
||||||
|
import zall.Zallery;
|
||||||
|
import zall.bean.Media.Size;
|
||||||
|
import zall.bean.Video;
|
||||||
|
import zutil.StringUtil;
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.log.LogUtil;
|
||||||
|
|
||||||
|
|
||||||
|
public class ZalleryTranscoder extends HttpServlet{
|
||||||
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// Media Queue
|
||||||
|
private static Queue<Video> transcodingQueue;
|
||||||
|
private static TranscoderThread worker;
|
||||||
|
|
||||||
|
public void init( ServletConfig config ){
|
||||||
|
try{
|
||||||
|
transcodingQueue = new LinkedList<Video>();
|
||||||
|
worker = new TranscoderThread();
|
||||||
|
worker.start();
|
||||||
|
|
||||||
|
// get untranscoded videos
|
||||||
|
DBConnection db = null;
|
||||||
|
try {
|
||||||
|
db = Zallery.getDB();
|
||||||
|
List<Video> incomplete = Video.loadUntransoded( db );
|
||||||
|
synchronized (transcodingQueue) {
|
||||||
|
transcodingQueue.addAll( incomplete );
|
||||||
|
transcodingQueue.notify();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, null, e);
|
||||||
|
}finally{
|
||||||
|
if( db != null ) db.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e){
|
||||||
|
logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy( ){
|
||||||
|
worker.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Video getProcessingVideo(){
|
||||||
|
return worker.currentVideo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Queue<Video> getQueue(){
|
||||||
|
return transcodingQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a video to the transcoding queue
|
||||||
|
*
|
||||||
|
* @param video is the video to transcode
|
||||||
|
*/
|
||||||
|
public static void addVideo(Video video) {
|
||||||
|
if( transcodingQueue == null ){
|
||||||
|
logger.severe("ZalleryTranscoder not initialized!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( !transcodingQueue.contains(video) && worker.currentVideo != video ){
|
||||||
|
synchronized (transcodingQueue){
|
||||||
|
transcodingQueue.add( video );
|
||||||
|
transcodingQueue.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the class that is doing the actual work of transcoding videos
|
||||||
|
*
|
||||||
|
* @author Ziver
|
||||||
|
*/
|
||||||
|
private static class TranscoderThread extends Thread{
|
||||||
|
private boolean stop;
|
||||||
|
private long startTime;
|
||||||
|
private Video currentVideo;
|
||||||
|
|
||||||
|
|
||||||
|
public void run(){
|
||||||
|
logger.info("Transcoder thread started.");
|
||||||
|
try {
|
||||||
|
while( !stop ){
|
||||||
|
// Get video to transcode
|
||||||
|
while( !transcodingQueue.isEmpty() ){
|
||||||
|
currentVideo = transcodingQueue.poll();
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
logger.info("Starting transcoding video(id:"+currentVideo.getId()+")");
|
||||||
|
|
||||||
|
File originalFile = currentVideo.getFile( Size.ORIGINAL );
|
||||||
|
File mediumFile = currentVideo.getFile( Size.MEDIUM );
|
||||||
|
File smallFile = currentVideo.getFile( Size.SMALL );
|
||||||
|
|
||||||
|
///////////// Start Transcoding
|
||||||
|
// create a media reader
|
||||||
|
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() );
|
||||||
|
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
|
||||||
|
reader.addListener(new ProgressListener(reader));
|
||||||
|
|
||||||
|
VideoTranscoderListener converter = new VideoTranscoderListener(640, 360);
|
||||||
|
reader.addListener(converter);
|
||||||
|
|
||||||
|
// create a media writer
|
||||||
|
IMediaWriter writer = ToolFactory.makeWriter(mediumFile.getPath(), reader);
|
||||||
|
converter.addListener(writer);
|
||||||
|
|
||||||
|
// create a media viewer with stats enabled for debugging
|
||||||
|
// add a viewer to the reader, to see the decoded media
|
||||||
|
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
|
||||||
|
//reader.addListener(mediaViewer);
|
||||||
|
//writer.addListener(mediaViewer);
|
||||||
|
|
||||||
|
// read and decode packets from the source file and
|
||||||
|
// and dispatch decoded audio and video to the writer
|
||||||
|
while (reader.readPacket() == null);
|
||||||
|
|
||||||
|
// Incomplete transcoding
|
||||||
|
if( reader.isOpen() ){
|
||||||
|
logger.severe("Transcoding incomplete, removing incomplete files!");
|
||||||
|
reader.close();
|
||||||
|
mediumFile.delete();
|
||||||
|
smallFile.delete();
|
||||||
|
if( stop )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
logger.info("Done transcoding video(id:"+currentVideo.getId()+") time: "+StringUtil.formatTimeToString(System.currentTimeMillis()-startTime));
|
||||||
|
currentVideo.setTranscoded(true);
|
||||||
|
try{
|
||||||
|
DBConnection db = Zallery.getDB();
|
||||||
|
currentVideo.save(db);
|
||||||
|
db.close();
|
||||||
|
}catch(Exception e){
|
||||||
|
logger.log(Level.SEVERE, "Unable to save video bean!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentVideo = null;
|
||||||
|
}
|
||||||
|
// Wait for new video to transcode
|
||||||
|
synchronized (transcodingQueue) {
|
||||||
|
transcodingQueue.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Transcoding thread has stopped!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.SEVERE, "Transcoding thread has crashed!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void abort(){
|
||||||
|
stop = true;
|
||||||
|
synchronized (transcodingQueue) {
|
||||||
|
transcodingQueue.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
package zall.util;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import sun.net.smtp.SmtpClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplifies sending of a email
|
|
||||||
*
|
|
||||||
* @author Ziver
|
|
||||||
*/
|
|
||||||
public class Email {
|
|
||||||
public static enum ContentType{
|
|
||||||
PLAIN, HTML
|
|
||||||
}
|
|
||||||
private static final SimpleDateFormat dateFormatter =
|
|
||||||
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
|
|
||||||
private static String host = "localhost";
|
|
||||||
|
|
||||||
private String from;
|
|
||||||
private String niceFrom = null;
|
|
||||||
private String to;
|
|
||||||
private String replyTo = null;
|
|
||||||
private ContentType type = ContentType.PLAIN;
|
|
||||||
private String subject;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
public Email(String from, String to){
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setFrom(String f){
|
|
||||||
from = f;
|
|
||||||
}
|
|
||||||
public void setNiceFrom(String nf){
|
|
||||||
niceFrom = nf;
|
|
||||||
}
|
|
||||||
public void setReplyTo(String rpt){
|
|
||||||
replyTo = rpt;
|
|
||||||
}
|
|
||||||
public void setTo(String t){
|
|
||||||
to = t;
|
|
||||||
}
|
|
||||||
public void setContentType(ContentType t){
|
|
||||||
type = t;
|
|
||||||
}
|
|
||||||
public void setSubject(String s){
|
|
||||||
subject = s;
|
|
||||||
}
|
|
||||||
public void setMessage(String msg){
|
|
||||||
message = msg;
|
|
||||||
}
|
|
||||||
public static void setServer(String host){
|
|
||||||
Email.host = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void send() throws IOException{
|
|
||||||
if(from == null)
|
|
||||||
throw new IllegalArgumentException("From value missing!");
|
|
||||||
if(to == null)
|
|
||||||
throw new IllegalArgumentException("To value missing!");
|
|
||||||
|
|
||||||
SmtpClient smtp = new SmtpClient( host );
|
|
||||||
smtp.from(from);
|
|
||||||
smtp.to(to);
|
|
||||||
PrintStream msg = smtp.startMessage();
|
|
||||||
|
|
||||||
//************ Headers
|
|
||||||
msg.println("From: "+(niceFrom!=null ? "\""+niceFrom+"\"" : "")+" <"+from+">");
|
|
||||||
msg.println("Reply-To: <"+replyTo+">");
|
|
||||||
if( replyTo != null )
|
|
||||||
msg.println("Reply-To: <"+replyTo+">");
|
|
||||||
msg.println("To: " + to); // so mailers will display the To: address
|
|
||||||
msg.println("Subject: "+subject);
|
|
||||||
// Date
|
|
||||||
msg.println("Date: "+dateFormatter.format(new Date(System.currentTimeMillis())));
|
|
||||||
// Content type
|
|
||||||
switch( type ){
|
|
||||||
case HTML:
|
|
||||||
msg.println("Content-Type: text/html;"); break;
|
|
||||||
default:
|
|
||||||
msg.println("Content-Type: text/plain;"); break;
|
|
||||||
}
|
|
||||||
msg.println();
|
|
||||||
|
|
||||||
//*********** Mesasge
|
|
||||||
msg.println( message );
|
|
||||||
|
|
||||||
smtp.closeServer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
75
src/zall/util/ZalleryEmail.java
Executable file
75
src/zall/util/ZalleryEmail.java
Executable file
|
|
@ -0,0 +1,75 @@
|
||||||
|
package zall.util;
|
||||||
|
|
||||||
|
import zall.Zallery;
|
||||||
|
import zall.bean.User;
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.net.smtp.Email;
|
||||||
|
import zutil.net.smtp.SMTPClient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ZalleryEmail {
|
||||||
|
private static String host;
|
||||||
|
|
||||||
|
public static void setSMTPHost(String host){
|
||||||
|
ZalleryEmail.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendVerificationEmail(User user) throws IOException {
|
||||||
|
// Email
|
||||||
|
Email email = new Email();
|
||||||
|
email.setFrom("admin@koc.se", "Koc.se Admin");
|
||||||
|
email.setTo(user.getEmail());
|
||||||
|
email.setSubject("Registration at "+ Zallery.getWebsiteName());
|
||||||
|
email.setContentType(Email.ContentType.HTML);
|
||||||
|
email.setMessage("You receive this message because you have requested an account" +
|
||||||
|
"<br>at "+Zallery.getWebsiteName()+". Please click the link to verify your email address: " +
|
||||||
|
"<p><a href='"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"'>"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"</a>" +
|
||||||
|
"<p> You will have to wait for an admin to activate your account after you have verified your email.");
|
||||||
|
|
||||||
|
SMTPClient smtp = new SMTPClient(host);
|
||||||
|
smtp.send(email);
|
||||||
|
smtp.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendActivationEmail(User user) throws IOException {
|
||||||
|
Email email = new Email();
|
||||||
|
email.setFrom("admin@koc.se", "Koc.se Admin");
|
||||||
|
email.setTo(user.getEmail());
|
||||||
|
email.setSubject("Account activation at " + Zallery.getWebsiteName());
|
||||||
|
email.setContentType(Email.ContentType.HTML);
|
||||||
|
email.setMessage("Your account has now been activated by an admin. You can now login and use the site. " +
|
||||||
|
"<a href='" + Zallery.getWebsiteURL() + "'>" + Zallery.getWebsiteURL() + "</a>");
|
||||||
|
|
||||||
|
SMTPClient smtp = new SMTPClient(host);
|
||||||
|
smtp.send(email);
|
||||||
|
smtp.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendNewUserRegistrationToAdmin(User user, DBConnection db) throws SQLException, IOException{
|
||||||
|
// Email the admin about new user
|
||||||
|
Email email = new Email();
|
||||||
|
email.setFrom("admin@koc.se", "Koc.se Admin");
|
||||||
|
email.setSubject("New user activation request at "+Zallery.getWebsiteName());
|
||||||
|
email.setContentType(Email.ContentType.HTML);
|
||||||
|
email.setMessage("A new user has registered for an account at " +
|
||||||
|
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteName()+"</a>:" +
|
||||||
|
"<p>Email: <b>" + user.getEmail() + "</b>" +
|
||||||
|
"<br>Name: <b>" + user.getName() + "</b>"
|
||||||
|
);
|
||||||
|
|
||||||
|
SMTPClient smtp = new SMTPClient(host);
|
||||||
|
for(User admin : User.loadSuperUsers(db)){
|
||||||
|
if( admin.isEmailVerified() ){
|
||||||
|
email.setTo( admin.getEmail() );
|
||||||
|
smtp.send(email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
smtp.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue