-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpysecuritycam.py
146 lines (126 loc) · 4.3 KB
/
pysecuritycam.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python
from __future__ import print_function
from getpass import getpass
# Not tried yet:
# - pip install IpCamPy
# - <https://stackoverflow.com/questions/49978705/
# access-ip-camera-in-python-opencv>
import io
import requests
import sys
import pygame as pg
from requests.auth import HTTPBasicAuth
if sys.version_info.major >= 3:
from urllib.request import urlopen
else:
# Python 2
from urllib2 import urlopen
# initialize pygame
# image_url = url
# import http
# try:
# image_str = urlopen(image_url).read()
# except http.client.InvalidURL:
# # Hide the exception, since invalid URL may contain password after
# # colon instead of port.
# print("The URL is incorrect (colon must be followed by port#)")
# sys.exit(1)
# - urlopen is only possible if no authentication (the url must have a
# port not a password after ":" if any ":")
# for other "magic url formats, see
qualities = ["Motion", "Standard"]
resolutions = ["640x480", "320x240"]
quality = qualities[0]
resolution = resolutions[0]
ip = input("IP: ")
username = input("Username: ")
password = getpass()
# NOTE: http://{u}:{p}@ format will not work with urlopen.
# See HTTPBasicAuth further down instead.
url = "http://{ip}/SnapShotJPEG?Resolution={r}&Quality={q}".format(
ip=ip,
r=resolution,
q=quality
)
# See <https://www.daniweb.com/programming/software-development/code/
# 493004/display-an-image-from-the-web-pygame>
pg.init()
pg.display.set_caption("PySecurityCam by Poikilos")
resolution_pair = resolution.split("x")
resolution_pair = int(resolution_pair[0]), int(resolution_pair[1])
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
screen = pg.display.set_mode(resolution_pair, pg.RESIZABLE)
def show_error(msg, color=red):
# print(msg, file=sys.stderr)
font = pg.font.Font('freesansbold.ttf', 16)
# render(text, antialias, color, background=None) -> Surface
lines = msg.split("\n")
textRect = None
for line in lines:
text = font.render(line, True, color, black)
if textRect is None:
textRect = text.get_rect()
textRect.center = (
resolution_pair[0] // 2,
resolution_pair[1] // 2
)
else:
textRect = textRect.move((0, text.get_rect().height))
screen.blit(text, textRect)
image = None
ok = None
def show_next():
global image
# urlopen doesn't work since security cameras require http authentication.
# See <https://stackoverflow.com/questions/24835100/
# getting-a-file-from-an-authenticated-site-with-python-urllib-urllib2>
r = None
if image is None:
if ok is None:
show_error("Loading {}...".format(ip), color=(255, 255, 255))
pg.display.flip()
try:
r = requests.get(url, auth=HTTPBasicAuth(username, password))
except requests.exceptions.ConnectionError:
screen.fill(black)
show_error("The URL is unreachable.")
return False
# See <https://stackoverflow.com/questions/31708519/
# request-returns-bytes-and-im-failing-to-decode-them>
if r.status_code == 200:
image_str = r.content
image_file = io.BytesIO(image_str)
# (r, g, b) color tuple, values 0 to 255
# create a 600x400 white screen
screen.fill(black)
# load the image from a file or stream
try:
image = pg.image.load(image_file)
except Exception as ex:
msg = str(ex)+":\n Invalid URL or login"
screen.fill(black)
show_error(msg)
return False
# image, position
screen.blit(image, (0, 0))
# nothing gets displayed until one updates the screen
# start event loop and wait until
# the user clicks on the window corner x to exit
else:
screen.fill(black)
show_error('{}: Login is bad apparently'
' otherwise get correct url from\n'
'http://www.ispyconnect.com/man.aspx?n=panasonic&page=5#'
''.format(r.status_code))
# bad login, otherwise an error would have occured earlier
return False
return True
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
raise SystemExit
ok = show_next()
pg.display.flip()