Lesson 5 : Transmitting stream
Sending multicast
Download lesson [here]
In this lesson, we are receiving frames from an IP camera using LiveThread and recast those frames to a multicast address using another LiveThread. The filterchain looks like this:
(LiveThread:livethread) --> {InfoFrameFilter:info_filter) -->> (LiveThread:livethread2)
Let’s start by importing Valkka:
import time
from valkka.core import *
Live555’s default output packet buffer size might be too small, so let’s make it bigger before instantiating any LiveThreads:
setLiveOutPacketBuffermaxSize(95000)
Construct the filtergraph from end-to-beginning:
livethread2 =LiveThread("livethread2")
live_in_filter =livethread2.getFrameFilter()
info_filter =InfoFrameFilter("info_filter",live_in_filter)
livethread =LiveThread("livethread")
Start threads
livethread2.startCall()
livethread. startCall()
Define stream source: incoming frames from IP camera 192.168.1.41 are tagged with slot number “2” and they are written to “info_filter”:
ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://admin:nordic12345@192.168.1.41", 2, info_filter)
Define stream sink: all outgoing frames with slot number “2” are sent to port 50000:
out_ctx =LiveOutboundContext(LiveConnectionType_sdp, "224.1.168.91", 2, 50000)
Start playing:
livethread2.registerOutboundCall(out_ctx)
livethread. registerStreamCall(ctx)
livethread. playStreamCall(ctx)
Stream and recast to multicast for a while:
time.sleep(60)
livethread. stopStreamCall(ctx)
livethread. deregisterStreamCall(ctx)
livethread2.deregisterOutboundCall(out_ctx)
Stop threads in beginning-to-end order
livethread. stopCall();
livethread2.stopCall();
print("bye")
To receive the multicast stream, you need this file, save it as “multicast.sdp”:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 224.1.168.91
t=0 0
a=tool:libavformat 56.36.100
m=video 50000 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1
a=control:streamid=0
Then you can test that the stream is multicasted (while running the python script) with:
ffplay multicast.sdp
(feel free to launch this command several times simultaneously)
Note
Receiving and recasting the stream can also be done using a single LiveThread only. This is left as an excercise.
Using the RTSP server
Download lesson [here]
In this lesson, we establish an on-demand RTSP server at the localhost.
Stream is read from an IP camera and then re-streamed (shared) to a local RTSP server that serves at port 8554. While this snippet is running, you can test the RTSP server with:
ffplay rtsp://127.0.0.1:8554/stream1
Let’s start by importing Valkka:
import time
from valkka.core import *
Live555’s default output packet buffer size might be too small, so let’s make it bigger before instantiating any LiveThreads:
setLiveOutPacketBuffermaxSize(95000)
Construct the filtergraph from end-to-beginning:
livethread2 =LiveThread("livethread2")
live_in_filter =livethread2.getFrameFilter()
info_filter =InfoFrameFilter("info_filter",live_in_filter)
livethread =LiveThread("livethread")
Before starting the threads, establish an RTSP server on livethread2 at port 8554:
livethread2.setRTSPServer(8554);
Start threads
livethread2.startCall()
livethread. startCall()
Define stream source: incoming frames from IP camera 192.168.1.41 are tagged with slot number “2” and they are written to “info_filter”:
ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://admin:nordic12345@192.168.1.41", 2, info_filter)
Define stream sink: all outgoing frames with slot number “2” are sent to the RTSP server, with substream id “stream1”:
out_ctx =LiveOutboundContext(LiveConnectionType_rtsp, "stream1", 2, 0)
Start playing:
livethread2.registerOutboundCall(out_ctx)
livethread. registerStreamCall(ctx)
livethread. playStreamCall(ctx)
Stream and recast to the RTSP server for a while:
time.sleep(60)
livethread. stopStreamCall(ctx)
livethread. deregisterStreamCall(ctx)
livethread2.deregisterOutboundCall(out_ctx)
Stop threads in beginning-to-end order
livethread. stopCall();
livethread2.stopCall();
print("bye")