You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by se...@apache.org on 2012/04/14 17:42:08 UTC

svn commit: r1326133 - in /incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app: data/flvrecord/converter/ data/flvrecord/listener/ data/flvrecord/listener/async/ remote/

Author: sebawagner
Date: Sat Apr 14 15:42:07 2012
New Revision: 1326133

URL: http://svn.apache.org/viewvc?rev=1326133&view=rev
Log:
OPENMEETINGS-165 Video freezes as soon as two people have audio/video turned on and you start to record the meeting => Convert FLV writers to act async

Added:
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamVideoListener.java
      - copied, changed from r1326094, incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamScreenListener.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamVideoWriter.java
Removed:
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/FLVDebugWriter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamScreenListener.java
Modified:
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/BaseConverter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/FlvRecorderConverter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/BaseStreamListener.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamAudioListener.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/BaseStreamWriter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamAudioWriter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/FLVRecorderService.java

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/BaseConverter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/BaseConverter.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/BaseConverter.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/BaseConverter.java Sat Apr 14 15:42:07 2012
@@ -157,10 +157,10 @@ public abstract class BaseConverter {
 			for (FlvRecordingMetaData flvRecordingMetaData : metaDataList) {
 				
 				if (flvRecordingMetaData.getStreamReaderThreadComplete() == null) {
-					throw new Exception("StreamReaderThreadComplete Bit is NULL, error in recording");
+					throw new IllegalStateException("StreamReaderThreadComplete Bit is NULL, error in recording");
 				}
 				
-				if (flvRecordingMetaData.getStreamReaderThreadComplete()) {
+				if (!flvRecordingMetaData.getStreamReaderThreadComplete()) {
 					
 					log.debug("### meta Stream not yet written to disk" + flvRecordingMetaData.getFlvRecordingMetaDataId());
 					boolean doStop = true;
@@ -168,8 +168,6 @@ public abstract class BaseConverter {
 						
 						log.debug("### Stream not yet written Thread Sleep - " );
 						
-						Thread.sleep(100L);
-						
 						flvRecordingMetaData = flvRecordingMetaDataDaoImpl.getFlvRecordingMetaDataById(flvRecordingMetaData.getFlvRecordingMetaDataId());
 						
 						if (flvRecordingMetaData.getStreamReaderThreadComplete()) {
@@ -177,8 +175,8 @@ public abstract class BaseConverter {
 							doStop = false;
 						}
 						
+						Thread.sleep(100L);
 					}
-					
 				}
 	
 				String inputFlv = streamFolderName
@@ -191,6 +189,8 @@ public abstract class BaseConverter {
 				flvRecordingMetaData.setWavAudioData(hashFileName);
 	
 				File inputFlvFile = new File(inputFlv);
+				
+				log.debug("FLV File Name: {} Length: {} ",inputFlvFile.getName(), inputFlvFile.length());
 	
 				if (inputFlvFile.exists()) {
 	

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/FlvRecorderConverter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/FlvRecorderConverter.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/FlvRecorderConverter.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/converter/FlvRecorderConverter.java Sat Apr 14 15:42:07 2012
@@ -82,6 +82,31 @@ public class FlvRecorderConverter extend
 			FlvRecordingMetaData flvRecordingMetaDataOfScreen = this.flvRecordingMetaDataDaoImpl
 					.getFlvRecordingMetaDataScreenFlvByRecording(flvRecording
 							.getFlvRecordingId());
+			
+			if (flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete() == null) {
+				throw new Exception("StreamReaderThreadComplete Bit is NULL, error in recording");
+			}
+			
+			if (!flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete()) {
+				
+				log.debug("### meta ScreenStream not yet written to disk" + flvRecordingMetaDataOfScreen.getFlvRecordingMetaDataId());
+				boolean doStop = true;
+				while(doStop) {
+					
+					log.debug("### Stream not yet written Thread Sleep - " );
+					
+					Thread.sleep(100L);
+					
+					flvRecordingMetaDataOfScreen = flvRecordingMetaDataDaoImpl.getFlvRecordingMetaDataById(flvRecordingMetaDataOfScreen.getFlvRecordingMetaDataId());
+					
+					if (flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete()) {
+						log.debug("### Screen Stream now written Thread continue - " );
+						doStop = false;
+					}
+				}
+			}
+			
+			
 			String hashFileFullName = flvRecordingMetaDataOfScreen
 					.getStreamName() + "_FINAL_WAVE.wav";
 			String outputFullWav = streamFolderName + hashFileFullName;

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/BaseStreamListener.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/BaseStreamListener.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/BaseStreamListener.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/BaseStreamListener.java Sat Apr 14 15:42:07 2012
@@ -18,98 +18,10 @@
  */
 package org.openmeetings.app.data.flvrecord.listener;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.openmeetings.app.persistence.beans.flvrecord.FlvRecordingMetaDelta;
-import org.red5.io.IStreamableFile;
-import org.red5.io.IStreamableFileFactory;
-import org.red5.io.IStreamableFileService;
-import org.red5.io.ITagWriter;
-import org.red5.io.StreamableFileFactory;
-import org.red5.server.api.IScope;
-import org.red5.server.api.ScopeUtils;
-import org.red5.server.api.stream.IBroadcastStream;
 import org.red5.server.api.stream.IStreamListener;
-import org.red5.server.api.stream.IStreamPacket;
 
 public abstract class BaseStreamListener implements IStreamListener {
 	
-	protected ITagWriter writer = null;
-	
-	protected Long flvRecordingMetaDataId = null;
-	protected List<FlvRecordingMetaDelta> flvRecordingMetaDeltas;
-	
-	protected Date startedSessionTimeDate = null;
-	
-	protected File file;
-	
-	protected IScope scope;
-	
-	protected boolean isClosed = false;
-
-	protected boolean isScreenData = false;
-	
-	protected Long offset = 0L;
-	
-	protected String streamName = "";
-
-	protected boolean isInterview;
-	
-	public BaseStreamListener(String streamName, IScope scope, 
-			Long flvRecordingMetaDataId, boolean isScreenData,
-			boolean isInterview) {
-		super();
-		this.startedSessionTimeDate = new Date();
-		this.isScreenData  = isScreenData;
-		this.streamName  = streamName;
-		this.flvRecordingMetaDataId = flvRecordingMetaDataId;
-		this.flvRecordingMetaDeltas = new LinkedList<FlvRecordingMetaDelta>();
-		this.scope = scope;
-		this.isInterview = isInterview;
-	}
-
-	public Long getFlvRecordingMetaDataId() {
-		return flvRecordingMetaDataId;
-	}	
-	
 	public abstract void closeStream();
-	
-	/**
-     * Initialization
-     *
-     * @throws IOException          I/O exception
-     */
-    protected void init() throws IOException {
-
-		IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils
-				.getScopeService(this.scope, IStreamableFileFactory.class,
-						StreamableFileFactory.class);
-		
-		File folder = file.getParentFile();
-
-		if (!folder.exists()) {
-			if (!folder.mkdirs()) {
-				throw new IOException("Could not create parent folder");
-			}
-		}
-
-		if (!this.file.isFile()) {
-
-			// Maybe the (previously existing) file has been deleted
-			this.file.createNewFile();
-
-		} else if (!file.canWrite()) {
-			throw new IOException("The file is read-only");
-		}
-
-		IStreamableFileService service = factory.getService(this.file);
-		IStreamableFile flv = service.getStreamableFile(this.file);
-		this.writer = flv.getWriter();
-
-	}
 
 }

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamAudioListener.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamAudioListener.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamAudioListener.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamAudioListener.java Sat Apr 14 15:42:07 2012
@@ -37,15 +37,12 @@ public class StreamAudioListener extends
 			StreamAudioListener.class, OpenmeetingsVariables.webAppRootKey);
 
 	private final StreamAudioWriter streamAudioWriter;
-
+	
 	public StreamAudioListener(String streamName, IScope scope,
 			Long flvRecordingMetaDataId, boolean isScreenData,
 			boolean isInterview,
 			FlvRecordingMetaDeltaDaoImpl flvRecordingMetaDeltaDao,
 			FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao) {
-		// Auto-generated method stub
-		super(streamName, scope, flvRecordingMetaDataId, isScreenData,
-				isInterview);
 		streamAudioWriter = new StreamAudioWriter(streamName, scope,
 				flvRecordingMetaDataId, isScreenData, isInterview,
 				flvRecordingMetaDeltaDao, flvRecordingMetaDataDao);

Copied: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamVideoListener.java (from r1326094, incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamScreenListener.java)
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamVideoListener.java?p2=incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamVideoListener.java&p1=incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamScreenListener.java&r1=1326094&r2=1326133&rev=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamScreenListener.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/StreamVideoListener.java Sat Apr 14 15:42:07 2012
@@ -18,144 +18,45 @@
  */
 package org.openmeetings.app.data.flvrecord.listener;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Date;
 
-import org.apache.mina.core.buffer.IoBuffer;
 import org.openmeetings.app.OpenmeetingsVariables;
 import org.openmeetings.app.data.flvrecord.FlvRecordingMetaDataDaoImpl;
-import org.openmeetings.app.persistence.beans.flvrecord.FlvRecordingMetaData;
-import org.openmeetings.app.remote.red5.ScopeApplicationAdapter;
-import org.red5.io.ITag;
-import org.red5.io.flv.impl.Tag;
+import org.openmeetings.app.data.flvrecord.listener.async.CachedEvent;
+import org.openmeetings.app.data.flvrecord.listener.async.StreamVideoWriter;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.api.IScope;
 import org.red5.server.api.stream.IBroadcastStream;
 import org.red5.server.api.stream.IStreamPacket;
 import org.slf4j.Logger;
 
-public class StreamScreenListener extends BaseStreamListener {
-
-	private int startTimeStamp = -1;
-
-	private Date startedSessionScreenTimeDate = null;
-
-	private long initialDelta = 0;
-
+public class StreamVideoListener extends BaseStreamListener {
+	
 	private static final Logger log = Red5LoggerFactory.getLogger(
-			StreamScreenListener.class, OpenmeetingsVariables.webAppRootKey);
+			StreamVideoListener.class, OpenmeetingsVariables.webAppRootKey);
 
-	// Autowire is not possible
-	private final FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao;
+	private final StreamVideoWriter streamVideoWriter;
 
-	public StreamScreenListener(String streamName, IScope scope,
+	public StreamVideoListener(String streamName, IScope scope,
 			Long flvRecordingMetaDataId, boolean isScreenData,
 			boolean isInterview,
 			FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao) {
-		super(streamName, scope, flvRecordingMetaDataId, isScreenData,
-				isInterview);
-		// Auto-generated constructor stub
-		this.flvRecordingMetaDataDao = flvRecordingMetaDataDao;
+		streamVideoWriter = new StreamVideoWriter(streamName, scope, flvRecordingMetaDataId, isScreenData,
+				isInterview, flvRecordingMetaDataDao);
 	}
 
 	public void packetReceived(IBroadcastStream broadcastStream,
 			IStreamPacket streampacket) {
 		try {
 
-			// We only are concerned about video at this moment
-			// if (streampacket.getDataType() == 9) {
-
-			if (this.startedSessionScreenTimeDate == null) {
-
-				this.startedSessionScreenTimeDate = new Date();
-
-				// Calculate the delta between the initial start and the first
-				// packet data
-
-				this.initialDelta = this.startedSessionScreenTimeDate.getTime()
-						- this.startedSessionTimeDate.getTime();
-
-				// This is important for the Interview Post Processing to get
-				// the time between starting the stream and the actual Access to
-				// the
-				// webcam by the Flash Security Dialog
-				flvRecordingMetaDataDao.updateFlvRecordingMetaDataInitialGap(
-						flvRecordingMetaDataId, this.initialDelta);
-
-			}
-
-			if (this.isClosed) {
-				// Already closed this One
-				return;
-			}
-
-			if (streampacket.getTimestamp() <= 0) {
-				log.warn("Negative TimeStamp");
-				return;
-			}
-
-			IoBuffer data = streampacket.getData().asReadOnlyBuffer();
-
-			if (data.limit() == 0) {
-				return;
-			}
-
-			if (startTimeStamp == -1) {
-
-				// That will be not bigger then long value
-				startTimeStamp = streampacket.getTimestamp();
-			}
-
-			if (writer == null) {
-
-				File folder = new File(ScopeApplicationAdapter.webAppPath
-						+ File.separatorChar + "streams" + File.separatorChar
-						+ this.scope.getName());
+			CachedEvent cachedEvent = new CachedEvent();
+			cachedEvent.setData(streampacket.getData().duplicate());
+			cachedEvent.setDataType(streampacket.getDataType());
+			cachedEvent.setTimestamp(streampacket.getTimestamp());
+			cachedEvent.setCurrentTime(new Date());
 
-				if (!folder.exists()) {
-					folder.mkdir();
-				}
+			streamVideoWriter.append(cachedEvent);
 
-				String flvName = ScopeApplicationAdapter.webAppPath
-						+ File.separatorChar + "streams" + File.separatorChar
-						+ this.scope.getName() + File.separatorChar
-						+ this.streamName + ".flv";
-
-				file = new File(flvName);
-				init();
-			}
-
-			int timeStamp = streampacket.getTimestamp();
-
-			timeStamp -= startTimeStamp;
-
-			ITag tag = new Tag();
-			tag.setDataType(streampacket.getDataType());
-
-			// log.debug("data.limit() :: "+data.limit());
-			tag.setBodySize(data.limit());
-			tag.setTimestamp(timeStamp);
-			tag.setBody(data);
-
-			if (this.isInterview) {
-				if (timeStamp <= 500) {
-					// We will cut the first 0.5 seconds
-					// The First seconds seem to break the Recording Video often
-					return;
-				}
-			}
-			
-			if (this.isClosed) {
-				throw new Exception("Stream was already closed");
-			}
-
-			writer.writeTag(tag);
-
-			// }
-
-		} catch (IOException e) {
-			log.error("[packetReceived]", e);
 		} catch (Exception e) {
 			log.error("[packetReceived]", e);
 		}
@@ -163,30 +64,7 @@ public class StreamScreenListener extend
 
 	@Override
 	public void closeStream() {
-		if (writer != null && !this.isClosed) {
-			try {
-
-				// Add Delta in the beginning, this Delta is the Gap between the
-				// device chosen and when the User hits the button in the Flash
-				// Security Warning
-				FlvRecordingMetaData flvRecordingMetaData = flvRecordingMetaDataDao
-						.getFlvRecordingMetaDataById(this.flvRecordingMetaDataId);
-
-				flvRecordingMetaData.setRecordStart(new Date(
-						flvRecordingMetaData.getRecordStart().getTime()
-								+ this.initialDelta));
-
-				flvRecordingMetaDataDao
-						.updateFlvRecordingMetaData(flvRecordingMetaData);
-
-				writer.close();
-
-				this.isClosed = true;
-
-			} catch (Exception err) {
-				log.error("[closeStream]", err);
-			}
-		}
+		streamVideoWriter.stop();
 	}
-
+	
 }

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/BaseStreamWriter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/BaseStreamWriter.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/BaseStreamWriter.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/BaseStreamWriter.java Sat Apr 14 15:42:07 2012
@@ -3,16 +3,11 @@ package org.openmeetings.app.data.flvrec
 import java.io.File;
 import java.io.IOException;
 import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 import org.openmeetings.app.OpenmeetingsVariables;
-import org.openmeetings.app.data.flvrecord.FlvRecordingMetaDataDaoImpl;
-import org.openmeetings.app.data.flvrecord.FlvRecordingMetaDeltaDaoImpl;
-import org.openmeetings.app.persistence.beans.flvrecord.FlvRecordingMetaDelta;
 import org.openmeetings.app.remote.red5.ScopeApplicationAdapter;
 import org.red5.io.IStreamableFile;
 import org.red5.io.IStreamableFileFactory;
@@ -39,7 +34,6 @@ public abstract class BaseStreamWriter i
 	protected ITagWriter writer = null;
 
 	protected Long flvRecordingMetaDataId = null;
-	protected List<FlvRecordingMetaDelta> flvRecordingMetaDeltas;
 
 	protected Date startedSessionTimeDate = null;
 
@@ -55,24 +49,15 @@ public abstract class BaseStreamWriter i
 
 	private final BlockingQueue<CachedEvent> queue = new LinkedBlockingQueue<CachedEvent>();
 
-	// Autowire is not possible
-	protected final FlvRecordingMetaDeltaDaoImpl flvRecordingMetaDeltaDao;
-	protected final FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao;
-
 	public BaseStreamWriter(String streamName, IScope scope,
 			Long flvRecordingMetaDataId, boolean isScreenData,
-			boolean isInterview,
-			FlvRecordingMetaDeltaDaoImpl flvRecordingMetaDeltaDao,
-			FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao) {
+			boolean isInterview) {
 		this.startedSessionTimeDate = new Date();
 		this.isScreenData = isScreenData;
 		this.streamName = streamName;
 		this.flvRecordingMetaDataId = flvRecordingMetaDataId;
-		this.flvRecordingMetaDeltas = new LinkedList<FlvRecordingMetaDelta>();
 		this.scope = scope;
 		this.isInterview = isInterview;
-		this.flvRecordingMetaDeltaDao = flvRecordingMetaDeltaDao;
-		this.flvRecordingMetaDataDao = flvRecordingMetaDataDao;
 		try {
 			init();
 		} catch (IOException ex) {

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamAudioWriter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamAudioWriter.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamAudioWriter.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamAudioWriter.java Sat Apr 14 15:42:07 2012
@@ -33,13 +33,19 @@ public class StreamAudioWriter extends B
 
 	private long byteCount = 0;
 	
+	// Autowire is not possible
+	protected final FlvRecordingMetaDeltaDaoImpl flvRecordingMetaDeltaDao;
+	protected final FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao;
+	
 	public StreamAudioWriter(String streamName, IScope scope,
 			Long flvRecordingMetaDataId, boolean isScreenData,
 			boolean isInterview,
 			FlvRecordingMetaDeltaDaoImpl flvRecordingMetaDeltaDao,
 			FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao) {
-		super(streamName, scope, flvRecordingMetaDataId, isScreenData, isInterview,
-				flvRecordingMetaDeltaDao, flvRecordingMetaDataDao);
+		super(streamName, scope, flvRecordingMetaDataId, isScreenData, isInterview);
+		
+		this.flvRecordingMetaDeltaDao = flvRecordingMetaDeltaDao;
+		this.flvRecordingMetaDataDao = flvRecordingMetaDataDao;
 		
 		FlvRecordingMetaData flvRecordingMetaData = flvRecordingMetaDataDao.
 								getFlvRecordingMetaDataById(flvRecordingMetaDataId);
@@ -112,8 +118,6 @@ public class StreamAudioWriter extends B
 					flvRecordingMetaDelta.setDeltaTimeStamp(deltaTimeStamp);
 					flvRecordingMetaDelta.setStartTimeStamp(startTimeStamp);
 
-					this.flvRecordingMetaDeltas.add(flvRecordingMetaDelta);
-
 					flvRecordingMetaDeltaDao
 							.addFlvRecordingMetaDelta(flvRecordingMetaDelta);
 
@@ -179,8 +183,6 @@ public class StreamAudioWriter extends B
 					flvRecordingMetaDelta.setDeltaTimeStamp(deltaTimeStamp);
 					flvRecordingMetaDelta.setStartTimeStamp(startTimeStamp);
 
-					this.flvRecordingMetaDeltas.add(flvRecordingMetaDelta);
-
 					flvRecordingMetaDeltaDao
 							.addFlvRecordingMetaDelta(flvRecordingMetaDelta);
 
@@ -242,8 +244,6 @@ public class StreamAudioWriter extends B
 			flvRecordingMetaDelta.setStartTime(this.startedSessionTimeDate);
 			flvRecordingMetaDelta.setCurrentTime(new Date());
 
-			this.flvRecordingMetaDeltas.add(flvRecordingMetaDelta);
-
 			flvRecordingMetaDeltaDao
 					.addFlvRecordingMetaDelta(flvRecordingMetaDelta);
 			

Added: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamVideoWriter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamVideoWriter.java?rev=1326133&view=auto
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamVideoWriter.java (added)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/data/flvrecord/listener/async/StreamVideoWriter.java Sat Apr 14 15:42:07 2012
@@ -0,0 +1,144 @@
+package org.openmeetings.app.data.flvrecord.listener.async;
+
+import java.io.IOException;
+import java.util.Date;
+
+import org.apache.mina.core.buffer.IoBuffer;
+import org.openmeetings.app.OpenmeetingsVariables;
+import org.openmeetings.app.data.flvrecord.FlvRecordingMetaDataDaoImpl;
+import org.openmeetings.app.persistence.beans.flvrecord.FlvRecordingMetaData;
+import org.red5.io.ITag;
+import org.red5.io.flv.impl.Tag;
+import org.red5.logging.Red5LoggerFactory;
+import org.red5.server.api.IScope;
+import org.slf4j.Logger;
+
+public class StreamVideoWriter extends BaseStreamWriter {
+	
+	private int startTimeStamp = -1;
+
+	private Date startedSessionScreenTimeDate = null;
+
+	private long initialDelta = 0;
+	
+	private final FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao;
+
+	private static final Logger log = Red5LoggerFactory.getLogger(
+			StreamVideoWriter.class, OpenmeetingsVariables.webAppRootKey);
+	
+	public StreamVideoWriter(String streamName, IScope scope,
+			Long flvRecordingMetaDataId, boolean isScreenData,
+			boolean isInterview,
+			FlvRecordingMetaDataDaoImpl flvRecordingMetaDataDao) {
+		
+		super(streamName, scope, flvRecordingMetaDataId, isScreenData, isInterview);
+		
+		this.flvRecordingMetaDataDao = flvRecordingMetaDataDao;
+		
+		FlvRecordingMetaData flvRecordingMetaData = flvRecordingMetaDataDao.
+				getFlvRecordingMetaDataById(flvRecordingMetaDataId);
+		flvRecordingMetaData.setStreamReaderThreadComplete(false);
+		flvRecordingMetaDataDao.updateFlvRecordingMetaData(flvRecordingMetaData);
+	}
+	
+	@Override
+	public void packetReceived(CachedEvent streampacket) {
+		try {
+
+			// We only are concerned about video at this moment
+			// if (streampacket.getDataType() == 9) {
+			
+			int timeStamp = streampacket.getTimestamp();
+			Date virtualTime = streampacket.getCurrentTime();
+
+			if (this.startedSessionScreenTimeDate == null) {
+
+				this.startedSessionScreenTimeDate = virtualTime;
+
+				// Calculate the delta between the initial start and the first
+				// packet data
+
+				this.initialDelta = this.startedSessionScreenTimeDate.getTime()
+						- this.startedSessionTimeDate.getTime();
+
+				// This is important for the Interview Post Processing to get
+				// the time between starting the stream and the actual Access to
+				// the
+				// webcam by the Flash Security Dialog
+				flvRecordingMetaDataDao.updateFlvRecordingMetaDataInitialGap(
+						flvRecordingMetaDataId, this.initialDelta);
+
+			}
+
+			if (streampacket.getTimestamp() <= 0) {
+				log.warn("Negative TimeStamp");
+				return;
+			}
+
+			IoBuffer data = streampacket.getData().asReadOnlyBuffer();
+
+			if (data.limit() == 0) {
+				return;
+			}
+
+			if (startTimeStamp == -1) {
+				// That will be not bigger then long value
+				startTimeStamp = streampacket.getTimestamp();
+			}
+
+			timeStamp -= startTimeStamp;
+
+			ITag tag = new Tag();
+			tag.setDataType(streampacket.getDataType());
+
+			// log.debug("data.limit() :: "+data.limit());
+			tag.setBodySize(data.limit());
+			tag.setTimestamp(timeStamp);
+			tag.setBody(data);
+
+			if (this.isInterview) {
+				if (timeStamp <= 500) {
+					// We will cut the first 0.5 seconds
+					// The First seconds seem to break the Recording Video often
+					return;
+				}
+			}
+			
+			writer.writeTag(tag);
+
+		} catch (IOException e) {
+			log.error("[packetReceived]", e);
+		} catch (Exception e) {
+			log.error("[packetReceived]", e);
+		}
+	}
+
+	@Override
+	public void closeStream() {
+		try {
+			
+			writer.close();
+
+			// Add Delta in the beginning, this Delta is the Gap between the
+			// device chosen and when the User hits the button in the Flash
+			// Security Warning
+			FlvRecordingMetaData flvRecordingMetaData = flvRecordingMetaDataDao
+					.getFlvRecordingMetaDataById(this.flvRecordingMetaDataId);
+
+			flvRecordingMetaData.setRecordStart(new Date(
+					flvRecordingMetaData.getRecordStart().getTime()
+							+ this.initialDelta));
+			
+			flvRecordingMetaData.setStreamReaderThreadComplete(true);
+			
+			flvRecordingMetaDataDao
+					.updateFlvRecordingMetaData(flvRecordingMetaData);
+			
+			
+
+		} catch (Exception err) {
+			log.error("[closeStream]", err);
+		}
+	}
+
+}

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/FLVRecorderService.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/FLVRecorderService.java?rev=1326133&r1=1326132&r2=1326133&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/FLVRecorderService.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/FLVRecorderService.java Sat Apr 14 15:42:07 2012
@@ -42,7 +42,7 @@ import org.openmeetings.app.data.flvreco
 import org.openmeetings.app.data.flvrecord.converter.FlvRecorderConverterTask;
 import org.openmeetings.app.data.flvrecord.listener.BaseStreamListener;
 import org.openmeetings.app.data.flvrecord.listener.StreamAudioListener;
-import org.openmeetings.app.data.flvrecord.listener.StreamScreenListener;
+import org.openmeetings.app.data.flvrecord.listener.StreamVideoListener;
 import org.openmeetings.app.data.user.Usermanagement;
 import org.openmeetings.app.data.user.dao.UsersDaoImpl;
 import org.openmeetings.app.persistence.beans.flvrecord.FlvRecording;
@@ -324,7 +324,7 @@ public class FLVRecorderService implemen
 			// Save the stream to disk.
 			if (isScreenData) {
 				
-				StreamScreenListener streamScreenListener = new StreamScreenListener(streamName,
+				StreamVideoListener streamScreenListener = new StreamVideoListener(streamName,
 																		conn.getScope(), flvRecordingMetaDataId, isScreenData,
 																		isInterview, flvRecordingMetaDataDao);
 				
@@ -343,7 +343,7 @@ public class FLVRecorderService implemen
 
 				if (isInterview) {
 					
-					StreamScreenListener streamScreenListener = new StreamScreenListener("AV_"
+					StreamVideoListener streamScreenListener = new StreamVideoListener("AV_"
 																		+ streamName, conn.getScope(),
 																		flvRecordingMetaDataId, isScreenData, isInterview,
 																		flvRecordingMetaDataDao);