Thank you Mathieu. I will read your post in greater detail.
Perhaps I should update on what I have done so far, where I am stuck, and ask for help... Let me attempt to do that here.
Please forgive any stupidity as I am pretty new to rtmfp / cumulus. It looks like a great piece of software.
Background:
-------------------
My
use case is: I create live streams on server side containing video in
h.264 and audio (aac), wrapped in an flv container. I am capable and
flexible in streaming either the flv container, or streaming the
independent video / audio streams to cumulus on server side (anything
possible, to get cumulus working). Client is a regular flash player
connecting to the rtmfp stream.
I already have it working with an
rtmp mediaserver (crtmpserver) and it works well. My requirement is to
lower the (network congestion related) latency even further by using
udp, so I am really using it as a live unicast from server to client, no
p2p requirements. My goal therefore is lowest possible latency.
What I have tried so far:
-----------------------------------
(1) I started with just video sterams just to make sure. I wrote a main.lua (attached to this message) to receive video data on port 6666 (TCP).
In that I tried to create a publication on client connection.
testpublication = nil
function onConnection(client,...)
-- if first time, start off publication
if not testpublication then
NOTE("Created a new publication")
testpublication = cumulus:publish("testpublication")
end
end
(2) When the client connects, I am trying to add it to the publication. I think I am doing it wrong, and dont think I can set the publisher of the client this way (is llisterner.publication.publisher "read only" ?)
function onSubscribe(client, listener)
NOTE("Added listener to publication")
listener.publication.publisher = testpublication
end
(3) I started a simple gstreamer test stream sending video h264 data to port 6666 (TCP).
For completeness, the stream is as follows. Removing the flvmux below will send the raw stream, without flvmux wrapper.
% gst-launch videotestsrc is-live=true do-timestamp=true ! queue ! video/x-raw-yuv,framerate=30/1,width=640,height=480 ! timeoverlay font-desc="Courier 40px" color=0x00ff00 shadow=false halignment=right valignment=bottom ! tee name=t1 ! queue ! xvimagesink sync=false t1. ! queue ! videoscale ! video/x-raw-yuv,framerate=30/1,width=640,height=480,format="(fourcc)I420" ! videoflip name=vflip ! x264enc tune=zerolatency speed-preset=ultrafast profile=baseline key-int-max=240 bitrate=1000 ! flvmux ! tcpclientsink port=6666
(4)
I push the video data received by the TCP server to the publication. Maybe I am doing this wrong.
function server:clientHandler(client)
function client:onReception(data)
if (testpublication) then
NOTE("Pushing video packet..")
testpublication:pushVideoPacket(cumulus.epochTime, data)
testpublication:flush()
end
return 0 -- return rest (all has been consumed here)
end
end
(5)
I see client from flashplayer connecting, and tcp server receiving streams from gstreamer, and pushing video packets to flash client. But nothing on flashplayer video.
Where I am stuck:
---------------------------
- Video packets forwarding but nothing seen on flashplayer. I know flashplayer connects since to cumulus since i get the messages printed on connection.
- SHould I be sending flv or h264. I saw pushVideoPacket and pushAudioPacket, which seems to indicate that it needs raw H264 elementary streams. If it is raw H264, then in the case of audio + video will the stream not get out of avsync due to network latencies on the way to the client ?
Note that this is only a prototype attempt and I know it is inefficient, but i just want to get a stream playing first and then clean it up. I am completely ok to dig into the C++ code of cumulus, but thought someone will know better than me since that is a very slow path.
Sorry for the long mail, and appreciate your help.
regards
Badri