Setup
I didn't have a webcam, but I did have a MiniDV camcorder that hooked in through the FireWire port, which my computer happened to have a few of.
Lastly, because I was sort of far away from my router, I set up a wireless connection using a USB WiFi adaptor. Driver installation wasn't too bad and my adaptor was compatible with Linux!
Script
To run the transmit script: I made sure to have a full install of GStreamer through my package manager. The script its self was pretty simple and simply took input from the camera, compressed it as a series of JPEG images and sent it out as a TCP stream over port 6000. The IP address my router assigned my streaming computer was 192.168.1.105, this address will vary based on when the router registers a PC.
I stored this script in the file: network-stream.sh and ran the script, in the terminal, using sh network-stream.sh, once I navigated to the directory I stored it in.#!/bin/bashgst-launch-0.10 -v dv1394src ! dvdemux ! dvdec ! ffmpegcolorspace ! videoscale ! videorate ! video/x-raw-yuv, height=240, width=427, framerate=3/1 ! jpegenc ! multipartmux ! tcpserversink host=192.168.1.105 port=6000
Network
Receiving the video over the Local Area Network is very easy. All I really have to do is open VLC on a computer, on the local network, and then type in tcp://192.168.1.105:6000.
To receive the stream over the internet is a more involved process which requires setting up port forwarding to allow access, for this application, to the Wide Area Network.
My router's IP address, on the network, is 192.168.1.1. Different routers will have different IP addresses. On the administration page, I set up port forwarding along port 6000 for the TCP protocol. All routers are different, but most will support doing this in one way or another.
Don't forget to set up port forwarding on the modem as well. The process should be similar to setup on the router. Again, you will need to find the network IP address for your modem. Mine was 192.168.0.1. Like with the router, IP address will vary by modem.
Once you have that set up, a user can access your camera through the Internet, all they'll need is the IP address to your house. Unfortunately, most ISPs dynamically assign IP addresses to their customers, the IP address you have will change. If that's the case, you will not be able to access your camera.
The solution to this comes from DNS forwarding services. Basically they can give you an internet domain like my-domain.com. The domain is an alias for your IP address. They will give you a program to run on your computer that updates the IP address your domain is associated with, every time it changes.
In 2012, a decent free DNS forwarding service I've come to use is no-ip.com they haven't yet forced their users to pay for their basic service or only provide a limited time trial. So their service is a good one to use to experiment with servers and web technology if you're not sure you want to invest much money yet.
Testing
Once the DNS forwarding service, network port forwarding and security camera server have been set up: an Internet stream is conceivable.
If you go into VLC, you can open up the network stream in a very similar maner to opening it up on the LAN, this time you just change the address in VLC: tcp://my-domain.no-ip.org:6000.
You should see the output of the security camera.
My server has to really crank along to keep up with producing the stream:
The CPU doesn't have too many clock cycles left and the network output, going out at about 100 KiB/s is about as fast as my internet can take.
Future Work
There are a number of issues with this streaming setup. The most obvious one is the slow frame rate of 3 frames per second. This is a consequence of sending series of JPEG images over the internet, they take about 100 KiB/s to stream. On my internet this is about the upload limit. Faster internet connections can provide a higher frame rate because they can provide more data throughout.
Another issue is the quality. 240p is barely acceptable. A more appropriate level of definition would be 360p or 480p.
Both these issues stem from the fact that I'm streaming a JPEG sequence over TCP. First of all, JPEG sequences don't do compression between frames, each frame is individually packaged. This really makes the stream a lot larger that it has to be, especially if the camera is sitting still. A better solution would be to broadcast an actual video stream using codecs like H.264 or VP8. These can provide higher quality and frame rates. I just need to find out how to directly stream these types of formats directly to VLC from GStreamer over the Internet.
Another problem is the use of TCP. TCP is not ideal for live streams because it scales how fast it transmits over the lines of the Internet and guarantees packet transmission. 100% packet transmission is not required for this application. Although TCP is great for transmitting static media over the internet, UDP is better for streaming media because it's designed around sending packets in real time as opposed guaranteeing 100% packet transmission. With TCP, if there's not enough bandwidth for the stream, the stream will become increasingly delayed, with UDP if there isn't enough bandwidth for the stream, packets will be dropped, the image quality will look worse, but it will be in real time. The only problem with UDP is that it doesn't scale like TCP does. ISPs can't make UDP take less bandwidth, like TCP, because all it does is throw out packets. As a result, some ISPs do not allow home internet users the ability to broadcast UDP streams. They can't control it. So in this, initial attempt, I used TCP, even though I'd like to have a UDP stream working.
No comments:
Post a Comment