1

I am using 2 raspberry pi and each of them has a camera connected. I am trying to run, from the first pi, a script to get the video feed of the second one.
And for that, I would need the value my function returns through ssh.

With a simple example :
slaveScript.py

def run():
    return "hello there"

if __name__ == '__main__':
    run()

masterScript.py

import pexpect

try:
    # ssh connection
    child = pexpect.spawn('ssh -X pi@pislave.local')
    child.expect('pi@pislave.local\'s password:', timeout=10) 
    child.sendline('pi')
    child.expect('$')

    # run script
    child.sendline('python3 slaveScript.py run')
    cap = child.read() # error here
    print(cap)
    
except pexpect.ExceptionPexpect as e:
    print(str(e))

I would like, for this example to get "hello there". How can I get it? Is there a pexpect method I can use?

In context with the cameras :
SlaveScript.py

import cv2

def run():
    return cv2.VideoCapture(0)

if __name__ == '__main__':
    run()

MasterScript.py

import pexpect
import cv2

try:
    # ssh connection
    child = pexpect.spawn('ssh -X pi@pislave.local')
    child.expect('pi@pislave.local\'s password:', timeout=10) 
    child.sendline('pi')
    child.expect('$')

    # run script to read and show the video feed
    while True:
        child.sendline('python3 SlaveScript.py')
        cap = child.read()
        ret, frame = cap.read()
        
        cv2.imshow('slaveCam', frame)


except pexpect.ExceptionPexpect as e:
    print(str(e))

I know that it works if I put the lines from while True to cv2.imshow in the slave script. I have a window opening and a video feed of around 1 image every 3 seconds (I don't care about performance).
However, the video feed will have to be implemented inside a kivy GUI, so I need to get the frame in my master script so that I can put it in a texture in kivy.

Is there any way to do it?

Sanico
  • 39
  • 7

1 Answers1

1

I think you are on the wrong track with pexpect. You should be using password-less login by copying your public RSA key to the slave device - then you can get rid of all the awkwardness of pexpect.

Also, I would consider using Redis. It is very fast, and lightweight and it serves integers, strings, lists, sets, hashes from memory (RAM) across a network.

Simply stuff the frames of video in Redis on the slave, either as JPEGs, or PNGs or Numpy arrays and call it latestFrame. That looks like:

redis.set('latestFrame', frame)

On the other machine, just grab latestFrame from Redis and display it. That looks like:

frame = redis.get('latestFrame')

Example here.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thank you! I will try that. I also posted on [raspberry pi exchange](https://raspberrypi.stackexchange.com/questions/137279/can-a-raspberry-pi-get-the-video-feed-of-another-through-a-nfs-server-between-th/137287#137287) and will first try to do videoCapture() by accessing the files in `/dev` (/home already works). Do you think it could work to share the dev directory? – Sanico Apr 30 '22 at 12:47
  • 1
    No, you can't share the devices in the `/dev` directory between machines - they do I/O into and out of the local kernel. – Mark Setchell Apr 30 '22 at 13:19