1

I have a circular buffer that is monitored for motion and saves clips to disk. Following the everything is a file philosophy, I should be able to write to a Unix pipe like I write to a file and make the gstreamer end work. The problem is I can't figure out how to write my video to a pipe.

How do I write to a pipe? Will writing to a pipe recreate the raspivid portion of this pipelint to create an RTSP stream that allows me to watch my dog at work?

raspivid -t 0 -w 1080 -h 720 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=VIDSERVERIP port=5000

My code

Ryan McGrath
  • 113
  • 1
  • 3
  • For capturing with raspivid and streaming, look at this. But it is not clear if you want to keep the motion part to write to disk? – jogco Jul 16 '16 at 06:26
  • So in the example you linked, everyone is using raspivid and piping the output to gstreamer/netcat. My h264 video stream is handled through picamera. I know how to write my video frame by frame. I don't know how to create a unix pipe from picamera that I can write my video to so I can replace the raspivid in the pipeline with my own code. – Ryan McGrath Jul 16 '16 at 15:39
  • Do you need to create a unix pipe? Is it not possible to use pygst and/or gst to stream in python? – jogco Jul 16 '16 at 20:30
  • If you want to use unix pipes, you need to design your code to write the stream to standard output, perhaps in addition to storing it on disk.. – jogco Jul 16 '16 at 20:34
  • I didn't know about pygst, it looks like it would allow me to do what I want.

    Another approach I was thinking of was creating an named pipe that I would open in python and write my video file to continuously. Then I could do

    cat named_pipe | gst-launch-1.0 .............

    This would allow me to use the regular gst documentation/tutorials rather than pygst as it seems less people use gst.

    Thanks for your help.

    – Ryan McGrath Jul 16 '16 at 21:55

1 Answers1

1

Sending data down a pipe to another process in Python is quite simple, especially if your script spawns that other process. First, you to import want the subprocess module. Then you want to use the Popen class in there to spawn the other process, specifying subprocess.PIPE as the stdin value. As you might expect, that'll cause a pipe to be spawned for communication to the other process via its stdin file.

Then it's just a matter of using the process' stdin as the recording output. The one thing to bear in mind is that you need to close the stdin pipe once recording is finished; picamera won't do it for you because it didn't open the pipe (you did via Popen), so it won't presume to close it for you:

import picamera
import subprocess

# start the gstreamer process with a pipe for stdin
gstreamer = subprocess.Popen([
    'gst-launch-1.0', '-v',
    'fdsrc',
    '!', 'h264parse',
    '!', 'rtph264pay', 'config-interval=1', 'pt=96',
    '!', 'gdppay',
    '!', 'tcpserversink', 'host=YOUR-PI-IP', 'port=5000'
    ], stdin=subprocess.PIPE)

# initialize the camera
camera = picamera.PiCamera(resolution=(1280, 720), framerate=25)
camera.hflip = True

# start recording to gstreamer's stdin
camera.start_recording(gstreamer.stdin, format='h264', bitrate=2000000)
camera.wait_recording(10)
camera.stop_recording()

# signal to gstreamer that the data's finished then wait for it to terminate
gstreamer.stdin.close()
gstreamer.wait()

As to the rest of your code - you've got some good stuff there, but some can be simplified with a few new toys introduced in picamera 1.11. Specifically, have a look at the new PiCameraCircularIO.copy_to method, and the clear method (just above it in the docs). Those can be used to greatly simplify (or even eliminate) your write_video function.

Dave Jones
  • 3,978
  • 15
  • 22