使用Python获取铁通独立IP

前段时间在调试IP摄像头时偶然发现铁通也能刷出独立IP,是183开头的,一开始以为只有铁通网络能够访问,后面发现跟myexternalip.com检测的IP一致,然后IP摄像头居然可以外网访问了,于是写了个python脚本来刷独立IP。

原理很简单,每次路由器重新拨号就能改变IP,然后将路由器的IP跟myexternalip.com检测的外网IP比较,如果一致就是独立IP

我家路由器是水星MD898n(固件:V2.0_140216标准版,以下都是针对此固件,不同版本固件可能不一样),根据Chrome抓包得到每次点击 断线,都会向路由器提交 “[ACT_PPP_DISCONN#2,1,1,0,0,0#0,0,0,0,0,0]0,0\r\n”的指令,点击 连接则提交“[ACT_PPP_CONN#2,1,1,0,0,0#0,0,0,0,0,0]0,0\r\n”,这样就实现路由器重新拨号。路由器登录验证则是base验证,只不过不需要用户名而已。

路由器的IP则可以通过UPnP的方式得到,具体可以参考关于UPnP端口映射的文献。

upnp.py的实现,主要实现get_external_ip()这个函数用于获取路由器IP

import socket
import socket
import re
import urllib2
import httplib
import struct
import time
from xml.dom.minidom import parseString
from urlparse import urlparse
 
xmlLocation = ""
xmlString = ""
 
def _get_external_ip():
	global xmlLocation
	global xmlString
 
	if xmlLocation == "" or xmlString == "":
		ssdpRequest = "M-SEARCH * HTTP/1.1\r\n" + \
						"MX: 3\r\n" + \
						"HOST: 239.255.255.250:1900\r\n" + \
						"MAN: \"ssdp:discover\"\r\n" + \
						"ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n\r\n"
 
		SSDP_ADDR = "239.255.255.250"
		SSDP_PORT = 1900
 
		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
		sock.bind(('192.168.1.5', 0))
		sock.settimeout(10)
		sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		sock.sendto(ssdpRequest, (SSDP_ADDR, SSDP_PORT))
		resp = sock.recv(1024)
 
		lines = resp.splitlines()
		for line in lines:
			params = line.split(':', 1)
			if len(params) == 2 and params[0].strip().lower() == "location":
				xmlLocation = params[1].strip()
				break
		opened = urllib2.urlopen(xmlLocation)
		xmlString = opened.read()
		opened.close()
 
	GetExternalIPAddress = "<?xml version=\"1.0\"?>" + \
								"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + \
								"<s:Body>" + \
								"<u:GetExternalIPAddress xmlns:u=\"urn:schemas-upnp-org:service:{0}:1\">" + \
								"</u:GetExternalIPAddress>" + \
								"</s:Body>" + \
								"</s:Envelope>"
 
	router_path = urlparse(xmlLocation)
	dom = parseString(xmlString)
 
	service_types = dom.getElementsByTagName('serviceType')
 
	path = ""
	action = ""
	for service in service_types:
		if service.childNodes[0].data.find('WANIPConnection') > 0:
			path = service.parentNode.getElementsByTagName('controlURL')[0].childNodes[0].data
			action = "urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"
		elif service.childNodes[0].data.find('WANPPPConnection') > 0:
			path = service.parentNode.getElementsByTagName('controlURL')[0].childNodes[0].data
			action = "urn:schemas-upnp-org:service:WANPPPConnection:1#GetExternalIPAddress"
		else:
			continue
 
		conn = httplib.HTTPConnection(router_path.hostname, router_path.port)
		conn.request('POST',
			path,
			GetExternalIPAddress,
			{'SOAPAction': action,
			'Content-Type': 'text/xml; charset="utf-8"'}
		)
		resp = conn.getresponse()
		result = resp.read()
		resp.close()
		conn.close()
		dom = parseString(result)
		external_ip = dom.getElementsByTagName('NewExternalIPAddress')[0].childNodes[0].nodeValue
		if external_ip != "0.0.0.0":
			return external_ip
	return ""
 
def get_external_ip():
	while(1):
		try:
			ip = _get_external_ip()
			if ip != "":
				return ip
		except Exception, e:
			print e
		time.sleep(3)
print get_external_ip()

get_global_ip.py的实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import httplib
import urllib
import base64
import time
import re,urllib2
import traceback
import upnp
 
def Get_public_ip(): #获取真实的广域网IP
	try:
		opener = urllib2.urlopen("http://myexternalip.com/raw")
		str = opener.read().strip()
		return str
	except Exception,ex:
		print Exception,":",ex
		return None
 
def _sendhttp(data):
	conn = httplib.HTTPConnection('192.168.1.1') #注意路由器的IP,下同
	conn.putrequest('POST', '/cgi?7')
	conn.putheader("Accept", "*/*")
	conn.putheader("Origin", "http://192.168.1.1")
	conn.putheader("Referer", "http://192.168.1.1/")
	conn.putheader("Content-Type", "text/plain")
	conn.putheader("Content-Length", str(len(data)))
	conn.putheader("Cookie", "Authorization=Basic " + base64.b64encode("123456")) # 123456为路由器登录密码
	conn.endheaders()
	conn.send(data)
 
	return conn.getresponse()
def sendhttp(data):
	httpres = _sendhttp(data)
	while httpres.status != 200:
		print httpres.status
		time.sleep(2)
		httpres = _sendhttp(data)
 
	print httpres.status
	print httpres.reason
	print httpres.read()
 
if __name__ == '__main__':
	try:
		print "Global IP:" + Get_public_ip()
		print "Router IP:" + upnp.get_external_ip()
		print "Refreshing..."
		while(1):
			sendhttp("[ACT_PPP_DISCONN#2,1,1,0,0,0#0,0,0,0,0,0]0,0\r\n") #路由器断线
			time.sleep(2)
			sendhttp("[ACT_PPP_CONN#2,1,1,0,0,0#0,0,0,0,0,0]0,0\r\n") #路由器连接,完成一次重新拨号
			time.sleep(1)
			public_ip = Get_public_ip() #获取实际外网IP
			external_ip = upnp.get_external_ip() #获取路由器IP
			if(public_ip == external_ip): #比较
				print "Global IP:" + public_ip
				print "Refresh OK!"
				break
			else:
				print "Router IP:" + external_ip
				print "Global IP:" + public_ip
				print "Continue refreshing..." #不是独立IP,继续刷
		time.sleep(1000)
	except Exception, e:
		print e
		print traceback.format_exc()
		time.sleep(1000)

将两个文件放置同一个目录,运行get_global_ip.py即可,确保跟路由器处于同一子网,并且路由器没有上级路由器,路由器要开启UPnP,切记!不同的路由器只要改一下拨号部分的代码即可。

当然还有粗暴的方式,把这代码弄到树莓派,再让树莓派控制继电器开关路由器电源,路由器每重启一次就能拨号一次,只是过于粗暴体验不佳……😂😂😂😂

本文地址 http://www.shenyaocn.com/2016/09/using_python_obtain_cmcc_global_ip/

USB摄像头 app的诞生

其实写这个APP的目的是因为没钱买FPV雪花屏,所以打算用便宜的图像采集卡挂手机,把手机显示屏当FPV显示屏用。找了一个开源项目得到了驱动UVC图像采集卡的方法,顺便也可以驱动USB摄像头,再把IP摄像头这个APP里面的服务器端搞过去,然后就诞生了USB摄像头😁😁😁😁

通过USB摄像头app连接外置摄像头
通过USB摄像头App连接图像采集卡
FPV的效果

有稍微明显的延迟,使用小蚁运动相机的av输出会有0.2秒的延迟经过传输总的有0.33秒左右,用CCD摄像头则不会感觉到延迟但是我不玩穿越,而且飞得很慢,主要看前面有没障碍物(前一段时间判断错误撞电线杆,掉花丛,没事,拿起来继续飞😂),影响不大。使用小蚁运动相机的av输出会有0.2秒的延迟经过传输总的有0.33秒左右,用CCD摄像头则不会感觉到延迟。下面这张是加了OSD的效果,用App的拍照功能抓取。

用USB摄像头 app 进行FPV拍照

相比普通雪花屏可以录像,抓拍,直接分享朋友圈!

关于App

《USB摄像头》可以让你的手机通过USB-OTG接口连接USB摄像头或视频采集卡,支持录像或者拍照,甚至变成包含双向音频支持的无线IP摄像头并用于安全监控,你可以使用浏览器(例如 IE, Chrome, Firefox) 查看或者用于QQ视频聊天,当然《IP摄像头》这个APP也可以查看。它还支持用户名和密码认证,默认情况下用户名和密码都是admin,您可以在设置里面进行修改。

它支持基于运动检测的自动录像,所拍摄的录像还能自动上传到FTP服务器!

提示:仅支持UVC网络摄像头和UVC兼容设备!!!(如视频采集卡)并且需要Android 4.4及上版本(4.4以上的内核uvc驱动比较好)。
双向音频需要 IP摄像头 app 你可以从 http://app.xiaomi.com/detail/59398 下载
USB摄像头 可以从小米商店下载 http://app.mi.com/detail/338972

USB摄像头
USB摄像头
USB摄像头

要是外接摄像头的话像电视盒子比较合适,例如用电视盒子+摄像头+app来安全监控,手机的话就没什么必要外接摄像头了,采集卡还差不多。这个App同时是用来解决IP摄像头这个App不能使用外接USB摄像头的问题,如果你要用电视盒子来做安全监控,选择《USB摄像头》吧😁😁

附飞机的照片和用《USB摄像头》录制的FPV飞行的视频,风有点大,抖……

我的四轴飞行器

晒一下这个星期做的四轴

小时候就想玩航模了,苦于那时候没钱……
现在娃子有了,想想再不完以后估计没那心思了……所以两个星期前脑袋抽风,找了朋友要了基础配置……花了1K多搞了这个,制作过程就没拍了,跟网上的差不多,拍一下成品。
 F450机架+朗宇2212 KV800电机+1147桨
 APM2.8飞控,事实证明不适合有娃的或者上了年纪的折腾,好在已经爽飞。GPS还没到手,依靠里面的气压计使用定高模式飞行,很稳,油门什么的交给飞控了,我实在操作不好油门,要么一口气上天要么一下子掉下来。
 电机和桨,这桨撞了几次墙和地板没断,问了朋友,说是交了几次学费后选择的……要是打到肉,画面会很唯美
 飞控和接收机的连接,接收机的电力来自飞控,每通道三根线,两根电源一根信号。入手这些设备前一直搞不懂。
 电池连接情况,使用XT60插头,朋友推荐,事实证明不错,主要是电流承受能力好。
 无刷电机,算了一下功率可以达到100W,比一般的电扇都大。焊接那香蕉插头遭到全家反对,说焊接产生的气体会影响孩子的健康,所以提着电烙铁去单位偷偷焊接,最后还接触不良,回家被赶出去楼道补焊,顺便说下,做四轴遭到全家反对,直到起飞后。
 Lumia 925微距不行,糊了……
最后来个低空飞的视频……老婆是学校的老师……所以在学校的广场上飞,风很大,一个人拿遥控拿手机不敢飞高,最后使用一键降落。话说我也不敢飞高,1K多的东西万一摔下来或者飞没了很心疼

GPS定点飞行

GPS自动返航,途中遇到大风,降落后发现GPS松了

不懂有没朋友在这里读过书哈,话说拿着四轴在学校走很吸引眼球,航拍啥的就准备自己用703n路由器搞,配合自己编写的IP摄像头,用iPad查看录像,目前还没完成。

这篇文章在数码之家发过,图片来自那里,我的网站可以节约点空间和带宽😂😂

使用VLC播放器查看IP摄像头的H.264视频流

新版IP摄像头的H.264视频流除了可以用IP摄像头本身的查看器查看外,也能用PC上的VLC播放器查看,不过这时候只有视频没有音频。

方法简单!

点击VLC播放器的工具->偏好设置,在弹出的对话框中点击左下角 显示设置 的全部,找到 输入/编解码器->去复用器,在右侧的去复用模块选择 H264视频去复用器!最后点击保存,关闭对话框。lc1

确保设备跟PC处于同一个局域网,在设备上运行IP摄像头,点击底部的打开IP摄像头服务器。在VLC播放器上,点击 媒体->打开网络串流(N),输入IP摄像头上显示的H.264视频地址,点击播放,可能会弹出用户名和密码输入框,输入IP摄像头的用户名密码即可。缓冲一两秒后VLC就会开始播放IP摄像头传输过来的实时视频了。

VLC正在播放IP摄像头的实时视频
VLC正在播放IP摄像头的实时视频

可能会遇到不断缓冲的状况,这是因为VLC默认的H.264帧率是25帧,受限于设备和网络性能,IP摄像头可能达不到这个帧率,可以手动设置H.264的帧率。在刚才的偏好设置里面,点击 输入/编解码器->去复用器 底下,选择H264,在右侧可以找到 每秒帧数 ,可以自己尝试合适的帧数,这里选择10帧,保存,再次打开网络串流试试看。不行再改……

目前手头上的设备只有iPad mini 2和Win10 PC上的IP摄像头可以达到23帧左右,Lumia 925可以达到12~14帧,荣耀3C移动乞丐版可以达到11~12帧。

IP摄像头的H.264支持

现在三个平台的IP摄像头已经支持H.264格式的视频传输了,是MJPEG所需带宽的1/7左右。各个平台的IP摄像头版本如下,Android版本8.0、Win10 UWP版本7.0.0.0和iOS版本3.0,坑爹的是正值App Store放假,目前可以安装到的iOS版IP摄像头是2.3版,3.0版还在排队审核中……免费版倒是上架了,但是不支持H.264😂😂😂😂。

iOS版IP摄像头的H.264支持
Android版IP摄像头的H.264支持
UWP版IP摄像头的H.264支持
UWP版IP摄像头的H.264支持

同时,IP摄像头查看器默认会使用H.264视频进行传输,如果服务器端不支持H.264则会自动使用MJPEG格式(例如连接到先前版本的IP摄像头服务器或者MJPEG格式的IP摄像头)。还可以使用VLC播放器查看IP摄像头服务器的H.264视频流后续会写一篇说明

特别的Android版IP摄像头的录像和运动检测可以支持Android 4.3以下系统了,也就是不限制Android版本。4.3以下系统会使用软件编码方式实现录像和运动检测,只要机器不太老,都能流畅编解码。实测手头的荣耀3C移动乞丐版MT6582的SoC可以达到13~15帧左右,跟MJPEG差不多。感觉这个开启显示帧率后可以测试机器的性能😁😁😁😁

为什么要加入H.264支持

前一段时间折腾n2n(不懂的朋友可以谷歌、百度一下),连接了老家和本地位于内网的设备,然后就测试了一下IP摄像头的传输状况,发现MJPEG很消耗带宽,加上老家使用铁通、本地使用校园网络,速度很慢,所以就想到H.264……然后谷歌到cisco的OpenH264做软编解码(OpenH264适合做实时编码,比较容易统一各个平台,至少我不觉得目前三个平台有好用的视频实时编码API,iOS上则使用硬件编码器实现H.264编码,速度比其它平台快),发现效率很高(有neon、SSE优化),有些机器上比JPEG编码还快,然后低版本Android的H.264编码问题也解决了(心里一个梗啊)……然后新版本又诞生了😂😂😁😁

下载链接

Android版IP摄像头

UWP版IP摄像头