A camera that streams MJPEG into your HMI does not hand out unlimited seats. Compact network cameras document a fixed number of simultaneous stream sessions, four being a typical printed value. The first client connects and shows video; every later client asks the camera for its own connection and gets refused, even though the network, the server and the URLs are all fine. The same wall meets clients at a remote site, which cannot reach the camera's plant address at all. This guide shows you how to count the sessions, fetch the stream once on your gateway, encode the camera's login inside the proxy URL, and verify that every client, local or remote, now gets the same live picture.
Why does the second HMI client show no video?
The second client shows no video because the camera has already handed out its stream sessions: your first viewer holds one HTTP connection to the camera, every later client asks for another one, and a compact network camera refuses anything past its printed cap.
The mechanism sits on the wire. Each HMI client is a separate program on an operator station, and its camera viewer opens its own HTTP connection to the camera's stream URL, then reads the continuous multipart response, JPEG frame after JPEG frame. Four stations are four sessions. A camera whose data sheet documents four simultaneous connections is finished at four: later requests are dropped or never answered, so the fourth operator sees an empty frame, or a log line claiming the address is not an MJPEG stream at all.
Browsers hit the same wall, which is why four browser tabs also exhaust such a camera. Clients just fail one at a time, as operators log in across the shift. If you have seen flicker or stutter with several browser windows on one camera, that is the same per-viewer connection count wearing a different symptom — the multiple browsers on one IP camera breakdown covers that side of it.
How many connections does the camera actually allow?
Small fixed-lens network cameras print the number on their data sheets: four simultaneous stream connections is a common value and some accept only one or two, so four viewers is not a stress test, it is the whole budget.
Read the figure and treat it as the budget for direct viewers. A session is a session whether it carries 20 fps or 2, so nothing is subtracted for light use.
Then measure what one viewer really opens. Viewer components have shipped that fetch the stream and a preview still separately — two camera connections per client — which halves the budget before the second operator logs in. The test takes a minute: put the camera's status or online-client page on a second screen, open one HMI client, and read the session count. One is healthy. Two or more means every multiplier below doubles.
The same arithmetic applies when the source is a machine-vision camera or vision sensor publishing an HTTP stream into SCADA screens; caps there are usually higher but never absent, and the figure lives in that camera's documentation too. If you are selecting the source rather than fixing one, the smart cameras and vision sensors category is where those parts sit.
Inspection on the device, no PC
350 models · from $169.00How does proxying one stream serve every client?
Proxying turns N direct camera sessions into exactly one: the gateway fetches the MJPEG stream once and re-serves the same byte stream to every client, so ten clients cost the camera one session instead of ten.
The gateway does the fetching. Your HMI server, or any small always-on service on the plant network, requests the camera's stream URL once and re-serves the identical MJPEG byte stream under its own address to every client that asks. The camera sees one session. Clients see an ordinary MJPEG URL and cannot tell the difference, except that the fourth operator now gets video, and a client at the remote office gets it too, because it only ever talks to the gateway.
Controls engineers will recognise the shape: it is the same one-master rule a Modbus RS-485 bus follows — one client owns the device and shares the result with the rest.
Worked example. The camera documents 4 sessions. The HMI runs 4 clients. The stream is 640×480 at 10 fps with JPEG frames around 30 KB, and 25-40 KB is typical for that size at usable quality.
- Direct: 4 clients × 1 session each = 4 sessions, exactly the cap, and 4 × 2.4 Mbit/s = 9.6 Mbit/s leaving the camera; a fifth window is refused.
- Proxied: the camera serves 1 session at 2.4 Mbit/s; the gateway re-serves 4 × 2.4 = 9.6 Mbit/s to clients, about 10% of a 100 Mbit/s plant link.
| Clients fetch the camera | Clients fetch the gateway | |
|---|---|---|
| Camera sessions at 4 clients | 4, cap reached | 1 |
| Load on the camera | 9.6 Mbit/s | 2.4 Mbit/s |
| Load on the plant LAN | 9.6 Mbit/s | 9.6 Mbit/s |
| Fifth client or remote site | refused or unroutable | works |
The trade is deliberate: camera-side sessions drop to the minimum, and the marginal cost of one more viewer is only plant-LAN bandwidth on hardware you control. When the source speaks RTSP rather than MJPEG over HTTP, the same pattern exists as an RTSP restream for HMI displays.
How do you put the camera login inside the proxy URL?
Encode the inner URL's reserved characters before you nest it: the camera's ? becomes %3F and the & between user and password becomes %26, because the proxy would otherwise read them as its own query separators.
Take an address that plays directly in a browser:
http://192.168.10.50:8080/videostream.cgi?user=viewer&pwd=viewonly
The proxy receives exactly one URL, as the value of its own parameter. Left raw, the ? and & split the proxy's query and the camera address arrives truncated, which is why naive nesting fails with 401 Unauthorized. Encode the inner separators, ? to %3F and & to %26:
http://192.168.10.50:8080/videostream.cgi%3Fuser=viewer%26pwd=viewonly
Then append that after your platform's proxy address as its url parameter — gateway host, proxy port, proxy path, then ?url= and the encoded string. The proxy path is whatever your HMI server or reverse proxy publishes; the encoded inner URL is the portable part. Strict parsers want the whole inner URL encoded, : as %3A, / as %2F, = as %3D, so if the minimal encoding still comes back 401, encode everything and retry.
Two practical details. If the viewer component has its own username and password fields, fill them too — some components send their own authorization header no matter what the URL carries, and refuse to connect with the fields empty. And read the failure mode before changing anything: a 401 means the login did not survive the trip, which the IP camera 401 in the client but not the designer walkthrough sorts out, while a login that clearly works but renders nothing points somewhere other than a real MJPEG stream, the case in MJPEG viewer shows no video. The MJPEG URL with username and password guide handles the same login on the direct, unproxied side.
Which machine on the plant network runs the proxy?
Any always-on computer that can reach the camera works: the HMI gateway server is usually enough, and a fanless vision controller with several LAN ports lets you keep the camera on its own VLAN while clients enter on another.
Most plants already own the host. The HMI gateway sits on the plant network and normally reaches the camera VLAN through one routed hop or a firewall rule opened for a single address and port. A dedicated box earns its place when you want the camera network physically separate from the office network: one LAN port faces the cameras, one faces the plant, and no client ever holds a route to the camera.
The vision controllers category is built for exactly this box, fanless industrial computers with multiple LAN ports that run services unattended in a cabinet. The MV-VC2140-128G40-1T carries an Intel N-series processor, 8 GB of memory and 3-4 LAN ports, which covers one camera VLAN plus one plant uplink. The MV-VC3301H-128G66 steps up to an Intel Core i3 processor with 5+ LAN ports and 3-4 USB 3 ports. The MV-VC5525-256G70-NN adds 32 GB of memory, PoE camera ports and 8 built-in light channels for a cabinet that also drives a vision cell's lighting.
- LAN ports
- 3-4 LAN ports
- USB 3 ports
- 2 USB 3 ports
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
- LAN ports
- 5+ LAN ports
- USB 3 ports
- 3-4 USB 3 ports
A restream of a few Mbit/s is trivial load for any of these, so choose on port count, mounting and environment rather than processor.
How do you set up the proxied stream step by step?
The whole change is one proxy URL and one viewer setting; on a system that already shows video in the first client, the steps below take well under half an hour.
Have on hand: the camera's stream URL with a read-only login, a fixed address for the camera, and the right to place a configuration change or small service on the gateway.
- Confirm the ceiling. Open the camera's stream URL directly in two or three browser tabs on a plant PC; the tab that loads nothing marks the cap you are working under.
- Pin the camera's address. Reserve 192.168.10.50 as a static IP or a DHCP reservation on the camera VLAN, because the inner URL must never start moving.
- Fetch once, server-side. From the gateway, request the inner URL in a browser or a command-line HTTP client; you should see the multipart/x-mixed-replace content type and JPEG boundaries scrolling, proof of login and stream independent of any viewer.
- Build the proxied URL exactly as in the encoding section: inner URL, ? to %3F, & to %26, appended after the platform's proxy path as its url parameter.
- Point one viewer at the proxied URL in the engineering environment and confirm video.
- Point every client's viewer at the same proxied URL, deploy, and log in from two stations at once.
- Save the configuration, encoded URL and all, under the gateway's backup; a rebuild that pastes the inner URL raw is the most common way this fix quietly disappears.
Platform menus differ, the failure patterns do not. The SCADA IP camera MJPEG stream configuration troubleshooting knowledgebase page walks the common SCADA cases end to end.
How do you verify every client now gets video?
Count the camera's open sessions while you open clients: when the fourth client still shows video and the camera reports one stream session instead of four, the proxy is doing its job.
- Play the proxied URL in a plain browser; video proves the gateway-to-camera fetch and the encoding together.
- Open clients up to the real shift load, however many stations run, and watch each carry the live picture.
- Read the camera's session or online-client list between stations: one stream session, not one per client.
- Watch the gateway log: one fetch of the source, fanned out to every client, with no fresh camera-side request per client.
- Reboot the camera, then the gateway, and confirm the clients recover on their own.
If operators then report their own stations sluggish now that all four decode video, that cost sits client-side in per-frame JPEG decoding — the MJPEG viewer CPU usage analysis explains where it goes and why a browser often decodes faster than an embedded viewer.
When is one shared stream the wrong answer?
One shared stream serves one picture: if clients need different crops, different frame rates or PTZ control, or if a two-frame-per-second snapshot is good enough, another pattern fits better.
- Per-client crops or rates: a shared stream is one JPEG sequence, so a station that needs a zoomed region cannot get it from the common feed. Run the camera's second stream URL if it publishes one, count it against the cap, or move that station to polling.
- PTZ: fine for watching, but if operators steer the camera, one shared viewer has no per-client control state; put PTZ behind the gateway as well, or dedicate the camera.
- Low update rates: many monitoring windows need 1-2 fps, not 15, and a snapshot loop holds no standing session at all. The IP camera snapshot URL refresh rates set-up and the snapshot-versus-stream comparison for HMI runtimes give the polling pattern, and the stream-versus-snapshot page-performance comparison covers the same choice from the page-speed side.
Decisions by case:
- One picture for every client, several stations, maybe a remote office: proxy one fetch; it is an afternoon's work.
- A different crop or rate per station: per-client snapshot polls at 1-2 fps, or a second camera aimed at the detail.
- An RTSP source instead of MJPEG over HTTP: an RTSP restream on the gateway, same one-fetch idea.
- Closed-loop machine guidance: never share this stream; guidance gets its own camera and its own link.
If the proxy needs a dedicated home, the vision controllers covered above are sized for it. For a quotation on the box and the cameras feeding it, /quote/ takes the stream count and station list, and /contact/ takes the open questions first.
Questions
How much latency does the shared stream add?
One extra hop through a switched plant network adds tens of milliseconds, well below the 100 ms between frames of a 10 fps stream, so the picture looks unchanged. The stream stays live. The one place this matters is closed-loop machine guidance: do not route that through an HMI viewer at all, regardless of proxying.
What frame size and frame rate should the shared stream use?
Size for the smallest screen that shows it. 640×480 at 10 fps costs about 2.4 Mbit/s per viewer in the worked example; doubling resolution roughly quadruples JPEG size at the same quality, so 1280×720 lands nearer 6-7 Mbit/s. Start at 10 fps, confirm operators can judge motion, and raise it only if they cannot.
Can the camera's own web page stay open while the proxy runs?
Budget it in. If the camera allows four sessions and the proxy holds one, three remain for the camera's setup pages and live view, which usually count as sessions while a page is streaming. Close the camera's browser view when commissioning ends, or the next direct viewer hits the cap you just explained away.
Does the proxy also serve clients at another site?
That is its second job. Remote clients reach the gateway's published address over the corporate network, and the gateway alone reaches the camera, so the camera never needs an internet route. Keep only the gateway exposed, behind your usual VPN or reverse-proxy login, and leave the camera's credentials inside the encoded inner URL.
What happens when the camera reboots mid-shift?
The gateway's fetch dies and every client freezes at once, which is at least easier to diagnose than four separate failures. Run a small supervisor on the gateway that watches the fetch and reconnects on drop, and let clients retry the proxied URL on a timer; recovery is then one reconnect instead of four, with no operator action.


