Remocon documentation

You will need:
- an API key from your account on https://remocon.tv, going forward <api_key> is to be replaced with your API key. You get an API key right away by creating a robot in your account page.


Video Streaming

Video can be streamed to the service using ffmpeg to our https://stream.remocon.tv server

ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 \ -f mpegts -codec:v mpeg1video -s 640x480 -b:v 1000k -bf 0 \ https://stream.remocon.tv/<api_key>


API Overview

Our API runs through websockets and returns JSON data.

It works just like any other HTTPS API out there that you are used to, except instead of making HTTPS requests you make a websocket connection, and then interpret the JSON data that you get back.

Interpreting the JSON data is very easy as you will see examples.

This means that it's very simple to set up, to use, and it's compatible with basically everything.

In Python, and MicroPython should be similar:

# run with python3, not with python import websockets # for web sockets import asyncio import json apiKey = "<api_key>" domain = "ws://control.remocon.tv/" async def connectSocket(): url = domain + apiKey async with websockets.connect(url) as websocket: print('websocket connected to ' + url) while True: input = await websocket.recv() try: interpretData(input) except: pass def interpretData(message): #print(message) data = json.loads(message) if (data["type"] == 'keydown' and data["key"] == 87): print('W key pressed') # put your code here on what you want to do # for example you could enable a GPIO pin here # GPIO.output(17,GPIO.HIGH) elif (data["type"] == 'keyup' and data["key"] == 87): print('W key released') # put your code here on what you want to do # for example you could disable a GPIO pin here # GPIO.output(17,GPIO.LOW) elif (data["type"] == 'keydown' and data["key"] == 83): print('S key pressed') # put your code here on what you want to do elif (data["type"] == 'keyup' and data["key"] == 83): print('S key released') # put your code here on what you want to do # run loop try: while True: asyncio.get_event_loop().run_until_complete(connectSocket()) asyncio.get_event_loop().run_forever() except KeyboardInterrupt: pass except: pass

In vanilla JavaScript:

In Node.js:

// Install Websockets with // npm install --save ws const WebSocket = require('ws'); const socket = new WebSocket('ws://control.remocon.tv/<api_key>'); // Replace this with your API key! socket.on('open', () => { console.log('Connected to the WebSocket server'); }); socket.on('message', data => { const jsonData = JSON.parse(data); if (jsonData.type === 'keydown' && jsonData.key === 87) { console.log('W key pressed'); // Put your code here on what you want to do } else if (jsonData.type === 'keyup' && jsonData.key === 87) { console.log('W key released'); // Put your code here on what you want to do } else if (jsonData.type === 'keydown' && jsonData.key === 65) { console.log('A key pressed'); // Put your code here on what you want to do } else if (jsonData.type === 'keyup' && jsonData.key === 65) { console.log('A key released'); // Put your code here on what you want to do } else if (jsonData.type === 'keydown' && jsonData.key === 83) { console.log('S key pressed'); // Put your code here on what you want to do } else if (jsonData.type === 'keyup' && jsonData.key === 83) { console.log('S key released'); // Put your code here on what you want to do } else if (jsonData.type === 'keydown' && jsonData.key === 68) { console.log('D key pressed'); // Put your code here on what you want to do } else if (jsonData.type === 'keyup' && jsonData.key === 68) { console.log('D key released'); // Put your code here on what you want to do } console.log('Received data:', jsonData); }); socket.on('close', () => { console.log('Disconnected from the WebSocket server'); }); socket.on('error', (error) => { console.error('WebSocket error:', error); }); setInterval(function () {socket.send('Keep-Alive')}, 1000);

In C and in Arduino:

That's it now get working.


Raspberry Pi Example

Open two terminal windows in your raspberry pi, run the following in each of them. The first streams the video, the second gets the commands from the website to control the motor and steering for a remote control car. To control anything else you just change the commands there.

First terminal window:

ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 \ -f mpegts -codec:v mpeg1video -s 640x480 -b:v 1000k -bf 0 \ https://stream.remocon.tv/<api_key>

If that throws an error then try "sudo apt-get install ffmpeg" first, or reach out to us.

Second terminal window:

First create a file called websockets.py and copy this into it:

import RPi.GPIO as GPIO # for raspberry pi GPIO import websockets # for web sockets import asyncio import json # https://www.w3schools.com/python/python_json.asp # sending data in json format lets us send as much data # as we want and in any order apiKey = "<api_key>" domain = "ws://control.remocon.tv/" # set GPIO pin variables # the standard Raspberry Pi 4 pins are: 17, 27, 22, 5, 6, 13, 26, 23, 24, 25, 12, 16 motor = 17 servo = 27 # raspberry pi GPIO setup GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(motor,GPIO.OUT) GPIO.setup(servo,GPIO.OUT) motorPWM = GPIO.PWM(motor, 50) # servo GPIO for PWM with 50Hz # <-- might have to # play around with the frequency for the motor, # for the servo 50 should work but for the motor I am not sure motorPWM.start(0) servoPWM = GPIO.PWM(servo, 50) # servo GPIO for PWM with 50Hz servoPWM.start(7.5) async def connectSocket(): url = domain+apiKey async with websockets.connect(url) as websocket: print('websocket connected to ' + url) while True: input = await websocket.recv() try: interpretData(input) except: pass def interpretData(message): print(message) # comment this out if you don't want to see every single message data = json.loads(message) if (data["type"] == 'keydown' and data["key"] == 87): print('forward key pressed') motorPWM.ChangeDutyCycle(8) elif (data["type"] == 'keyup' and data["key"] == 87): print('forward key released') motorPWM.ChangeDutyCycle(0) elif (data["type"] == 'keydown' and data["key"] == 83): print('backward key pressed') motorPWM.ChangeDutyCycle(0) # <-- not sure if there # is a PWM duty cycle for reverse, motors # should have it but I am not sure what it is elif (data["type"] == 'keyup' and data["key"] == 83): print('backward key released') motorPWM.ChangeDutyCycle(0) elif (data["type"] == 'keydown' and data["key"] == 65): print('left key pressed') servoPWM.ChangeDutyCycle(2.5) elif (data["type"] == 'keyup' and data["key"] == 65): print('left key released') servoPWM.ChangeDutyCycle(7.5) elif (data["type"] == 'keydown' and data["key"] == 68): print('right key pressed') servoPWM.ChangeDutyCycle(12.5) elif (data["type"] == 'keyup' and data["key"] == 68): print('right key released') servoPWM.ChangeDutyCycle(7.5) asyncio.get_event_loop().run_until_complete(connectSocket()) asyncio.get_event_loop().run_forever()

Then run this in the terminal window:

sudo apt-get install python3 sudo apt-get install python3-pip pip3 install websockets pip3 install RPi python3 websockets.py # <-- this is the file we just created

And you're done, it should work. If you want to have these two run on startup then add them to the crontab file as cron jobs. The benefit of doing it this way is that you can see how it works and then customize what your Raspberry Pi does in response. When you run the websockets file it will show you every command, you can then change what's in the 'if' statements to make the Raspberry Pi do whatever you want.


How to make it run automatically on startup

Still writing this part, although you can do it with cron jobs. This is regarding the Raspberry Pi example above.

crontab -e

Why is this on Neocities rather than on some other documentation site?

It's because it's very easy to use and FOSS and ideologically good.

Last edited on 2023-06-25