Git Product home page Git Product logo

mjpeg-proxy's People

Contributors

keschercode avatar vvidic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mjpeg-proxy's Issues

Chunkers not ending when HTTP HEAD requests are made

I've recently noticed an issue where mjpeg-proxy would no longer realize that connections have ended.
I'm using it behind an NGINX reverse proxy.

sudo bandwhich -i eth0 reveals:
image
(Only small poll connections, nothing related to mjpeg-proxy, is hitting NGINX)
The log of my systemd unit for mjpeg-proxy reveals the following:
image
This stays true even when I stop NGINX entirely - mjpeg-proxy will still think those connections are open, even though nothing is connected to it anymore.

Pubsub writes HTTP 200 status code even if something is wrong with the stream.

See title.

$ mjpeg-proxy -source http://example.com
chunker[/]: serving from http://example.com
server: starting on address :8080
pubsub[/]: added subscriber 127.0.0.1:37456 (total=1)
chunker[/]: connecting to http://example.com
pubsub[/]: failed to start chunker: expected multipart media type: text/html; charset=UTF-8
pubsub[/]: removed subscriber 127.0.0.1:37456 (total=0)
$ curl http://localhost:8080 -v
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 04 Jan 2021 00:05:28 GMT
< Content-Length: 68
< Content-Type: text/plain; charset=utf-8
< 

--b17532825b4bfd3e0683422f4a0e6244ef58ac1be81d752b510b2d248538--

This is possibly a regression. The same thing is happening with timeouts (when using something like "http://this-host-does-not-exist.faketld/video.mjpg" as source).

Is this append needed?

Here you are using append, but you are not providing other arguments to append.
I also compared the address returned and it is the same of the original data.
So why did you use it?

case pubChan <- append(data):

Reduce tcp buffer size to keep viewers with slow connection real time (sending less FPS)

Hi! Congrats for this small but very useful project.

It was exactly what I was looking for: pub/sub mjpeg proxy.
I made a similar solution some years ago in python for raspberry picamera
BigNerd95/picamera@f723b08#diff-9dc379f8ac02d2f947ab8b7e67be6877ae0ca646f31a475b0169867e105f91edR112

Anyway my question is:

  • how to keep real time even slow clients?

If a client has a very slow connection, this method sends less frame than the original FPS (which is what I want), but due to tcp buffer (I think) the stream is not real time, because even if you use unbuffered channel, the thread sending frame to a client is not blocking during the tcp send, so it will keep reading frame from the publisher channel until the tcp buffer is full.
Only then it will start to drop frame.

I think a possible solution is to reduce the tcp buffer size to a size similar of a single frame, so it will start dropping frame as soon as possible if the viewer connection is too slow to handle the original FPS.
Do you have other ideas?

401 Unauthorized (digest?)

I can access my Dahua IPCam directly via http://guest:[email protected]/cgi-bin/mjpg/video.cgi?channel=1&subtype=1.
But ./mjpeg-proxy -source "http://192.168.1.108/cgi-bin/mjpg/video.cgi?channel=1&subtype=1" -username guest -password guest fails with:

chunker[/]: connecting to http://192.168.1.108/cgi-bin/mjpg/video.cgi?channel=1&subtype=1
pubsub[/]: failed to start chunker: request failed: 401 Unauthorized

./mjpeg-proxy -source "http://guest:[email protected]/cgi-bin/mjpg/video.cgi?channel=1&subtype=1" fails the same way.

PS: The autorization method of the camera is digest, not basic.

streams kept open unexpectedly

hey everybody. first of all thx for this piece - really helps me with a rather annoying ip camera.

so, my setup is pretty normale I guess, I'm starting mjpeg-proxy like this:

./mjpeg-proxy --bind [::1]:5500 --rate 16.0 --source "http://mycam/control/faststream.jpg?stream=full&fps=16.0" > /dev/null 2>&1 &

I'm serving it with Nginx like this:

        location /stream {
                proxy_pass http://[::1]:5500;
        }

on my client (iPhone) I've added an img tag with the correct src.

problem ist now, after some timeout, the stream stops as expected and the imp tag's content is empty - so I don't see anything again.
As a solution I've added some eventListeners and I remove the src or add it back in on visibilitychange events.

now I can brute force mjpeg-proxy so to speak: when switching away from my client tab and switch back to it, I can see in the PubSub log, that each cycle adds a new Subscriber and doesn't close the not longer consumed one. I tried several things including remove the complete imp node from the DOM but I can't find a way to tell mjpeg-proxy that a particular consumer is gone.
"naturally" there is some kind of timeout happening if I stay away long enough from the tab/safari eventually all subscriber cancel the subscription - I can trigger the same with closing the tab or force-quitting Safari.

so, I'm not sure what else to do to further debug this so I thought you guys might be interested and might help me, please :)

let me know if I could provide additional information - disclaimer: I'm not a go developer.

If you have any other suggestions how to reliably (reconnecting) render a MJPEG stream please let me know.

