[Red5devs] Live streaming without swf
SPV
s_p_v at mail.ru
Sat May 17 12:25:36 PDT 2008
Hello, Red5 guru's!
Im newbie in Red5 (and in Java:) and I need some help. Im trying to send live stream to server without swf file. With the last SVN sources of Red5 and http://dl.fancycode.com/red5/api/, I wrote this test class:
<code>
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.mina.common.ByteBuffer;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.io.flv.impl.FLVReader;
import org.red5.io.ITag;
import org.red5.io.IoConstants;
import org.red5.io.utils.ObjectMap;
import org.red5.server.net.rtmp.RTMPClient;
import org.red5.server.net.rtmp.RTMPClient.INetStreamEventHandler;
import org.red5.server.net.rtmp.RTMPConnection;
import org.red5.server.net.rtmp.Channel;
import org.red5.server.net.rtmp.message.Header;
import org.red5.server.net.rtmp.codec.RTMP;
import org.red5.server.net.rtmp.event.Ping;
import org.red5.server.net.rtmp.event.Notify;
import org.red5.server.net.rtmp.event.AudioData;
import org.red5.server.net.rtmp.event.VideoData;
import org.red5.server.stream.message.RTMPMessage;
public class TestPublisher extends RTMPClient implements
IPendingServiceCallback, INetStreamEventHandler
{
private static final Logger logger = LoggerFactory
.getLogger(TestPublisher.class);
public static void main(String[] args)
{
String host = "localhost";
String app = "oflaDemo";
int port = 1935;
final TestPublisher publisher = new TestPublisher();
logger.debug("Connecting to rtmp://" + host + ":" + port + "/" + app);
publisher.connect(host, port, app, publisher);
}
private int streamId;
@Override
protected void onPing(RTMPConnection conn, Channel channel, Header source,
Ping ping)
{
// logger.debug("Ping");
}
@Override
public void connectionOpened(RTMPConnection conn, RTMP state)
{
logger.debug("Connection opened");
super.connectionOpened(conn, state);
}
@Override
public void connectionClosed(RTMPConnection conn, RTMP state)
{
logger.debug("Connection closed");
super.connectionClosed(conn, state);
System.exit(0);
}
@Override
synchronized public void resultReceived(IPendingServiceCall call)
{
logger.debug("Service call {" + call + "}");
if ("connect".equals(call.getServiceMethodName()))
{
// invoke("createStream", null, this);
createStream(this);
} else if ("createStream".equals(call.getServiceMethodName()))
{
streamId = (Integer) call.getResult();
logger.debug("Publishing stream id = " + streamId);
publish(streamId, "red5StreamDemo", "live", this);
}
}
@Override
synchronized public void onStreamEvent(Notify notify)
{
ObjectMap map = (ObjectMap) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
logger.debug("Stream notify: " + notify);
if ("NetStream.Publish.Start".equals(code))
{
startPublish();
}
}
synchronized public void startPublish()
{
File file = new File(
"/home/freelander/Programs/red5/webapps~/oflaDemo/streams/IronMan.flv");
FLVReader reader = null;
try
{
reader = new FLVReader(file);
} catch (Exception e)
{
}
int prevTime = 0;
while (reader.hasMoreTags())
{
ITag tag = reader.readTag();
int tagTime = tag.getTimestamp();
int dataType = tag.getDataType();
if (tagTime > prevTime)
try
{
//wait(tagTime - prevTime);
Thread.sleep(tagTime - prevTime);
} catch (Exception e)
{
}
prevTime = tagTime;
ByteBuffer frame = tag.getBody();
RTMPMessage msg = new RTMPMessage();
if (IoConstants.TYPE_METADATA == dataType)
msg.setBody(new Notify(frame));
else if (IoConstants.TYPE_VIDEO == dataType)
msg.setBody(new VideoData(frame));
else if (IoConstants.TYPE_AUDIO == dataType)
msg.setBody(new AudioData(frame));
else
logger.debug("Unknown data type: " + dataType);
publishStreamData(streamId, msg);
}
disconnect();
}
}
</code>
Im using "simpleSubscriber.swf" from Red5 examples for viewing this stream and all works fine... but for the first several seconds, when sound goes to silent for ~ 3 seconds and then appears again but with this 3 seconds delay. Disconnect/Connect again in simpleSubscriber.swf removes the delay but all repeats again on short time. I think its because of "Thread.sleep(tagTime - prevTime)" bad solution. I tried to change code from "while()" to special method "readNextTag" and Timer object with (tagTime - prevTime) interval, but situation with the sounds stay the same.
Question: how to synchronize video and audio correctly?
Thanx and sorry for my non-native English.
More information about the Red5devs
mailing list