以下是red5服务器端的代码,接受H264编码的视频流,发送协议是RTMP。
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.mina.core.buffer.IoBuffer;
import org.red5.io.IStreamableFile;
import org.red5.io.IStreamableFileFactory;
import org.red5.io.IStreamableFileService;
import org.red5.io.ITag;
import org.red5.io.ITagWriter;
import org.red5.io.StreamableFileFactory;
import org.red5.io.flv.impl.Tag;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.stream.IBroadcastStream;
import org.red5.server.api.stream.IStreamListener;
import org.red5.server.api.stream.IStreamPacket;
import org.red5.server.api.stream.ISubscriberStream;
import org.red5.server.util.ScopeUtils;
public class MyApplicationAdapter extends MultiThreadedApplicationAdapter {
private Map<String, MyStreamListener> map = new ConcurrentHashMap<String, MyStreamListener>();
@Override
public void streamPublishStart(IBroadcastStream stream) {
System.out.println("-------------streamPublishStart---------------------");
String publishedName = stream.getPublishedName();
MyStreamListener myStreamListener = new MyStreamListener(publishedName, this.scope);
map.put(publishedName, myStreamListener);
stream.addStreamListener(myStreamListener);
super.streamPublishStart(stream);
}
class MyStreamListener implements IStreamListener {
private int startTimeStamp = -1;
private ITagWriter writer = null;
private File file;
MyStreamListener (String publishedName, IScope scope) {
init(publishedName, scope);
}
private void init(String publishedName, IScope scope) {
try {
file = new File("C:/Program Files/Red5/webapps/FirstVideoDemo/streams/"+ publishedName +"_"+System.currentTimeMillis() +"_a.flv");
IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils
.getScopeService(scope, IStreamableFileFactory.class,
StreamableFileFactory.class);
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();
} catch (IOException e) {
e.printStackTrace();
}
}
void close() {
writer.close();
}
@Override
public void packetReceived(IBroadcastStream stream, IStreamPacket packet) {
int timeStamp = packet.getTimestamp();
IoBuffer data = packet.getData().asReadOnlyBuffer();
if (data.limit() == 0) {
return;
}
if (startTimeStamp == -1) {
// That will be not bigger then long value
startTimeStamp = packet.getTimestamp();
}
timeStamp -= startTimeStamp;
ITag tag = new Tag();
tag.setDataType(packet.getDataType());
tag.setBodySize(data.limit());
tag.setTimestamp(timeStamp);
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void streamBroadcastStart(IBroadcastStream stream) {
System.out.println("-------------streamBroadcastStart---------------------");
super.streamBroadcastStart(stream);
// String publishName=stream.getPublishedName();
// ISharedObject iso=getSharedObject(scope, publishName);
// if (iso==null) {
// createSharedObject(scope, publishName, true);
// iso = getSharedObject(scope, publishName);
// }
// iso.setAttribute("hasStream", true);
}
@Override
public void streamBroadcastClose(IBroadcastStream stream) {
System.out.println("-------------streamBroadcastClose---------------------");
String publishedName = stream.getPublishedName();
MyStreamListener myListener = map.get(publishedName);
if (null != myListener) {
myListener.close();
map.remove(publishedName);
}
super.streamBroadcastClose(stream);
}
}