Using WriteGear's Compression Mode for RTSP/RTP Live-Streaming¶
In Compression Mode, you can use WriteGear for livestreaming with traditional protocols such as RTSP/RTP. The example to achieve that is as follows:
New in v0.2.6
This example was added in v0.2.6.
Creating your own RTSP Server locally
If you want to create your RTSP Server locally, then checkout MediaMTX (formerly rtsp-simple-server) - ready-to-use and zero-dependency real-time media server and media proxy that allows to publish, read, proxy, record and playback video and audio streams.
This example assume you already have a RTSP Server running at specified RTSP address with format rtsp://[RTSP_ADDRESS]:[RTSP_PORT]/[RTSP_PATH] for publishing video frames.
Make sure to change RTSP address rtsp://localhost:8554/mystream with yours in following code before running!
# import required librariesimportcv2fromvidgear.gearsimportCamGearfromvidgear.gearsimportWriteGear# open any valid video stream(for e.g `foo.mp4` file)stream=CamGear(source="foo.mp4").start()# define required FFmpeg parameters for your writeroutput_params={"-f":"rtsp","-rtsp_transport":"tcp"}# Define writer with defined parameters and RTSP address# [WARNING] Change your RTSP address `rtsp://localhost:8554/mystream` with yours!writer=WriteGear(output="rtsp://localhost:8554/mystream",logging=True,**output_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if NonetypeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# safely close video streamstream.stop()# safely close writerwriter.close()
Using WriteGear's Compression Mode for YouTube-Live Streaming¶
In Compression Mode, you can also use WriteGear for Youtube-Livestreaming. The example is as follows:
# import required librariesfromvidgear.gearsimportCamGearfromvidgear.gearsimportWriteGearimportcv2# define and open video sourcestream=CamGear(source="/home/foo/foo.mp4",logging=True).start()# define required FFmpeg parameters for your writeroutput_params={"-clones":["-f","lavfi","-i","anullsrc"],"-vcodec":"libx264","-preset":"medium","-b:v":"4500k","-bufsize":"512k","-pix_fmt":"yuv420p","-f":"flv",}# [WARNING] Change your YouTube-Live Stream Key here:YOUTUBE_STREAM_KEY="xxxx-xxxx-xxxx-xxxx-xxxx"# Define writer with defined parameterswriter=WriteGear(output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY),logging=True,**output_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if NonetypeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# safely close video streamstream.stop()# safely close writerwriter.close()
This code assume given input video source contains valid audio stream.
# import required librariesfromvidgear.gearsimportCamGearfromvidgear.gearsimportWriteGearimportcv2# define video source(with audio) hereVIDEO_SOURCE="/home/foo/foo.mp4"# Open streamstream=CamGear(source=VIDEO_SOURCE,logging=True).start()# define required FFmpeg parameters for your writer# [NOTE]: Added VIDEO_SOURCE as audio-sourceoutput_params={"-i":VIDEO_SOURCE,"-acodec":"aac","-ar":44100,"-b:a":712000,"-vcodec":"libx264","-preset":"medium","-b:v":"4500k","-bufsize":"512k","-pix_fmt":"yuv420p","-f":"flv",}# [WARNING] Change your YouTube-Live Stream Key here:YOUTUBE_STREAM_KEY="xxxx-xxxx-xxxx-xxxx-xxxx"# Define writer with defined parameterswriter=WriteGear(output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY),logging=True,**output_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if NonetypeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# safely close video streamstream.stop()# safely close writerwriter.close()
Using WriteGear's Compression Mode with v4l2loopback Virtual Cameras¶
With WriteGear's Compression Mode, you can directly feed video-frames to v4l2loopback generated Virtual Camera devices on Linux Machines. The complete usage example is as follows:
New in v0.3.0
This example was added in v0.3.0.
Example Assumptions
You're running are a Linux machine.
WriteGear API's backend FFmpeg binaries are compiled with v4l2/v4l2loopback demuxer support.
You already have v4l2loopback Virtual Camera device running at address: /dev/video0
Creating your own Virtual Camera device with v4l2loopback module.
To install and create a v4l2loopback virtual camera device on Linux Mint OS/Ubuntu (may slightly differ for other distros), run following two terminal commands:
# import required librariesfromvidgear.gearsimportCamGearfromvidgear.gearsimportWriteGearimportcv2# open any valid video stream(for e.g `foo.mp4` file)stream=CamGear(source="foo.mp4").start()# define required FFmpeg parameters for your writer# also retrieve framerate from CamGear Stream and pass it as `-input_framerate` parameteroutput_params={"-input_framerate":stream.framerate,"-vcodec":"libxvid","-f":"v4l2","-pix_fmt":"yuv420p",}# Define writer with "/dev/video0" as source and user-defined parameters writer=WriteGear(output="/dev/video0",logging=True,**output_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if None-typeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# close output windowcv2.destroyAllWindows()# safely close video streamstream.stop()# safely close writerwriter.close()
The data sent to the v4l2loopback device /dev/video0 in this example with WriteGear API, can then be read by any v4l2-capable application (such as OpenCV, VLC, ffplay etc.)
Using WriteGear's Compression Mode for creating MP4 segments¶
In Compression Mode, you can also use WriteGear for creating MP4 segments from almost any video source. The example is as follows:
# import required librariesfromvidgear.gearsimportVideoGearfromvidgear.gearsimportWriteGearimportcv2# Open any video source `foo.mp4`stream=VideoGear(source="foo.mp4",logging=True).start()# define required FFmpeg optimizing parameters for your writeroutput_params={"-c:v":"libx264","-crf":22,"-map":0,"-segment_time":9,"-g":9,"-sc_threshold":0,"-force_key_frames":"expr:gte(t,n_forced*9)","-clones":["-f","segment"],}# Define writer with defined parameterswriter=WriteGear(output="output%03d.mp4",logging=True,**output_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if NonetypeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# Show output windowcv2.imshow("Output Frame",frame)# check for 'q' key if pressedkey=cv2.waitKey(1)&0xFFifkey==ord("q"):break# close output windowcv2.destroyAllWindows()# safely close video streamstream.stop()# safely close writerwriter.close()
Using WriteGear's Compression Mode to add external audio file input to video frames¶
You can also use WriteGear for merging external audio with live video-source:
New in v0.2.1
This example was added in v0.2.1.
Make sure this -i audio-source it compatible with provided video-source, otherwise you could encounter multiple errors or no output at all.
# import required librariesfromvidgear.gearsimportCamGearfromvidgear.gearsimportWriteGearimportcv2# open any valid video stream(for e.g `foo_video.mp4` file)stream=CamGear(source="foo_video.mp4").start()# add various parameters, along with custom audiostream_params={"-input_framerate":stream.framerate,# controlled framerate for audio-video sync !!! don't forget this line !!!"-i":"foo_audio.aac",# assigns input audio-source: "foo_audio.aac"}# Define writer with defined parameterswriter=WriteGear(output="Output.mp4",logging=True,**stream_params)# loop overwhileTrue:# read frames from streamframe=stream.read()# check for frame if NonetypeifframeisNone:break# {do something with the frame here}# write frame to writerwriter.write(frame)# Show output windowcv2.imshow("Output Frame",frame)# check for 'q' key if pressedkey=cv2.waitKey(1)&0xFFifkey==ord("q"):break# close output windowcv2.destroyAllWindows()# safely close video streamstream.stop()# safely close writerwriter.close()
Using WriteGear's Compression Mode for generating Timely Accurate Video¶
If you need timely accurate video with exactly same speed as real-time input, then you need to use FFmpeg directly through its execute_ffmpeg_cmd method:
New in v0.2.4
This example was added in v0.2.4.
In this example we are capturing video from desktop screen in a Timely Accurate manner.
# import required librariesfromvidgear.gearsimportWriteGear# Define writer with defined parameters and with some dummy namewriter=WriteGear(output="Output.mp4",logging=True)# format FFmpeg command to generate time accurate videoffmpeg_command=["-y","-f","gdigrab","-framerate","30","-i","desktop","Output.mkv",]# `-y` parameter is to overwrite outputfile if exists# execute FFmpeg commandwriter.execute_ffmpeg_cmd(ffmpeg_command)# safely close writerwriter.close()
# import required librariesfromvidgear.gearsimportWriteGear# Define writer with defined parameters and with some dummy namewriter=WriteGear(output="Output.mp4",logging=True)# format FFmpeg command to generate time accurate videoffmpeg_command=["-y","-f","x11grab","-framerate","30","-i","default","Output.mkv",]# `-y` parameter is to overwrite outputfile if exists# execute FFmpeg commandwriter.execute_ffmpeg_cmd(ffmpeg_command)# safely close writerwriter.close()
# import required librariesfromvidgear.gearsimportWriteGear# Define writer with defined parameters and with some dummy namewriter=WriteGear(output="Output.mp4",logging=True)# format FFmpeg command to generate time accurate videoffmpeg_command=["-y","-f","avfoundation","-framerate","30","-i","default","Output.mkv",]# `-y` parameter is to overwrite outputfile if exists# execute FFmpeg commandwriter.execute_ffmpeg_cmd(ffmpeg_command)# safely close writerwriter.close()
We will be using cv_bridge to convert OpenCV frames to ROS image messages and vice-versa.
In this example, we'll create a node that listens to a ROS image message topic, converts the received images messages into OpenCV frames, draws a circle on it, and then process these frames into a lossless compressed file format in real-time.
New in v0.2.2
This example was added in v0.2.2.
This example is vidgear implementation of this wiki example.
# import roslibimportroslibroslib.load_manifest("my_package")# import other required librariesimportsysimportrospyimportcv2fromstd_msgs.msgimportStringfromsensor_msgs.msgimportImagefromcv_bridgeimportCvBridge,CvBridgeErrorfromvidgear.gearsimportWriteGear# custom publisher classclassimage_subscriber:def__init__(self,output="Output.mp4"):# create CV bridgeself.bridge=CvBridge()# define publisher topicself.image_pub=rospy.Subscriber("image_topic_sub",Image,self.callback)# Define writer with default parametersself.writer=WriteGear(output=output)defcallback(self,data):# convert received data to frametry:cv_image=self.bridge.imgmsg_to_cv2(data,"bgr8")exceptCvBridgeErrorase:print(e)# check if frame is validifcv_image:# {do something with the frame here}# let's add a circle(rows,cols,channels)=cv_image.shapeifcols>60androws>60:cv2.circle(cv_image,(50,50),10,255)# write frame to writerself.writer.write(cv_image)defclose(self):# safely close video streamself.writer.close()defmain(args):# define publisher with suitable output filename# such as `Output.mp4` for saving outputic=image_subscriber(output="Output.mp4")# initiate ROS node on publisherrospy.init_node("image_subscriber",anonymous=True)try:# run noderospy.spin()exceptKeyboardInterrupt:print("Shutting down")finally:# close publisheric.close()if__name__=="__main__":main(sys.argv)