Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ To this:

If there is any issue, please check on our [Discord server](https://discord.gg/uGYMNByeTH), some people might help you there. You can also consult the [DigiView Wiki.](https://github.com/fpvout/fpvout.com/wiki)

## Experimental
- The WiFi module can be used to pipe the USB from the goggles to a WiFi client. This can allow devices that are unsupported by libUSB (iOS) to act as a screen. There is currently no service setup up for this. See fpvout-stream-listen.py for more details.

## Known Issues
- Do not plug into the Pi until after video is showing in your goggles.
- If you need to power cycle the air unit, you may need to replug the USB cable in order to re-establish the stream.
Expand Down
20 changes: 19 additions & 1 deletion Scripts/fpvout-start.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,22 @@ export DISPLAY=:0;

cd /home/fpvout/Scripts/fpv-c/

./fpv-video-out | /opt/vc/src/hello_pi/hello_video/hello_video.bin
# If there is no display connected don't start streaming with fpv-video-out.
# At best it's a waste of resources, at worst it will prevent the WiFi
# stream from obtaining the USB connection.
#
# NOTE This is pretty poorly tested (and understood by me). I don't even
# have an HDMI cable for this PI right now, so I can't test the case
# where the display is available. I also suspect that this wouldn't
# work with composite video out, which is a pretty valid use case
# for using an old analog monitor (like the one sitting in my garage).
# I could probably embed a PI zero inside of that display and get a
# high quality but low res stream for passengers.
displayStatus=$(/usr/bin/tvservice -s)
displayDetect="[TV is off]"
if [[ "$displayStatus" == *"$displayStatus"* ]]; then
echo "No HDMI display connected, not streaming to screen. $displayStatus"
else
echo "HDMI display detected, streaming to screen. $displayStatus"
./fpv-video-out | /opt/vc/src/hello_pi/hello_video/hello_video.bin
fi
43 changes: 43 additions & 0 deletions Scripts/fpvout-stream-listen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/python3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with python - but does this script need to be called from somewhere to start?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this a very basic server. It waits for a connection and when it gets one it pipes the data from the goggles to the remote client on line 38. It can only handle 1 client at a time because the client takes over the connection to the goggles.

Originally I had wanted to implement this as an inetd service (and the script wouldn't have been required) but inetd isn't installed anymore. I think that the mechanism used to launch fpv-video-out when the USB connection to the goggles is made would be able to launch on an incoming connection, but I wasn't familiar with that, and this was a quick proof of concept.

I thought that I did set up something to launch this automatically, but I don't remember what it is, and it doesn't look like I comitted it. I'll have to check my image to see exactly what I did.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use inetd, it's all about systems for many years now.

Also pipelining video to a webserver might be faster if threaded and called via go or node maybe, or somehow wrap lighttpd or other super small and fast server into the mix.

Sadly I lack time to really write a good doc on this, but if you dig hard, at least find ways to multithread it in python, etc.

I want to see this done, but I'd likely bodge out a crap c++ implementation, and then do it in rust (that's my daily driver language) but I'm so backlogged now. :(

#
# A server that waits for connections and pipes the output of fpv-c to the
# remote client. The client will be an h264 stream (without an MP4 wrapper)
# so clients will need to act accordingly. To view the stream in VLC open
# a url: tcp/h264://fpvout.local:8081
#
# This service can be used to create a simple device that will clients such
# as iOS to connect to DJI FPV goggles. I haven't tested yet, but I suspect
# even a Pi Zero could handle it since it's just redirecting USB to Wifi and
# not even decoding the video. That said my Pi 4 has horrible latency, so this
# may not work.

import socket
import subprocess
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the port
server_address = ('', 8081)
print('starting up on %s port %s' % server_address, file=sys.stderr)
sock.bind(server_address)

# Listen for incoming connections
sock.listen(1)

while True:
# Wait for a connection
print('waiting for a connection', file=sys.stderr)
connection, client_address = sock.accept()

try:
print('connection from %s port %s' % client_address, file=sys.stderr)

socket_input = connection.makefile('wb',0)
proc = subprocess.run(['/home/fpvout/Scripts/fpv-c/fpv-video-out'], stdout=socket_input)
finally:
# Clean up the connection
print('closed connection from %s port %s' % client_address, file=sys.stderr)
connection.close()