Panic -> crash on i/o timeout

mjpeg-proxy currently panics when a source stream is not available due to a close of a closed channel.

server: starting on address unix:/run/mjpeg-proxy/socket
pubsub[/wc-lazy-lounge.mjpg]: added subscriber [REDACTED] (total=1)
chunker[/wc-lazy-lounge.mjpg]: connecting to http://[REDACTED]/mjpg/video.mjpg
server[/wc-lazy-lounge.mjpg]: stream failed
pubsub[/wc-lazy-lounge.mjpg]: failed to start chunker: Get "http://[REDACTED]/mjpg/video.mjpg": dial tcp [REDACTED]: i/o timeout
pubsub[/wc-lazy-lounge.mjpg]: added subscriber [REDACTED] (total=2)
chunker[/wc-lazy-lounge.mjpg]: connecting to http://[REDACTED]/mjpg/video.mjpg
server[/wc-lazy-lounge.mjpg]: stream failed
pubsub[/wc-lazy-lounge.mjpg]: failed to start chunker: Get "http://[REDACTED]/mjpg/video.mjpg": dial tcp [REDACTED]: i/o timeout
panic: close of closed channel
goroutine 13 [running]:
main.(*PubSub).stopSubscribers(0xc00006a700)
        pubsub.go:133 +0x85
main.(*PubSub).doSubscribe(0xc00006a700, 0xc0001be000)
        pubsub.go:126 +0x298
main.(*PubSub).loop(0xc00006a700)
        pubsub.go:94 +0x245
created by main.(*PubSub).Start
        pubsub.go:71 +0x3f

I currently work around this issue by restarting the process upon a crash, but I suppose this issue needs to be resolved so other streams don't get killed by this crash.

Add info endpoint

This HTTP endpoint could return the amount of connected clients per stream in JSON format. We're using mjpeg-proxy for the camera in our hackerspace, and it's nice to know if somebody is watching, that way, we can wave to them.

For example, on /api//info

{
'connections': {
  'stream1': 3,
  'stream2': 5
  }
}

I'm willing to implement this myself, but I'd first like to ask what you think of this, so I don't spend time coding a feature that you don't want in the codebase.

No data returned, response 'pending'

I feel like I'm missing something, so forgive me if this is obvious.

I have 2 cameras that I want to proxy. I tried creating a JSON file with their sources. When I run ./mjpeg-proxy --sources sources.json I see it starting, but nothing ever gets returned from the connections to localhost:8080/camera1 or localhost:8080/camera2:

chunker[/camera1]: serving from http://192.168.2.139/mjpg/1/video.mjpg
chunker[/camera2]: serving from http://192.168.2.139/mjpg/2/video.mjpg
server: starting on address :8080
pubsub[/camera1]: added subscriber [::1]:58014 (total=1)
chunker[/camera1]: connecting to http://192.168.2.139/mjpg/1/video.mjpg
chunker[/camera1]: started

In the browser, it just blocks like this forever:

Screen Shot 2022-03-01 at 8 17 49 PM

If I hit my cameras (which work) I get back a response like this:

curl -I http://192.168.2.139/mjpg/2/video.mjpg
HTTP/1.0 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Connection: close
Content-Type: multipart/x-mixed-replace; boundary=--myboundary

What am I missing?

Some DLINK camera fail the content type check

I came across a dlink camera who's content type is multipart/x-mixed-replace;boundary=video boundary--

This fails to parse as the -- is not valid unless its in quotes.
Thus we need a way to sanitize the header to get ``multipart/x-mixed-replace;boundary="video boundary--"` (quotes added)

The following might be sufficient

func SanitizeContentType(s string) string {
    if strings.HasSuffix(s, "-") {
        // Boundary is not escaped
        segments:= strings.Split(s, "boundary=")
        formatted := segments[0] + "boundary=\"" + segments[1] + "\""
        return formatted
    }
    return s
}

Boundary changes with every request

Is this intended? If so, could you add a options to make it fixed?
The boundary of my camera is --myboundary. mjpeg-proxy uses a different boundary for every request.

eg:

multipart/x-mixed-replace; boundary=97fe87f7600ea95da17778fce99c9d72218ff1513e778ee3892c60081cef
multipart/x-mixed-replace; boundary=c690fd9c03c8d4cf408809d70a0ea8eec88b763f1f206fc173f132d9ff07

Also, I checked the response, and apparently the boundary used in the stream have "--" before, while the random boundary in the content-header does not. Maybe this is what causes #14 (comment) .

eg:
The content-header is:

multipart/x-mixed-replace; boundary=97fe87f7600ea95da17778fce99c9d72218ff1513e778ee3892c60081cef

but the stream actually uses:

--97fe87f7600ea95da17778fce99c9d72218ff1513e778ee3892c60081cef

Connecting directly to my camera the boundary in the content-type is --myboundary and --myboundary is actually used in the stream.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.