[osflash] Changing destination files in ClientBroadcastStream
Ryo Neyama
neyama at utagoe.com
Mon Sep 10 07:29:50 PDT 2007
Hi Chris,
Thank you for pointing out the correct mailing lists.
I'll post future emails on Red5 there.
I created a ticket on Jira.
Thanks,
-----------------------------------------
Ryo Neyama
Utagoe Inc.
email: neyama <at> utagoe.com
Tel: 03-3461-1118 / Fax: 03-3461-1119
http://www.utagoe.com/
http://channel.is/
-----------------------------------------
From: "Chris Allen" <mrchrisallen at gmail.com>
Subject: Re: [osflash] Changing destination files in ClientBroadcastStream
Date: Mon, 10 Sep 2007 14:43:51 -0400
> Hey Ryo,
>
> First of all, thanks for submitting a patch and for your kind words about
> Red5.
>
> We have a dedicated mailing list for Red5 here:
> http://osflash.org/mailman/listinfo/red5_osflash.org<http://osflash.org/mailman/listinfo/osflash_osflash.org>Please
> sign up for that and send future Red5 emails there. This list that
> you sent to is for general Open Source Flash topics.
>
> As for the patch, could you open a ticket on Jira (http://jira.red5.org) and
> submit it through there? This way it won't get lost.
>
> Thanks again!
>
> -Chris
>
> On 9/10/07, Ryo Neyama <neyama at utagoe.com> wrote:
> >
> > Hi,
> >
> > I'm a user of Red5. Thank you very much for providing the great open
> > source software.
> >
> > I'm using org.red5.server.stream.ClientBroadcastStream to record video
> > stream into flv files.
> >
> > I expected that calling ClientBroadcastStream#saveAs(name, isAppend)
> > multiple times allows me to change the file without any
> > frame-overwrapping and any frame-loss.
> >
> > However, current SVN trunk and v0.6.2 do not behave as I expected. By
> > calling saveAs() twice (with different file names), two files are
> > created and both files just keep growing.
> >
> > Calling stopRecording() before second saveAs() works. However, some
> > flames seem to be lost. This seems to be due to unsubscribing from
> > the pipe by stopRecording() and skipping some frames before the next
> > keyframe.
> >
> > Subscribing new FileConsumer followed by unsubscribing the original
> > FileConsumer results in overwrapping some frames among files.
> >
> > After some trial and error, I made some changes in the following
> > source code in SVN trunk so that I can change files without any
> > frame-overwrapping and any frame-loss. The new code with my patch
> > changes files at the next keyframe.
> >
> > org.red5.server.stream.ClientBroadcastStream
> > org.red5.server.stream.consumer.FileConsumer
> >
> > I think this patch might be useful for other users too. So, I'm
> > wondering if this patch could be incorporated into the main stream of
> > Red5. Any comments and helps will be appreciated.
> >
> > Best regards,
> > -----------------------------------------
> > Ryo Neyama
> > Utagoe Inc.
> > email: neyama at utagoe.com
> > Tel: 03-3461-1118 / Fax: 03-3461-1119
> >
> > http://www.utagoe.com/
> > http://channel.is/
> > -----------------------------------------
> >
> > Index:
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/consumer/FileConsumer.java
> > ===================================================================
> > ---
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/consumer/FileConsumer.java
> > (revision 2305)
> > +++
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/consumer/FileConsumer.java
> > (working copy)
> > @@ -44,6 +44,8 @@
> > import org.red5.server.messaging.OOBControlMessage;
> > import org.red5.server.messaging.PipeConnectionEvent;
> > import org.red5.server.net.rtmp.event.IRTMPEvent;
> > +import org.red5.server.net.rtmp.event.VideoData;
> > +import org.red5.server.net.rtmp.event.VideoData.FrameType;
> > import org.red5.server.net.rtmp.message.Constants;
> > import org.red5.server.stream.IStreamData;
> > import org.red5.server.stream.message.RTMPMessage;
> > @@ -87,6 +89,10 @@
> > * Start timestamp
> > */
> > private int startTimestamp;
> > + /**
> > + * Next file
> > + */
> > + private File nextFile;
> >
> > /**
> > * Creates file consumer
> > @@ -96,10 +102,21 @@
> > public FileConsumer(IScope scope, File file) {
> > this.scope = scope;
> > this.file = file;
> > + this.nextFile = null;
> > offset = 0;
> > lastTimestamp = 0;
> > startTimestamp = -1;
> > }
> > +
> > + /**
> > + * Changes file
> > + * @param file
> > + */
> > + public synchronized void changeFile(File file) {
> > + if (!file.equals(this.file)) {
> > + this.nextFile = file;
> > + }
> > + }
> >
> > /**
> > * Push message through pipe
> > @@ -119,11 +136,21 @@
> > if (!(message instanceof RTMPMessage)) {
> > return;
> > }
> > - if (writer == null) {
> > - init();
> > - }
> > RTMPMessage rtmpMsg = (RTMPMessage) message;
> > final IRTMPEvent msg = rtmpMsg.getBody();
> > + synchronized (this) {
> > + if (writer == null) {
> > + init();
> > + } else if (nextFile != null && msg instanceof
> > VideoData && ((VideoData) msg).getFrameType() == FrameType.KEYFRAME) {
> > + this.file = this.nextFile;
> > + this.nextFile = null;
> > + this.writer = null;
> > + offset = 0;
> > + lastTimestamp = 0;
> > + startTimestamp = -1;
> > + init();
> > + }
> > + }
> > if (startTimestamp == -1) {
> > startTimestamp = msg.getTimestamp();
> > }
> > Index:
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/ClientBroadcastStream.java
> > ===================================================================
> > ---
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/ClientBroadcastStream.java
> > (revision 2305)
> > +++
> > C:/work/WorkingDraft/eclipse-ws/red5_server/src/org/red5/server/stream/ClientBroadcastStream.java
> > (working copy)
> > @@ -569,15 +569,20 @@
> > if (log.isDebugEnabled()) {
> > log.debug("Recording file: " +
> > file.getCanonicalPath());
> > }
> > - recordingFile = new FileConsumer(scope, file);
> > - Map<Object, Object> paramMap = new HashMap<Object,
> > Object>();
> > - if (isAppend) {
> > - paramMap.put("mode", "append");
> > + if (recordingFile == null) {
> > + recordingFile = new FileConsumer(scope, file);
> > + Map<Object, Object> paramMap = new HashMap<Object,
> > Object>();
> > + if (isAppend) {
> > + paramMap.put("mode", "append");
> > + } else {
> > + paramMap.put("mode", "record");
> > + }
> > + recordPipe.subscribe(recordingFile, paramMap);
> > + recording = true;
> > } else {
> > - paramMap.put("mode", "record");
> > + recordingFile.changeFile(file);
> > + recordingFilename = filename;
> > }
> > - recordPipe.subscribe(recordingFile, paramMap);
> > - recording = true;
> > recordingFilename = filename;
> > }
> >
> >
> > _______________________________________________
> > osflash mailing list
> > osflash at osflash.org
> > http://osflash.org/mailman/listinfo/osflash_osflash.org
> >
> >
More information about the osflash
mailing list