0

I am trying to stream Raspberry Pi camera, and for security reasons I'm tunneling my server through a secured server even though the client is on the same LAN. However, this resulted in horrible latency. I'm trying now to stream the video over the LAN instead of through the server. I know that browsers only allow HTTP connections over HTTPS servers only on passive elements, such as .

My server is saving the image as a local jpeg file encoded as base64:

camera = cv2.VideoCapture(0)
grabbed, frame = camera.read()
frame = cv2.resize(frame, (320, 240))
buffer = cv2.imencode('.jpg', frame)[1]
buffer = base64.b64encode(buffer)
buffer.decode('utf-8')
with open(ROOT + '/static/image.jpeg', mode='wb+') as image:
    image.write(buffer)

my client has an image tag, and a simple script to request the file saved:

<img id='img'>
<script>
  setInterval(function() {
    var myImageElement = document.getElementById('img');
    myImageElement.src = 'data:image/jpg;base64,http://10.0.0.35:8000/static/image.jpg?rand=' + Math.random();
  }, 500);
</script>

The result is a constant stream of console errors such as:

data:image/jpg;charset=utf-8;base64,http://10.0.0.35:8000/static/image.jpg?rand=0.7520646586573345:1 GET data:image/jpg;charset=utf-8;base64,http://10.0.0.35:8000/static/image.jpg?rand=0.7520646586573345 net::ERR_INVALID_URL

I have checked that the image is accessible (entered http://10.0.0.35:8000/static/image.jpg in my broswer, and haven't gotten any errors) I have also checked that the file is a base64 jpeg using an online tool. I have looked at this question but nothing there worked, I can't understand why am I getting this error, and how to solve it. Can someone please direct me in the right direction?

Dan Sheinin
  • 59
  • 10
  • Why don't you just write `myImageElement.src = 'http://10.0.0.35:8000/static/image.jpg?rand=' + Math.random();` – ozcanyarimdunya Feb 28 '19 at 07:39
  • You can set the `src` to a) the URL of an actual image *or* b) the actual base64 data. You can't do both like that. You need to 1. request the file using AJAX, 2. concat `'data:image/jpg;base64,'` and the base64 string 3. set that as `src`. –  Feb 28 '19 at 07:45
  • Which most likely means you can't do this, since AJAX also would only allow an HTTPS request, afaik. –  Feb 28 '19 at 07:56
  • @ozcanyarimdunya because then the image isn't processed as base64 – Dan Sheinin Feb 28 '19 at 08:19
  • @ChrisG as you answered yourself, AJAX isn't passive, so HTTP requests can't happen if the page is loaded over HTTPS – Dan Sheinin Feb 28 '19 at 08:20
  • Right. Which means you cannot do what you're trying to do. One thing comes to mind though: if loading a ` –  Feb 28 '19 at 08:20
  • I manged to do this with unencoded image, but it was too slow, and I only got 2 FPS – Dan Sheinin Feb 28 '19 at 08:29
  • 1
    base64 takes up more space than the original data, so it will be even slower. You should probably look for a different solution altogether. –  Feb 28 '19 at 08:32

1 Answers1

0

To solve this issue, I used 2 different solutions:

[A]: I used mjpg-streamer to stream my video to LAN mjpg-streamer is opening a local server to stream or capture images from camera on port 8080. so I've changed the src attribute of the image to:

[B]: myImageElement.src = http://10.0.0.35:8080

And that's it.

Dan Sheinin
  • 59
  • 10