就是这么个东西,牛逼的狠
装手机上
装好啦
WiFi连接实时传输
有个老哥用QX10拍的珠穆朗玛峰,还是挺能打的
在API的页面,QX10和QX100放在一起,我不知道两个的代码可以混合使用吗?我测试一下。
我们就有API的列表
这里面是安卓的接口,当然还有苹果的
pip install opencv-python
pip install requests
使用这4个协议,SSDP用来让主机发现相机,HTTP来进行长时间的连接,接着json发送控制序列,我好喜欢序列这个词啊。
WiFi密码在里面
zP2EbQVr
真尼玛鬼畜,这密码。。。。
https://sourceforge.net/projects/sony-desktop-dsc-qx10/
QT4写的界面
人家的白色相机好好看
这个是最新的SDK的连接示意图
这个是以前的连接图,其实都一样
完整的函数和类集合
把显示的工作单独拿出来
在api的里面可以看到我吗感兴趣的API
第一个方法,预览画面:
结尾方法
json的例子
执行之后的回复信息
错误代码
我们先写一个关于获取视频流的方法,就好像是一个水管的接口一样
当你拿到这个数据流的时候,我们应该进行解码操作
接下来就进行解码
✓ 通过 HTTP GET 将实时视图数据作为一个数据流下载。
最小单位称为“数据包”,如下图所示。在下载过程中,这个“数据包”将被重复。
客户端应不断下载“Packet”的数据,并从一个“数据包”,并对其进行解码,并将其显示在显示器上。
由于解码时间的原因,客户端可能无法显示所有的JPEG。在这种情况下,
客户端应该跳过一些 JPEG 图像。
✓ 数据的字节序是网络字节序。
不管你看懂与否,你都能找到机器传出来的都是单帧的
你头对上是万里长征第一步,你得看看它的数据部分能不能解码出来东西。
Common Header 由以下 8 个字节构成。
✓ 起始字节 : 1 [B]
0xFF,固定
Payload type : 1 [B] 表示Payload的类型
0x01 = 对于实时取景图像
0x02 = 用于实时取景帧信息
✓ 序列号:2 [B]
帧号,2 字节整数,每帧递增
此帧编号将重复。
时间戳:4 [B]
4字节整数,单位以Payload类型表示
若Payload type = 0x01,则Common Header的时间戳单位为毫秒。开始时间可能不会从零开始,取决于服务器。
有效载荷头
有效载荷头格式将如下 128 字节。 起始码:4[B]
固定 (0x24, 0x35, 0x68, 0x79)
这可用于检测有效载荷报头。 无填充大小的有效载荷数据大小:3[B]
字节。
如果Payload Type = 0x01,大小表示Payload数据中JPEG的大小。
如果Payload Type = 0x02,大小表示Payload data中Frame信息数据的大小。
填充尺寸:1[B]
JPEG 数据后Payload 数据的填充大小,字节。
如果 Payload Type = 0x01,则报头格式如下。 保留 : 4[B]
✓ 标志 : 1[B]
该值设置为 0x00
其他值保留
保留 : 115[B]
全部固定,0x00
如果 Payload Type = 0x02,则报头格式如下。 帧信息数据版本:2[B]
帧信息数据的数据版本。
高 1 字节表示主要版本,低 1 字节表示次要版本
版本。
0x01, 0x00: 版本 1.0
客户端应该使用数据版本忽略它不理解的数据。
帧数:2[B]
帧数据的编号。
单帧数据大小:2[B]
单一尺寸的帧数据。如果数据版本为 1.0,则数据大小为 16[B]。
客户端可以使用数据大小读取每一帧。
保留 : 114[B]
全部固定,0x00
大概就是这样的,先看看头是不是合适的头,然后把下面的读了

把这个开始视频流的命令给get_payload()这个函数
在此
这个函数是仿照json的样子打包的
是不是一模一样嗷
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type
然后前端的知识来了
headers = {'Content-Type': 'application/json'}
所以是json
看语法,写的没有错
这次就更加的正确了
我们这样的发送一个数据出去
https://docs.python-requests.org/zh_CN/latest/user/quickstart.html
文档在此
拍一张照片的指令

