- Saved searches
- Use saved searches to filter your results more quickly
- License
- gabrieljablonski/rtsp-rtp-stream
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- How to RTSP stream a video using Gstreamer and Python?
- How to convert a video (on disk) to a rtsp stream
- 2 Answers 2
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
RTSP and RTP streaming. Programming assignment from the book «Computer Networking: A Top-Down Approach» by Jim Kurose
License
gabrieljablonski/rtsp-rtp-stream
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
DISCLAIMER: PYQT IS AVAILABLE THROUGH THE GPL LICENSE. THE MIT LICENSE ONLY APPLIES TO NON-PYQT CODE
Python implementation of the programming assignment from the chapter «Multimedia Networking» (chapter 7 in the 6th edition) of the book «Computer Networking: A Top-Down Approach» by Jim Kurose.
Implements basic RTSP and RTP streaming functionality using the standard Python 3 library, plus PyQt5 and Pillow for stuff related to GUI. Further info available in the assignment guide (from the 3rd edition, newer versions of the book might change the assignment slightly). Error handling is very minimal, reopening the server and client is required to run another session.
This implementation does NOT strictly follow the one provided by the book authors
Clone the repository with git clone https://github.com/gabrieljablonski/rtsp-rtp-stream .
Having python>=3.6 installed, create a virtual environment by running python -m venv venv inside the cloned folder.
Activate the virtual environment ( source venv/bin/activate on Linux, .\venv\Scripts\activate on Windows).
Install the requirements with python -m pip install -r requirements.txt .
Go to the sources folder with cd src/ (video stream class assumes mjpeg file is in working directory).
Server should be run first with
In which port is the port number for the RTSP socket to listen on.
Client can then be run with
in which file name is the name for the file to be sent via RTP ( movie.mjpeg is the available sample), host address is the server address ( localhost if running on same machine), host port is the port selected when running the server, RTP port is the port for receiving the video via RTP.
Since you’re probably running each instance on separate terminals, remember to activate the venv on both.
python main_server.py 5540 python main_client.py movie.mjpeg localhost 5540 5541
About
RTSP and RTP streaming. Programming assignment from the book «Computer Networking: A Top-Down Approach» by Jim Kurose
How to RTSP stream a video using Gstreamer and Python?
I have a code that currently takes one video and show it in screen using the gstreamer bindings for Python. I can seek the video when a «Forward» button is clicked at the player opened, and that is an important feature for me, hence the reason I don’t want to use a parse to write a pipeline and send it to gst-launch. What I want to do now is stream this video not only to a new opened window, but also (or only if I can’t have both) via RTSP to open it at VLC or even another client over LAN. Is there any way to do that? I am sorry, for the long code, but here it is:
import sys, os, time import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GObject, Gtk from gi.repository import GdkX11, GstVideo class GTK_Main(object): def __init__(self): window = Gtk.Window(Gtk.WindowType.TOPLEVEL) window.set_title("Vorbis-Player") window.set_default_size(500, -1) window.connect("destroy", Gtk.main_quit, "WM destroy") vbox = Gtk.VBox() window.add(vbox) self.entry = Gtk.Entry() vbox.pack_start(self.entry, False, False, 0) hbox = Gtk.HBox() vbox.add(hbox) buttonbox = Gtk.HButtonBox() hbox.pack_start(buttonbox, False, False, 0) rewind_button = Gtk.Button("Rewind") rewind_button.connect("clicked", self.rewind_callback) buttonbox.add(rewind_button) self.button = Gtk.Button("Start") self.button.connect("clicked", self.start_stop) buttonbox.add(self.button) forward_button = Gtk.Button("Forward") forward_button.connect("clicked", self.forward_callback) buttonbox.add(forward_button) self.time_label = Gtk.Label() self.time_label.set_text("00:00 / 00:00") hbox.add(self.time_label) window.show_all() self.player = Gst.ElementFactory.make("playbin", "player") bus = self.player.get_bus() bus.add_signal_watch() bus.enable_sync_message_emission() bus.connect("message", self.on_message) bus.connect("sync-message::element", self.on_sync_message) def start_stop(self, w): if self.button.get_label() == "Start": filepath = self.entry.get_text().strip() if os.path.isfile(filepath): filepath = os.path.realpath(filepath) self.butto n.set_label("Stop") self.player.set_property("uri", "file://" + filepath) self.player.set_state(Gst.State.PLAYING) time.sleep(1) self.forward_callback(60) else: self.player.set_state(Gst.State.NULL) self.button.set_label("Start") def on_message(self, bus, message): t = message.type if t == Gst.MessageType.EOS: self.player.set_state(Gst.State.NULL) self.button.set_label("Start") elif t == Gst.MessageType.ERROR: self.player.set_state(Gst.State.NULL) err, debug = message.parse_error() print ("Error: %s" % err, debug) self.button.set_label("Start") def on_sync_message(self, bus, message): if message.get_structure().get_name() == 'prepare-window-handle': imagesink = message.src imagesink.set_property("force-aspect-ratio", True) imagesink.set_window_handle(self.movie_window.get_property('window').get_xid()) def rewind_callback(self, w): rc, pos_int = self.player.query_position(Gst.Format.TIME) seek_ns = pos_int - 10 * 1000000000 if seek_ns < 0: seek_ns = 0 print ("Backward: %d ns ->%d ns" % (pos_int, seek_ns)) self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, seek_ns) def forward_callback(self, w): rc, pos_int = self.player.query_position(Gst.Format.TIME) if type(w) == int: seek_ns = w * 1000000000 else: seek_ns = pos_int + 10 * 1000000000 print ("Forward: %d ns -> %d ns" % (pos_int, seek_ns)) self.player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, seek_ns) def convert_ns(self, t): # This method was submitted by Sam Mason. # It's much shorter than the original one. s,ns = divmod(t, 1000000000) m,s = divmod(s, 60) if m < 60: return "%02i:%02i" %(m,s) else: h,m = divmod(m, 60) return "%i:%02i:%02i" %(h,m,s) GObject.threads_init() Gst.init(None) GTK_Main() Gtk.main()
How to convert a video (on disk) to a rtsp stream
I have a video file on my local disk and i want to create an rtsp stream from it, which i am going to use in one of my project. One way is to create a rtsp stream from vlc but i want to do it with code (python would be better). I have tried opencv's VideoWritter like this
import cv2 _dir = "/path/to/video/file.mp4" cap = cv2.VideoCapture(_dir) framerate = 25.0 out = cv2.VideoWriter( "appsrc ! videoconvert ! x264enc noise-reduction=10000 speed-preset=ultrafast tune=zerolatency ! rtph264pay config-interval=1 pt=96 ! tcpserversink host=127.0.0.1 port=5000 sync=false", 0, framerate, (1920, 1080), ) counter = 0 while cap.isOpened(): ret, frame = cap.read() if ret: out.write(frame) print(f"Read frames",sep='',end="\r",flush=True) counter += 1 if cv2.waitKey(1) & 0xFF == ord("q"): break else: break cap.release() out.release()
[00007fbb307a3e18] access_realrtsp access error: cannot connect to 127.0.0.1:5000 [00007fbb2c189f08] core input error: open of `rtsp://127.0.0.1:5000' failed [00007fbb307a4278] live555 demux error: Failed to connect with rtsp://127.0.0.1:5000
Gstreamer is another option but as i have never used it, so would be nice if someone points me in the right direction.
2 Answers 2
You tried to expose RTP protocol via TCP server but please note that RTP is not RTSP and that RTP (and RTCP) can only be part of RTSP.
Anyways, there is a way to create RTSP server with GStreamer and Python by using GStreamer's GstRtspServer and Python interface for Gstreamer ( gi package).
Assuming that you already have Gstreamer on your machine, first install gi python package and then install Gstreamer RTSP server (which is not part of standard Gstreamer installation).
Python code to expose mp4 container file via simple RTSP server
#!/usr/bin/env python import sys import gi gi.require_version('Gst', '1.0') gi.require_version('GstRtspServer', '1.0') from gi.repository import Gst, GstRtspServer, GObject, GLib loop = GLib.MainLoop() Gst.init(None) class TestRtspMediaFactory(GstRtspServer.RTSPMediaFactory): def __init__(self): GstRtspServer.RTSPMediaFactory.__init__(self) def do_create_element(self, url): #set mp4 file path to filesrc's location property src_demux = "filesrc location=/path/to/dir/test.mp4 ! qtdemux name=demux" h264_transcode = "demux.video_0" #uncomment following line if video transcoding is necessary #h264_transcode = "demux.video_0 ! decodebin ! queue ! x264enc" pipeline = " ! queue ! rtph264pay name=pay0 config-interval=1 pt=96".format(src_demux, h264_transcode) print ("Element created: " + pipeline) return Gst.parse_launch(pipeline) class GstreamerRtspServer(): def __init__(self): self.rtspServer = GstRtspServer.RTSPServer() factory = TestRtspMediaFactory() factory.set_shared(True) mountPoints = self.rtspServer.get_mount_points() mountPoints.add_factory("/stream1", factory) self.rtspServer.attach(None) if __name__ == '__main__': s = GstreamerRtspServer() loop.run()
- this code will expose RTSP stream named stream1 on default port 8554
- I used qtdemux to get video from MP4 container. You could extend above pipeline to extract audio too (and expose it too via RTSP server)
- to decrease CPU processing you can only extract video without decoding it and encoding it again to H264. However, if transcoding is needed, I left one commented line that will do the job (but it might choke less powerful CPUs).
You can play this with VLC
vlc -v rtsp://127.0.0.1:8554/stream1
gst-launch-1.0 playbin uri=rtsp://127.0.0.1:8554/stream1
However, If you actually do not need RTSP but just end-to-end RTP following Gstreamer pipeline (that utilizes rtpbin) will do the job
gst-launch-1.0 -v rtpbin name=rtpbin \ filesrc location=test.mp4 ! qtdemux name=demux \ demux.video_0 ! decodebin ! x264enc ! rtph264pay config-interval=1 pt=96 ! rtpbin.send_rtp_sink_0 \ rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=5000 sync=true async=false