如何将视频(在磁盘上)转换为 rtsp 流
How to convert a video (on disk) to a rtsp stream
我的本地磁盘上有一个视频文件,我想从中创建一个 rtsp 流,我将在我的一个项目中使用它。一种方法是从 vlc 创建一个 rtsp 流,但我想用代码来实现(python 会更好)。
我试过像这样的 opencv 的 VideoWritter
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 {counter} frames",sep='',end="\r",flush=True)
counter += 1
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
break
cap.release()
out.release()
但是当我像这样在 vlc 上播放它时
vlc -v rtsp://127.0.0.1:5000
I am getting
[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 是另一种选择,但因为我从未使用过它,所以如果有人指出我正确的方向,那就太好了。
您试图公开 RTP protocol via TCP server but please note that RTP is not RTSP 并且 RTP(和 RTCP)只能是 RTSP 的一部分。
无论如何,有一种方法可以使用 GStreamer 的 GstRtspServer 和 Python 接口来使用 GStreamer 和 Python 创建 RTSP 服务器(gi
包)。
假设您的机器上已经安装了 Gstreamer,首先 and then install Gstreamer RTSP server(这不是标准 Gstreamer 安装的一部分)。
Python 通过简单的 RTSP 服务器公开 mp4 容器文件的代码
#!/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 = "{0} {1} ! 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()
注意
- 此代码将在默认端口 8554
上公开名为 stream1
的 RTSP 流
- 我使用
qtdemux
从 MP4 容器中获取视频。您也可以在管道上方扩展以提取音频(并通过 RTSP 服务器公开它)
- 要减少 CPU 处理,您只能提取视频而不对其进行解码并再次编码为 H264。但是,如果需要转码,我留下了一个注释行来完成这项工作(但它可能会变得不那么强大 CPUs)。
你可以用 VLC 播放这个
vlc -v rtsp://127.0.0.1:8554/stream1
或使用 Gstreamer
gst-launch-1.0 playbin uri=rtsp://127.0.0.1:8554/stream1
但是,如果您实际上不需要 RTSP,而只是 Gstreamer 管道(利用 rtpbin)之后的端到端 RTP 就可以完成工作
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
并且 VLC 可以播放
vlc -v rtp://127.0.0.1:5000
如何在管道中添加帧率和比特率
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 = "{0} {1} ! queue ! rtph264pay name=pay0 config-interval=1 pt=96".format(src_demux, h264_transcode)
print ("Element created: " + pipeline)
return Gst.parse_launch(pipeline)
我的本地磁盘上有一个视频文件,我想从中创建一个 rtsp 流,我将在我的一个项目中使用它。一种方法是从 vlc 创建一个 rtsp 流,但我想用代码来实现(python 会更好)。 我试过像这样的 opencv 的 VideoWritter
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 {counter} frames",sep='',end="\r",flush=True)
counter += 1
if cv2.waitKey(1) & 0xFF == ord("q"):
break
else:
break
cap.release()
out.release()
但是当我像这样在 vlc 上播放它时
vlc -v rtsp://127.0.0.1:5000 I am getting
[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 是另一种选择,但因为我从未使用过它,所以如果有人指出我正确的方向,那就太好了。
您试图公开 RTP protocol via TCP server but please note that RTP is not RTSP 并且 RTP(和 RTCP)只能是 RTSP 的一部分。
无论如何,有一种方法可以使用 GStreamer 的 GstRtspServer 和 Python 接口来使用 GStreamer 和 Python 创建 RTSP 服务器(gi
包)。
假设您的机器上已经安装了 Gstreamer,首先
Python 通过简单的 RTSP 服务器公开 mp4 容器文件的代码
#!/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 = "{0} {1} ! 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()
注意
- 此代码将在默认端口 8554 上公开名为
- 我使用
qtdemux
从 MP4 容器中获取视频。您也可以在管道上方扩展以提取音频(并通过 RTSP 服务器公开它) - 要减少 CPU 处理,您只能提取视频而不对其进行解码并再次编码为 H264。但是,如果需要转码,我留下了一个注释行来完成这项工作(但它可能会变得不那么强大 CPUs)。
stream1
的 RTSP 流
你可以用 VLC 播放这个
vlc -v rtsp://127.0.0.1:8554/stream1
或使用 Gstreamer
gst-launch-1.0 playbin uri=rtsp://127.0.0.1:8554/stream1
但是,如果您实际上不需要 RTSP,而只是 Gstreamer 管道(利用 rtpbin)之后的端到端 RTP 就可以完成工作
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
并且 VLC 可以播放
vlc -v rtp://127.0.0.1:5000
如何在管道中添加帧率和比特率
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 = "{0} {1} ! queue ! rtph264pay name=pay0 config-interval=1 pt=96".format(src_demux, h264_transcode)
print ("Element created: " + pipeline)
return Gst.parse_launch(pipeline)