Skip to content

A live stream ASCII webcam server for Raspberry Pis using websockets, written in go.

License

Notifications You must be signed in to change notification settings

leonlaser/pi-asciicam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Report Card

Raspberry Pi ASCII-Cam

pi-asciicam demo GIF

The pi-ascii-cam project allows you to create an ASCII live camera stream from a Raspberry Pi with an attached Raspberry Pi Camera or any MJPEG stream. It is utilizing raspivid to convert its MJPEG stream into an ASCII character representation and transport them over a websocket.

The servers are written in golang, the client is simply HTML/CSS/JavaScript.

Binaries

You can find binaries for Linux and MacOS in bin/.

On plattforms other than the Raspberry Pi, asciicam-server will only be able to do a conversion from MJPEG to ASCII from an external network source. See Receive an external MJPEG stream on how to do that.

I did not test all binaries. Just linux-arm and macos-amd64.

Start the ASCII stream server

./asciicam-server

You are now able to connect to a websocket on port 8000 on all network interfaces. There is already an example HTML/JavaScript client you can host: asciicam-server/example_client.html. Use a webserver of your choice on the same machine. The client will connect automatically to the websocket.

Show all possible options and defaults:

./asciicam-server --help

Serve clients from other machines

asciicam-server can server multiple clients, but a single Raspberry Pi could be quickly overwhelmed. Also you may not want to serve your stream directly from your office or home server.

The asciicam-imux is a very simple inverse multiplexer, which connects to your asciicam-server, splits the websocket stream for multiple clients and serves them.

To start a single server on an external machine just run:

./asciicam-imux -s 10.0.0.10:8000 -p 88888

-s ip and port where asciicam-server is running

-p the port you want your clients to connect to

asciicam-imux docker image

You can use the existing Dockerfile to build your own image or use the ones already available on hub.docker.com.

Run the docker image

docker run -p 9000:9000 -e PORT=9000 -e SOURCE=10.0.0.10:8000 leonlaser/pi-asciicam-imux

Receive an external MJPEG stream

The asciicam-server calls raspvid directly and uses its MJPEG stream on stdout to generate the ASCII frames.

A Raspberry Pi Zero is quickly overwhelmed when converting 10 frames per second or more and serving a websocket connection.

To remove the load of converting frames, you can use your Raspberry Pi to only start raspivid itself and stream the MJPEG over the network with netcat:

raspivid -o - -w 320 -h 200 -n -t 0 -cd MJPEG -fps 25 | nc -lkv4 5001

In my expierence netcat somehow gives up at some point. A better alternative for me was to use ncat, which belongs to nmap and will be installed with it:

raspivid -o - -w 320 -h 200 -n -t 0 -cd MJPEG -fps 25 | ncat -k -l 5001

Now use asciicam-server to connect and open a new websocket:

./asciicam-server -net 10.0.0.1:5001

Now your Raspberry Pi only sends a video stream and another machine running asciicam-server can convert your video and serve the websocket connections.

Based on your needs, your clients can directly connect to your asciicam-server or you can use asciicam-imux to scale:

-> Raspberry Pi running raspivid streams to -> a Machine running asciicam-server serving a websocket, which gets distributes by -> n-Machines running asciicam-imux in a docker swarm or using a loadbalancer for your clients to connect to.

Using an USB webcam

Because asciicam-server is able to retrieve any MPJEG stream, you can use any source and convert it to an ASCII video. Here is an example on using avconv to access you local video device and start an MJPEG stream:

avconv -f video4linux2 -s 320x200 -i /dev/video0 -r 15 -f mjpeg tcp://0.0.0.0:5001?listen

Now use asciicam-server with the -net parameter to connect.

Client

Without a client nobody can see your live stream. You can use two different files. As mentioned earlier, there is a really simple client to show you what is going on: asciicam-server/example_client.html.

webclient/webclient.html is a bit more advanced, allowing you to connect to any websocket stream by entering an address. It is using requestAnimationFrame() and shows the frames per second, received through the websocket connection. It is very helpfull for debugging your setup.

Build

This section is mostly for myself. But if you want to built your own setup for streaming your video feed, want to modify the sources and deploy them on different machines, help yourself:

Compile go sources

See makefile.

Build docker images

See makefile.

But why?

I was looking for project to learn more about golang, Docker, Docker Swarm and Raspberry Pi.

Thanks

A thank you goes to idevelop for his awesome ascii-camera. My image to character conversion is simply a port of his ascii.js, which features some links to every step of his image pre-processing before converting it to actual characters.