使用Red5 录制视频

import java.io.File;

import org.apache.mina.common.ByteBuffer;
import org.red5.io.IStreamableFile;
import org.red5.io.ITag;
import org.red5.io.ITagWriter;
import org.red5.io.flv.impl.FLVService;
import org.red5.io.flv.impl.Tag;
import org.red5.io.utils.ObjectMap;
import org.red5.server.api.event.IEvent;
import org.red5.server.api.event.IEventDispatcher;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.net.rtmp.Channel;
import org.red5.server.net.rtmp.RTMPClient;
import org.red5.server.net.rtmp.RTMPConnection;
import org.red5.server.net.rtmp.codec.RTMP;
import org.red5.server.net.rtmp.event.AudioData;
import org.red5.server.net.rtmp.event.IRTMPEvent;
import org.red5.server.net.rtmp.event.Notify;
import org.red5.server.net.rtmp.event.VideoData;
import org.red5.server.net.rtmp.message.Header;
import org.red5.server.net.rtmp.status.StatusCodes;
import org.red5.server.stream.AbstractClientStream;
import org.red5.server.stream.IStreamData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyRtmpClient extends RTMPClient {

private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);

private String saveAsFileName = "test.flv";

public static void main(String[] args) {

String host = "localhost";
String app = "oflaDemo";
final String name = "IronMan.flv";
int port = 1935;
final int duration = 10000; // milliseconds, -2 means until end of stream

final MyRtmpClient client = new MyRtmpClient();
logger.debug("connecting, host: " + host + ", app: " + app + ", port: " + port);

IPendingServiceCallback callback = new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
logger.debug("service call result: " + call);
if ("connect".equals(call.getServiceMethodName())) {
client.createStream(this);
} else if ("createStream".equals(call.getServiceMethodName())) {
Integer streamId = (Integer) call.getResult();
logger.debug("createStream result stream id: " + streamId);
logger.debug("playing video by name: " + name);
client.play(streamId, name, 0, duration);
}
}
};

client.connect(host, port, app, callback);

}

private RTMPConnection conn;
private ITagWriter writer;

private int videoTs;
private int audioTs;

@Override
public void connectionOpened(RTMPConnection conn, RTMP state) {
logger.debug("connection opened");
super.connectionOpened(conn, state);
this.conn = conn;
init();
}

@Override
public void connectionClosed(RTMPConnection conn, RTMP state) {
logger.debug("connection closed");
super.connectionClosed(conn, state);
if (writer != null) {
writer.close();
writer = null;
}
System.exit(0);
}

@Override
public void createStream(IPendingServiceCallback callback) {
logger.debug("create stream");
IPendingServiceCallback wrapper = new CreateStreamCallBack(callback);
invoke("createStream", null, wrapper);
}

@Override
protected void onInvoke(RTMPConnection conn, Channel channel, Header header, Notify notify, RTMP rtmp) {
super.onInvoke(conn, channel, header, notify, rtmp);
ObjectMap<String, String> map = (ObjectMap) notify.getCall().getArguments()[0];
String code = map.get("code");
if (StatusCodes.NS_PLAY_STOP.equals(code)) {
logger.debug("onInvoke, code == NetStream.Play.Stop, disconnecting");
disconnect();
}
}

private void init() {
File file = new File(saveAsFileName);
FLVService flvService = new FLVService();
flvService.setGenerateMetadata(true);
try {
IStreamableFile flv = flvService.getStreamableFile(file);
writer = flv.getWriter();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private class CreateStreamCallBack implements IPendingServiceCallback {

private IPendingServiceCallback wrapped;

public CreateStreamCallBack(IPendingServiceCallback wrapped) {
this.wrapped = wrapped;
}

public void resultReceived(IPendingServiceCall call) {
Integer streamIdInt = (Integer) call.getResult();
if (conn != null && streamIdInt != null) {
MyNetStream stream = new MyNetStream();
stream.setConnection(conn);
stream.setStreamId(streamIdInt.intValue());
conn.addClientStream(stream);
}
wrapped.resultReceived(call);
}

}

private class MyNetStream extends AbstractClientStream implements IEventDispatcher {

public void close() { }

public void start() { }

public void stop() { }

public void dispatchEvent(IEvent event) {
if (!(event instanceof IRTMPEvent)) {
logger.debug("skipping non rtmp event: " + event);
return;
}
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
if (logger.isDebugEnabled()) {
logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
+ rtmpEvent.getClass().getSimpleName());
}
if (!(rtmpEvent instanceof IStreamData)) {
logger.debug("skipping non stream data");
return;
}
if (rtmpEvent.getHeader().getSize() == 0) {
logger.debug("skipping event where size == 0");
return;
}
ITag tag = new Tag();
tag.setDataType(rtmpEvent.getDataType());
if (rtmpEvent instanceof VideoData) {
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
} else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
ByteBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

}

使用:
commons-collections-3.2.jar
jcl104-over-slf4j-1.4.3.jar
logback-classic-0.9.8.jar
logback-core-0.9.8.jar
mina-core-1.1.6.jar
red5.jar
slf4j-api-1.4.3.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值