I want to ask how could I stream images using C# to clients which are not local.
The idea is to let users from other computers see the images coming from the webcam connected to my PC, by typing the IP of my computer to their webbrowser.
I have succeeded in making it locally - when I access the 127.0.0.1 address on my computer, it works.
I have tried using WCF, and also TcpListener:
listener = new HttpListener();
listener.Start();
HttpListenerContext context = listener.GetContext();
HttpListenerResponse response = context.Response;
System.IO.Stream output = response.OutputStream;
...
But, when I try to make it work from outside my local network - I fail to.
My question is like this:
-Do you know any library in C# which will easily let me listen to requests and answer them by a Stream? (I am trying to let browsers access the images stream which I send to them. it works nicely locally...)
-Maybe you know of a different approach which will ease the task?
-Besides, to which address should I listen when trying to broadcast to the outside world? 127.0.0.1? the address which I see on WhatsMyIp sites?
Thank you Very Much!
Webcams with built in networking typically stream images back using MJPEG/MIME multipart.
If you have a camera with built-in networking, then it most likely already supports streaming an MJPEG stream over the network. Being able to access the camera from outside your local network is a matter of configuring your home router to pass external requests (probably on port 80) to the camera's IP address (this is known as NAT configuration). The exact process for doing this will depend on your router, but it should be fairly easy to configure.
If you have a camera without networking built-in you can build a 'proxy' on your home computer that will listen for network requests from external clients, fetch images from the camera, and send the images back as parts within the response stream. Once you have the proxy written, it will be just like the network camera in terms of external access--you will need to configure your router to allow external access.
HttpListener would be a good choice for implementing the proxy. The main work here is formatting the response.OutputStream according to the MJPEG/MIME multipart convention. Here I would recommend using StreamWriter (for the textual parts) and Image.Save for the images. Keep in mind that the MJPEG response contains a combination of textual data (for the MIME/multipart headers and boundaries) and binary data (for the actual JPEG images) contained within the MIME/multipart body. If you need to support streaming to multiple clients concurrently you will also need to use threading.
As far as the IP address to use HttpListener supports a + or * notation that avoids the need to specify any IP address. For example: http://+/Stream/ See MSDN for more information.
Related
I need to stream a video which is located in a local network between two computers using C#. I am thinking to use TCP rather than UDP since I need reliability. I already build a simple program for data transfer with TCP/IP. Now I want to build a TCP communication for video streaming. Is there any sample code or suggestion for both the server and client side for that?
I already try to open video in local network and tried to encode the video same as I do on data transfer but it didn't work.
Thanks.
I am currently working on a little chat utility in C#.
The problem is I can't figure out how to scan the network for a specific port on all machines. I am currently using this method
IPGlobalProperties network = IPGlobalProperties.GetIPGlobalProperties();
IEnumerable<IPEndPoint> connections = network.GetActiveTcpListeners()
.Where(x => x.Port == ConstParams.iPort);
where ConstParams.iPort is the port I want to scan (6910 here).
The problem is that the returned values are only local ports and the "0.0.0.0" ip address...
How can I scan for all open ports (6910) on the current network?
Rather than using port scanning, I suggest you to implement a simple discovery mechanism based on multicast/broadcast communication.
During the startup the application should broadcast/multicast its IP/Port information. All running instances should respond to this message with their IP/Port information. This kind of a discovery mechanism is easy to implement, and it is both faster in runtime and more dynamic than the port scanning approach.
You should consider multicast, but rather than rolling your own, rely on an existing standard with library support, like mDNS:
http://en.wikipedia.org/wiki/Multicast_DNS
Or, since you said C#, using one of its native solutions:
http://msdn.microsoft.com/en-us/library/system.net.peertopeer.aspx
Scanning ports is a poor choice, you will most likely trigger firewalls on machines in the network to display your machine as an attacker. Any Intrusion detection systems on the networks could potentially be triggered as well. It's a lot of overhead for what you need.
I would recommend doing a broadcast using UDP or a multicast to discover other clients
http://www.codeproject.com/Articles/1705/IP-Multicasting-in-C
Another option would be to have a centralized server, either on a web server (php script, asp.net page, etc) or a web service (REST) which the chat client would connect to on start up, POSTing it's listening IP/Port, and then in turn would receive a list of all recently announced IP/Ports of the other clients on the network. You'd probably want some keep alive here, IE: the client would POST to the page every 5 minutes, if an IP does not POST for 10 minutes, it would be removed from the list.
To get the public IP of the machine, you could check out this page:
http://www.whatismyip.com/faq/automation.asp
You'd just need to send a web request to it to retrieve the IP. If you want to get the non 0.0.0.0/127.0.0.1 IP of the local interface, you can check out these posts:
Get local IP address
How do I get the Local Network IP address of a computer programmatically? (C#)
GetIPGlobalProperties only returns info about your local machine (see http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipglobalproperties.getipglobalproperties.aspx ).
To find out which other machines on the network have that port open, you'd have to iterate through the a range of IPs, attempting to connect on that port. There is no central repository to query on this.
This article describes an approach: http://www.dijksterhuis.org/building-a-simple-portscanner-in-c/
I have a working system that receives data via UDP packets sent to a fixed IP:Port and I want to use a program (some kind of proxy?) to send a copy of those packets to a new IP:Port (or a list of IP:Ports, but all inside the same LAN as the program).
Not as easy as it seems, because I need the copied packets to have the same Source IP address as the original ones.
In my research, I have found PCap.Net (WinPCap .NET wrapper) to be useful, because it can build a Packet from scratch and it supports modifying all the address fields. I have managed to capture the packets and build them. But somewhat they are not arriving at the desired destination (!?). Should I use a different PacketCommunicator to receive and send them?
Anyway, the question is not fully related to PCap.Net but to know alternative ways to achieve my desired goal. Via a free application? commercial application? Open source sample? Any other library to use?
My systems are Windows based (no Linux available here). And I have C# (.NET) experience (I can not use a C++ library, if NET bindings are not available).
Many thanks for your help
I know it's an old question, but this is the answer:
http://code.google.com/p/samplicator/
Listens for UDP and forwards it to one or more other IP addresses, optionally spoofing (the original) source IP address.
Used for forwarding netflow/sflow/syslog etc. packets.
you should think about network first. it may not be possible if traffic needs to go through router.
the original packet came through:
source->router->your server
if you are trying to sent it back out like so:
your server->router->another computer
then the router may not even accept this traffic, since it can not originate from your computer, according to routers configuration. just think about it - i could send traffic as anybody, if that was allowed.
however, in LAN that's very doable (unless you have some sort of MAC spoofing protection on your switches)
What you are trying to do is called "UDP Forwarding". You receive a UDP packet and then forward it to another host
Here is an application that does that (seems to be free)
in addition to keeping the source ip address and changing the destination ip address
you MUST swap the source and destination mac addresses.
if you send a raw packet out to your router/switch/modem, but the mac address is not addresses to it.
it will be dropped.
basicly, you have to revise every network layer your dealing with, and handle addressing approperately.
Sorry for my spelling
If you try to spoof the destination address to do things like netflow relaying you often will get blocked by anti-spoofing routers inbetween. I encountered this with AWS for example.
The solution is to take the RAW udp packet and then just send that along to your new destination inside another udp packet. When it reaches the destination you have to "unwrap" the packet and then send it to itself on the loopback interface (essentially "unwrapping").
You can do this with python code with the sockets module.
I have a piece of hardware with an embedded user control accessed by typing the device's IP Address into a web browser. The device is connected directly to my PC via x-over ethernet cable and static IP's. I need to integrate the control of the device into my C# application.
My thought was to use a packet sniffer to monitor the traffic between my PC and the device while at the same time playing with the device's controls in my web browser. Then finding out which packets that my PC is sending correspond with which controls I am using at that time. Then I can create a class of HTTP or TCP packets in my C# application and send them to the device using the Socket class.
However, I dont have much expereince with network protocols, so when I am using Wireshark to monitor the traffic between my PC and the device, I am not sure where to even start when finding out which packets do what. Does anyone have any ideas? I am open to anything. Thanks!!
EDIT:
Its hard to explain exactly what my device is, but its basically an elaborate sensor and typically used in industrial applications, so it could likely be using Modbus, which I am moderately familiar with. Do you know how I can tell which protocol is being used by examining the packets? I noticed (using Wireshark) that the packets being sent from my PC to the device occur in a pattern of 1 HTTP packet, then 5 TCP packets and repeat that same sequence as long as the control is open in my browser. Are there any resources that might give me a better understanding of what is going on?
If this is browser controlled, my first thought would be to examine the web pages the device sends to your browser and see what the browser is instructed to do when you manipulate the controls - this seems much easier than messing around with Wireshark.
Is there something I'm missing that makes this impossible (such as a Flash-based control system)? If it's just done with HTML or Javascript, and HTML POST messages or something a bit more sophisticated like Ajax, it should be relatively easy to work out the interface.
Depending on the device it will either be using a variant of the modbus protocol (http://en.wikipedia.org/wiki/Modbus) or something obscure and propriatory.
The best thing to do is to keep sending the same command to the device over and over again until you can recognise similarities in the packets.
If it is propriatory it will probably be something simple like a command/data pair or possibly an XML blob. If you're really unlucky it will be compressed or encoded but unless you're hacking a game or a cash machine this is unlikely.
Asking the manufacturer of the device if they can give you the spec often works as well.
We need to capture a live video stream from WebRTC (or any other capturing mechanism from the client webcam, even if it is not supported on all browsers, but as a PoC).
This live video needs to be handled by a server component (ASP.Net MVC / Web API), I imagine that the code on the server will look like:
[HttpPost]
public ActionResult HandleVideoStream(Stream videoStream)
{
//Handle the live stream
}
Looking for any keyword or helpful link.
We have already implemented a way to send individual frames using base64 jpg, but this is not useful at all, because there is a huge overhead of the base64 encoding and because we could use any video encoding to send the video more efficiently (send the difference between the frames using VPx -vp8- for example), the required solution needs to capture a video from the webcam of the client and send it live (not recorded) to the server (asp.net) as a stream -or chunks of data representing the new video data-.
Your question is too broad and asking for off-site resources is considered off-topic on stackoverflow. In order to avoid opinion-prone statements I will restrict the answer to general concepts.
Flash/RTMP
WebRTC is not yet available on all browser so the most widely used way of capturing webcam input from a browser currently in use is via a plugin. The most common solution uses the Adobe Flash Player, whether people like it or not. This is due to the H.264 encoding support in recent versions, along with AAC, MP3 etc. for audio.
The streaming is accomplished using the RTMP protocol which was initially designed for Flash communication. The protocol works on TCP and has multiple flavors like RTMPS (RTMP over TLS/SSL for encryption), RTMPT(RTMP encapsulated in HTTP for firewall traversal).
The stream usually uses the FLV container format.
You can easily find open-source projects that use Flash to capture webcam input and stream it to an RTMP server.
On the server-side you have two options:
implement a basic RTMP server to talk directly to the sending library and read the stream
use one of the open-source RTMP servers and implement just a client in ASP (you can also transcode the incoming stream on the fly depending on what you're trying to do with your app).
WebRTC
With WebRTC you can either:
record small media chunks on a timer and upload them on the server where the stream is reconstructed (needs concatenating and re-stamping the chunks to avoid discontinuities). See this answer for links.
use the peer-to-peer communication features of WebRTC with the server being one of the peers.
A possible solution for the second scenario, which I haven't personally tested yet, is offered by Adam Roach:
Browser retrieves a webpage with javascript in it.
Browser executes javascript, which:
Gets a handle to the camera using getUserMedia,
Creates an RTCPeerConnection
Calls createOffer and setLocalDescription on the
RTCPeerConnection
Sends an request to the server containing the offer (in SDP format)
The server processes the offer SDP and generates its own answer SDP,
which it returns to the browser in its response.
The JavaScript calls setRemoteDescription on the RTCPeerConnection
to start the media flowing.
The server starts receiving DTLS/SRTP packets from the browser,
which it then does whatever it wants to, up to and including storing
in an easily readable format on a local hard drive.
Source
This will use VP8 and Vorbis inside WebM over SRTP (UDP, can also use TCP).
Unless you can implement RTCPeerConnection directly in ASP with a wrapper you'll need a way to forward the stream to your server app.
The PeerConnection API is a powerful feature of WebRTC. It is currently used by the WebRTC version of Google Hangouts. You can read: How does Hangouts use WebRTC.
Agreed that this is an off-topic question, but I recently bumped into the same issue/requirement, and my solution was to use MultiStreamRecorder from WebRTCExperiments. This basically gives you a "blob" of the audio/video stream every X seconds, and you can upload this to your ASP.NET MVC or WebAPI controller as demonstrated here. You can either live-process the blobs on the server part by part, or concatenate them to a file and then process once the stream stops. Note that the APIs used in this library are not fully supported in all browsers, for example there is no iOS support as of yet.
My server side analysis required user to speak full sentences, so in addition I used PitchDetect.js to detect silences in the audio stream before sending the partial blob to server. With this type of setup, you can configure your client to send partial blobs to server after they finish talking, rather than every X seconds.
As for achieving 1-2 second delay, I would suggest looking into WebSockets for delivery, rather than HTTP POST - but you should play with these options and choose the best channel for your requirements.
Most IP cameras these days will use H264 encoding, or MJPEG. You aren't clear about what sort of cameras are being used.
I think the real question is, what components are out there for authoring/editing video and which video format does it require. Only once you know what format you need to be in, can you transcode/transform your video as necessary so you can handle it on the server side.
There are any number of media servers to transform/transcode, and something like FFMPEG or Unreal Media Server can transform, decode, etc on server side to get it to some format you can work with. Most of the IP cameras I have seen just use an H264 web based browser player.
EDIT: Your biggest enemy is going to be your delay. 1-2 seconds of delay is going to be difficult to achieve.