You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2013/12/01 17:37:09 UTC
svn commit: r1546823 - in /openmeetings:
branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/
branches/2.x/src/org/apache/openmeetings/screen/webstart/
trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/...
Author: solomax
Date: Sun Dec 1 16:37:08 2013
New Revision: 1546823
URL: http://svn.apache.org/r1546823
Log:
[OPENMEETINGS-556] Screen share recording is tested and fixed to work as expected
Modified:
openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java
openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java
openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java
openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/CaptureScreen.java
openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java
openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java
openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java
openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java
openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java
Modified: openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java (original)
+++ openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java Sun Dec 1 16:37:08 2013
@@ -18,6 +18,8 @@
*/
package org.apache.openmeetings.data.flvrecord.listener.async;
+import static org.apache.openmeetings.OpenmeetingsVariables.webAppRootKey;
+
import java.io.File;
import java.io.IOException;
import java.util.Date;
@@ -25,7 +27,6 @@ import java.util.concurrent.BlockingQueu
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import static org.apache.openmeetings.OpenmeetingsVariables.webAppRootKey;
import org.apache.openmeetings.utils.OmFileHelper;
import org.red5.io.IStreamableFile;
import org.red5.io.IStreamableFileFactory;
@@ -118,7 +119,6 @@ public abstract class BaseStreamWriter i
try {
CachedEvent item = queue.poll(100, TimeUnit.MICROSECONDS);
if (item != null) {
-
if (dostopping) {
log.debug("Recording stopped but still packets to write to file!");
}
Modified: openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java (original)
+++ openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java Sun Dec 1 16:37:08 2013
@@ -77,10 +77,12 @@ public class StreamAudioWriter extends B
}
if (isInterview && startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) {
//skip until keyframe
+ log.trace("no KEYFRAME, skipping");
return;
}
IoBuffer data = streampacket.getData().asReadOnlyBuffer();
if (data.limit() == 0) {
+ log.trace("data.limit() == 0 ");
return;
}
@@ -169,6 +171,7 @@ public class StreamAudioWriter extends B
metaDeltaDao.addFlvRecordingMetaDelta(metaDelta);
}
+ log.trace("timeStamp :: " + timeStamp);
ITag tag = new Tag();
tag.setDataType(streampacket.getDataType());
Modified: openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java (original)
+++ openmeetings/branches/2.x/src/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java Sun Dec 1 16:37:08 2013
@@ -19,6 +19,7 @@
package org.apache.openmeetings.data.flvrecord.listener.async;
import static org.apache.openmeetings.OpenmeetingsVariables.webAppRootKey;
+import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME;
import java.util.Date;
@@ -52,6 +53,21 @@ public class StreamVideoWriter extends B
public void packetReceived(CachedEvent streampacket) {
try {
int timeStamp = streampacket.getTimestamp();
+ log.trace("incoming timeStamp :: " + timeStamp);
+ if (startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) {
+ //skip until keyframe
+ log.trace("no KEYFRAME, skipping ::" + streampacket.getFrameType());
+ return;
+ }
+ if (timeStamp <= 0) {
+ log.warn("Negative TimeStamp");
+ return;
+ }
+ IoBuffer data = streampacket.getData().asReadOnlyBuffer();
+ if (data.limit() == 0) {
+ log.trace("Data.limit() == 0");
+ return;
+ }
Date virtualTime = streampacket.getCurrentTime();
if (startedSessionScreenTimeDate == null) {
@@ -64,24 +80,14 @@ public class StreamVideoWriter extends B
metaDataDao.updateFlvRecordingMetaDataInitialGap(metaDataId, 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();
+ startTimeStamp = timeStamp;
}
timeStamp -= startTimeStamp;
+ log.trace("timeStamp :: " + timeStamp);
ITag tag = new Tag();
tag.setDataType(streampacket.getDataType());
Modified: openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/CaptureScreen.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/CaptureScreen.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/CaptureScreen.java (original)
+++ openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/CaptureScreen.java Sun Dec 1 16:37:08 2013
@@ -39,9 +39,10 @@ import org.slf4j.Logger;
final class CaptureScreen extends Thread {
private static final Logger log = getLogger(CaptureScreen.class);
+ private static final int NANO_MULTIPLIER = 1000 * 1000;
private CoreScreenShare core;
private int timeBetweenFrames;
- private volatile long timestamp = 0;
+ private volatile int timestamp = 0;
private volatile boolean active = true;
private IScreenEncoder se;
private IScreenShare client;
@@ -61,27 +62,26 @@ final class CaptureScreen extends Thread
this.host = host;
this.app = app;
this.port = port;
- int tbf;
switch (quality) {
case VeryHigh:
- tbf = 50;
+ timeBetweenFrames = 50;
break;
case High:
- tbf = 200;
+ timeBetweenFrames = 200;
break;
case Low:
case Medium:
default:
- tbf = 500;
+ timeBetweenFrames = 500;
break;
}
- timeBetweenFrames = tbf * 1000 * 1000; // nano time
se = new ScreenV1Encoder(); //NOTE get image should be changed in the code below
}
public void release() {
active = false;
+ timestamp = 0;
try {
scheduler.shutdownNow();
} catch (Exception e) {
@@ -120,18 +120,19 @@ final class CaptureScreen extends Thread
if (log.isTraceEnabled()) {
log.trace(String.format("Image was encoded in %s ms", System.currentTimeMillis() - start));
}
+ timestamp += timeBetweenFrames;
pushVideo(data, timestamp);
} catch (IOException e) {
log.error("Error while encoding/sending: ", e);
}
}
- }, 0, timeBetweenFrames, TimeUnit.NANOSECONDS);
+ }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
if (sendCursor) {
cursorScheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
core.sendCursorStatus();
}
- }, 0, timeBetweenFrames, TimeUnit.NANOSECONDS);
+ }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
}
} catch (Exception e) {
log.error("Error while running: ", e);
@@ -155,7 +156,7 @@ final class CaptureScreen extends Thread
}
*/
- private void pushVideo(byte[] video, long ts) throws IOException {
+ private void pushVideo(byte[] video, int ts) throws IOException {
if (startPublish) {
if (buffer == null || (buffer.capacity() < video.length && !buffer.isAutoExpand())) {
buffer = IoBuffer.allocate(video.length);
@@ -166,7 +167,8 @@ final class CaptureScreen extends Thread
buffer.put(video);
buffer.flip();
- RTMPMessage rtmpMsg = RTMPMessage.build(new VideoData(buffer), (int) ts);
+ log.trace("Video frame sent :: " + ts);
+ RTMPMessage rtmpMsg = RTMPMessage.build(new VideoData(buffer), ts);
client.publishStreamData(streamId, rtmpMsg);
}
}
Modified: openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java (original)
+++ openmeetings/branches/2.x/src/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java Sun Dec 1 16:37:08 2013
@@ -20,6 +20,9 @@ package org.apache.openmeetings.screen.w
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.resizeX;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.resizeY;
+import static org.red5.io.IoConstants.FLAG_CODEC_SCREEN;
+import static org.red5.io.IoConstants.FLAG_FRAMETYPE_INTERFRAME;
+import static org.red5.io.IoConstants.FLAG_FRAMETYPE_KEYFRAME;
import java.awt.Rectangle;
import java.awt.Robot;
@@ -67,7 +70,7 @@ public class ScreenV1Encoder extends Bas
boolean isKeyFrame = (frameCount++ % keyFrameIndex) == 0 || last == null || !screen.equals(this.screen);
//header
- ba.write(getTag(isKeyFrame ? 0x01 : 0x02, 0x03));
+ ba.write(getTag(isKeyFrame ? FLAG_FRAMETYPE_KEYFRAME : FLAG_FRAMETYPE_INTERFRAME, FLAG_CODEC_SCREEN));
writeShort(ba, imgArea.width + ((blockSize / 16 - 1) << 12));
writeShort(ba, imgArea.height + ((blockSize / 16 - 1) << 12));
Modified: openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java (original)
+++ openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/BaseStreamWriter.java Sun Dec 1 16:37:08 2013
@@ -119,7 +119,6 @@ public abstract class BaseStreamWriter i
try {
CachedEvent item = queue.poll(100, TimeUnit.MICROSECONDS);
if (item != null) {
-
if (dostopping) {
log.debug("Recording stopped but still packets to write to file!");
}
Modified: openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java (original)
+++ openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamAudioWriter.java Sun Dec 1 16:37:08 2013
@@ -77,10 +77,12 @@ public class StreamAudioWriter extends B
}
if (isInterview && startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) {
//skip until keyframe
+ log.trace("no KEYFRAME, skipping");
return;
}
IoBuffer data = streampacket.getData().asReadOnlyBuffer();
if (data.limit() == 0) {
+ log.trace("data.limit() == 0 ");
return;
}
@@ -90,7 +92,6 @@ public class StreamAudioWriter extends B
int timeStamp = streampacket.getTimestamp();
Date virtualTime = streampacket.getCurrentTime();
- // TODO seems like this copy/pasted block need to be refactored
if (startTimeStamp == -1) {
// Calculate the delta between the initial start and the first audio-packet data
@@ -170,6 +171,7 @@ public class StreamAudioWriter extends B
metaDeltaDao.addFlvRecordingMetaDelta(metaDelta);
}
+ log.trace("timeStamp :: " + timeStamp);
ITag tag = new Tag();
tag.setDataType(streampacket.getDataType());
Modified: openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java (original)
+++ openmeetings/trunk/singlewebapp/src/main/java/org/apache/openmeetings/data/flvrecord/listener/async/StreamVideoWriter.java Sun Dec 1 16:37:08 2013
@@ -19,6 +19,7 @@
package org.apache.openmeetings.data.flvrecord.listener.async;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.red5.server.net.rtmp.event.VideoData.FrameType.KEYFRAME;
import java.util.Date;
@@ -52,6 +53,21 @@ public class StreamVideoWriter extends B
public void packetReceived(CachedEvent streampacket) {
try {
int timeStamp = streampacket.getTimestamp();
+ log.trace("incoming timeStamp :: " + timeStamp);
+ if (startTimeStamp == -1 && KEYFRAME != streampacket.getFrameType()) {
+ //skip until keyframe
+ log.trace("no KEYFRAME, skipping ::" + streampacket.getFrameType());
+ return;
+ }
+ if (timeStamp <= 0) {
+ log.warn("Negative TimeStamp");
+ return;
+ }
+ IoBuffer data = streampacket.getData().asReadOnlyBuffer();
+ if (data.limit() == 0) {
+ log.trace("Data.limit() == 0");
+ return;
+ }
Date virtualTime = streampacket.getCurrentTime();
if (startedSessionScreenTimeDate == null) {
@@ -64,24 +80,14 @@ public class StreamVideoWriter extends B
metaDataDao.updateFlvRecordingMetaDataInitialGap(metaDataId, 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();
+ startTimeStamp = timeStamp;
}
timeStamp -= startTimeStamp;
+ log.trace("timeStamp :: " + timeStamp);
ITag tag = new Tag();
tag.setDataType(streampacket.getDataType());
Modified: openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java (original)
+++ openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/CaptureScreen.java Sun Dec 1 16:37:08 2013
@@ -39,9 +39,10 @@ import org.slf4j.Logger;
final class CaptureScreen extends Thread {
private static final Logger log = getLogger(CaptureScreen.class);
+ private static final int NANO_MULTIPLIER = 1000 * 1000;
private CoreScreenShare core;
private int timeBetweenFrames;
- private volatile long timestamp = 0;
+ private volatile int timestamp = 0;
private volatile boolean active = true;
private IScreenEncoder se;
private IScreenShare client;
@@ -61,27 +62,26 @@ final class CaptureScreen extends Thread
this.host = host;
this.app = app;
this.port = port;
- int tbf;
switch (quality) {
case VeryHigh:
- tbf = 50;
+ timeBetweenFrames = 50;
break;
case High:
- tbf = 200;
+ timeBetweenFrames = 200;
break;
case Low:
case Medium:
default:
- tbf = 500;
+ timeBetweenFrames = 500;
break;
}
- timeBetweenFrames = tbf * 1000 * 1000; // nano time
se = new ScreenV1Encoder(); //NOTE get image should be changed in the code below
}
public void release() {
active = false;
+ timestamp = 0;
try {
scheduler.shutdownNow();
} catch (Exception e) {
@@ -120,18 +120,19 @@ final class CaptureScreen extends Thread
if (log.isTraceEnabled()) {
log.trace(String.format("Image was encoded in %s ms", System.currentTimeMillis() - start));
}
+ timestamp += timeBetweenFrames;
pushVideo(data, timestamp);
} catch (IOException e) {
log.error("Error while encoding/sending: ", e);
}
}
- }, 0, timeBetweenFrames, TimeUnit.NANOSECONDS);
+ }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
if (sendCursor) {
cursorScheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
core.sendCursorStatus();
}
- }, 0, timeBetweenFrames, TimeUnit.NANOSECONDS);
+ }, 0, timeBetweenFrames * NANO_MULTIPLIER, TimeUnit.NANOSECONDS);
}
} catch (Exception e) {
log.error("Error while running: ", e);
@@ -155,7 +156,7 @@ final class CaptureScreen extends Thread
}
*/
- private void pushVideo(byte[] video, long ts) throws IOException {
+ private void pushVideo(byte[] video, int ts) throws IOException {
if (startPublish) {
if (buffer == null || (buffer.capacity() < video.length && !buffer.isAutoExpand())) {
buffer = IoBuffer.allocate(video.length);
@@ -166,7 +167,8 @@ final class CaptureScreen extends Thread
buffer.put(video);
buffer.flip();
- RTMPMessage rtmpMsg = RTMPMessage.build(new VideoData(buffer), (int) ts);
+ log.trace("Video frame sent :: " + ts);
+ RTMPMessage rtmpMsg = RTMPMessage.build(new VideoData(buffer), ts);
client.publishStreamData(streamId, rtmpMsg);
}
}
Modified: openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java?rev=1546823&r1=1546822&r2=1546823&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java (original)
+++ openmeetings/trunk/singlewebapp/src/screenshare/java/org/apache/openmeetings/screen/webstart/ScreenV1Encoder.java Sun Dec 1 16:37:08 2013
@@ -20,6 +20,9 @@ package org.apache.openmeetings.screen.w
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.resizeX;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.resizeY;
+import static org.red5.io.IoConstants.FLAG_CODEC_SCREEN;
+import static org.red5.io.IoConstants.FLAG_FRAMETYPE_INTERFRAME;
+import static org.red5.io.IoConstants.FLAG_FRAMETYPE_KEYFRAME;
import java.awt.Rectangle;
import java.awt.Robot;
@@ -67,7 +70,7 @@ public class ScreenV1Encoder extends Bas
boolean isKeyFrame = (frameCount++ % keyFrameIndex) == 0 || last == null || !screen.equals(this.screen);
//header
- ba.write(getTag(isKeyFrame ? 0x01 : 0x02, 0x03));
+ ba.write(getTag(isKeyFrame ? FLAG_FRAMETYPE_KEYFRAME : FLAG_FRAMETYPE_INTERFRAME, FLAG_CODEC_SCREEN));
writeShort(ba, imgArea.width + ((blockSize / 16 - 1) << 12));
writeShort(ba, imgArea.height + ((blockSize / 16 - 1) << 12));