Reputation: 4678
Finally I created a stream video recorder flash application and its simple Red5 backend but of course Red5 jokes me again. Most of the times the recorded videos are corrupted, cannot play them back without randomly stopping-resuming, hanging out the player .. and me as well. Why is it doing this?
I researched the internet and found this issue but no solution! I tried not to record the video instead switch it to live and attach an ffmpeg to do the dirty job but naturally the ffmpeg couldn't connect with the following error message on the red5's output:
Error executing call: Service: null Method: play Num Params: 1 0: my_little_stream ... blabla bla
Before I try out integrating the Xuggler stuff what I truly don't want to I ask you, what to do, can I attach the ffmpeg somehow or is there a configuration in the red5 server I should change.. or anything! Thanks!
Edit: I'm using Red5 1.0 RC2
Edit#2: I compiled the oflaDemo app from trunk sources with red5 1.0.0rc2 server files then created a live stream with a simple flex app just to try out if ffmpeg recorder worked. Now it could connect to red5 but the result is the same! The videos seems to be corrupt...
Upvotes: 2
Views: 2541
Reputation: 3860
*But what should I put into the packetReceived() function? *
I add this in a separated answer to highlight correctly:
To write the packets to disk, you need: 1) the packet, 2) convert the packet to an ITag 3) Obtain an instance of a ITagWriter
1) the packet data http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/flvrecord/listener/StreamVideoListener.java?view=markup around Line 50
public void packetReceived(IBroadcastStream broadcastStream,
IStreamPacket streampacket) {
}
streampacket => the packet you want to write to disk.
2) write the packet by converting it to a ITag
IoBuffer data = streampacket.getData().asReadOnlyBuffer();
if (data.limit() == 0) {
return;
}
if (startTimeStamp == -1) {
// That will be not bigger then long value
startTimeStamp = streampacket.getTimestamp();
}
timeStamp -= startTimeStamp;
ITag tag = new Tag();
tag.setDataType(streampacket.getDataType());
// log.debug("data.limit() :: "+data.limit());
tag.setBodySize(data.limit());
tag.setTimestamp(timeStamp);
tag.setBody(data);
writer.writeTag(tag);
3) Obtaining an instance of a Writer
protected ITagWriter writer = null;
private void init() throws IOException {
file = new File(OmFileHelper.getStreamsSubDir(this.scope.getName()), this.streamName + ".flv");
IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils
.getScopeService(this.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();
}
So this is a rough walk through. In that sense you can then go ahead.
class also contains a Queue to collect the packets.
IStreamPacket.getType == 9 is video and I think 8 is audio (but you need to verify that).
Sebastian
Upvotes: 3
Reputation: 3860
What recording method do you use now? There are actually 2 methods in Red5 to record: 1) NetStream.record => this is plain simple 2) You do NetStream "live" but you have a server side StreamListener that you attach to the stream and then write the stream to disc.
I have implemented both solutions successfully at: http://incubator.apache.org/openmeetings/ There is no choppy video or random stop/pause.
There is no need to integrate FFMPEG or Xuggler to do a simple recording with Red5! FFMPEG might be useful if you want to modify the resulting video and add a watermark. For audio editing you might use tools like SoX. However ... just plain record and playback as-is does not require those tools at all!
Sebastian
Upvotes: 0