get方法是得到一些数据
从相机得到数据,给了解码的方法
这个解码的方法解出来视频的数据给了下面得方法
显示,Numpy的库进行数据的变换,接着传给了我们的cv2,cv2使用imshow的方法显示出来
这个可能会看的清晰那么一些
上面把相机的连接,数据的解码什么的,封装了一个类。接着在写一个东西用来管理数据流的状态,比如拍张照片,停止这个事情什么的。
下面可以新建一个对象,这个对象其实
已经对上面的类进行了调用
"""QX10 interfacing code for python"""
import json
import requests
import numpy as np
import cv2
import threading
from cmd import Cmd
class LiveviewThread(threading.Thread):
running = True
def __init(self, url):
threading.Thread.__init__(self)
self.url = url
self.running = True
def run(self):
s = start_liveview()
data = open_stream(s)
while self.running:
jpg = decode_frame(data)
show_img(jpg)
data.raw.close()
cv2.destroyWindow('liveview')
def stop_running(self):
self.running = False
class yunswjPrompt(Cmd):
LVthread = LiveviewThread()
def do_t(self, args):
take_picture()
def do_loop(self, args):
for i in range(int(args)):
take_picture()
print(i)
def do_start_liveview(self, args):
self.LVthread.start()
def do_start_liveview(self, args):
self.LVthread.stop_running()
def do_quit(self, args):
self.do_stop_liveview([])
raise SystemExit
def get_payload(method, params):
return {
"method": method,
"params": params,
"id": 1,
"version": "1.0"
}
def take_picture():
payload = get_payload("actTakePicture", [])
headers = {'Content-Type': 'application/json'}
response = requests.post(
'http://10.0.0.1:10000/sony/camera', data=json.dumps(payload), headers=headers)
url = response.json()['result']
strurl = str(url[0][0])
return strurl
def get_event():
payload = get_payload("getEvent", [False])
headers = {'Content-Type': 'application/json'}
response = requests.post(
'http://10.0.0.1:10000/sony/camera', data=json.dumps(payload), headers=headers)
return response
def get_picture(url, filename):
response = requests.get(url)
chunk_size = 1024
with open(filename, 'wb') as fd:
for chunk in response.iter_content(chunk_size):
fd.write(chunk)
# LIVEVIEW STUFF
def start_liveview():
payload = get_payload("startLiveview", [])
headers = {'Content-Type': 'application/json'}
response = requests.post(
'http://10.0.0.1:10000/sony/camera', data=json.dumps(payload), headers=headers)
url = response.json()['result']
strurl = str(url[0])
return strurl
def open_stream(url):
return requests.get(url, stream=True)
def decode_frame(data):
# 解码包头
start = ord(data.raw.read(1))
if(start != 0xFF):
print('bad start byte\nexpected 0xFF got %x' % start)
return
pkt_type = ord(data.raw.read(1))
if(pkt_type != 0x01):
print('not a liveview packet')
return
frameno = int(data.raw.read(2).encode('hex'), 16)
timestamp = int(data.raw.read(4).encode('hex'), 16)
# 解码 liveview 头
start = int(data.raw.read(4).encode('hex'), 16)
if(start != 0x24356879):
print('expected 0x24356879 got %x' % start)
return
jpg_size = int(data.raw.read(3).encode('hex'), 16)
pad_size = ord(data.raw.read(1))
# 读出保留的头,就是后面还有信息
data.raw.read(4)
fixed_byte = ord(data.raw.read(1))
if(fixed_byte is not 0x00):
print('expected 0x00 got %x' % fixed_byte)
return
data.raw.read(115)
# 读出jpg
jpg_data = data.raw.read(jpg_size)
data.raw.read(pad_size)
return jpg_data
def show_img(str_jpg):
nparr = np.fromstring(str_jpg, np.uint8)
img_np = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR)
cv2.namedWindow('liveview', flags=cv2.CV_WINDOW_AUTOSIZE)
cv2.imshow('liveview', img_np)
cv2.waitKey(1)
prompt = yunswjPrompt()
prompt.prompt = '> '
prompt.cmdloop('starting qx10 control')
代码附上
这个VSCode和Pycharm比较老是觉得缺点东西
这个地方,网关有点毛病,我没有想明白。。。