Quantcast
Viewing latest article 8
Browse Latest Browse All 52

Pulling H264 video from an IP camera using Python

IP cameras have come a long ways, and recently I upgraded some old cameras to these new Lorex cameras (model LNB2151/LNB2153) and I'm very impressed.

These cameras record 1080p wide-angle video at 30 frames per second, use power over ethernet (PoE), can see when it's dark using builtin infrared LEDs and are weather-proof. The video quality is impressive and they are surprisingly inexpensive. The camera can deliver two streams at once, so you can pull a lower resolution stream for preview, motion detection, etc., and simultaneously pull the higher resolution stream to simply record it for later scrutinizing.
After buying a few of these cameras I needed a simple way to pull the raw H264 video from them, and with some digging I discovered the cameras speak RTSPand RTPwhich are standard protocols for streaming video and audio from IP cameras. Many IP cameras have adopted these standards.

Both VLCand MPlayercan play RTSP/RTP video streams; for the Lorex cameras the default URL is:

  rtsp://admin:000000@<hostname>/PSIA/Streaming/channels/1.

After more digging I found the nice open-source (LGPL license) Live555 project, which is a C++ library for all sorts of media related protocols, including RTSP, RTP and RTCP. VLCand MPlayeruse this library for their RTSP support. Perfect!

My C++ is a bit rusty, and I really don't understand all of Live555's numerous APIs, but I managed to cobble together a simple Python extension module, derived from Live555's testRTSPClient.cpp example, that seems to work well.

I've posted my current source code in a new Google code project named pylive555. It provides a very simple API (only 3 functions!) to pull frames from a remote camera via RTSP/RTP; Live555 has many, many other APIs that I haven't exposed.

The code is thread-friendly (releases the global interpreter lock when invoking the Live555 APIs).

I've included a simple example.pyPython program, that shows how to load H264 video frames from the camera and save them to a local file. You could start from this example and modify it to do other things, for example use the ffmpeg H264 codec to decode individual frames, use a motion detection library to trigger recording, parse each frame's metadata to find the keyframes, etc. Here's the current example.py:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
importtime
importsys
importlive555
importthreading

# Shows how to use live555 module to pull frames from an RTSP/RTP
# source. Run this (likely first customizing the URL below:

# Example: python3 example.py 10.17.4.118 1 10 out.264
iflen(sys.argv) !=5:
print()
print('Usage: python3 example.py cameraIP channel seconds fileOut')
print()
sys.exit(1)

cameraIP = sys.argv[1]
channel = sys.argv[2]
seconds =float(sys.argv[3])
fileOut = sys.argv[4]

# NOTE: the username & password, and the URL path, will vary from one
# camera to another! This URL path works with the Lorex LNB2153:
url ='rtsp://admin:000000@%s/PSIA/Streaming/channels/%s'% (cameraIP, channel)

fOut =open(fileOut, 'wb')

defoneFrame(codecName, bytes, sec, usec, durUSec):
print('frame for %s: %d bytes'% (codecName, len(bytes)))
fOut.write(b'\0\0\0\1'+bytes)

# Starts pulling frames from the URL, with the provided callback:
useTCP =False
live555.startRTSP(url, oneFrame, useTCP)

# Run Live555's event loop in a background thread:
t = threading.Thread(target=live555.runEventLoop, args=())
t.setDaemon(True)
t.start()

endTime = time.time() + seconds
while time.time() < endTime:
time.sleep(0.1)

# Tell Live555's event loop to stop:
live555.stopEventLoop()

# Wait for the background thread to finish:
t.join()


Installation is very easy; see the README.txt. I've only tested on Linux with Python3.2 and with the Lorex LNB2151 cameras.

I'm planning on installing one of these Lorex cameras inside a bat house that I'll build with the kids this winter. If we're lucky we'll be able to view live bats in the summer!

Viewing latest article 8
Browse Latest Browse All 52

Trending Articles