打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Sony-QX10 Python 连接读取视频流

Sony 相机API官网资料合集

Sony QX10 相机预告

就是这么个东西,牛逼的狠

装手机上

装好啦

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的连接示意图

这个是以前的连接图,其实都一样

  1. json解码和发送指令

  2. requests来进行HTTP协议的打包

  3. Numpy是高效的数组,搭配opencv的库使用

  4. cv2是opencv的名字

  5. 还有多线程的库

  6. cmd是调用控制台协议

完整的函数和类集合

把显示的工作单独拿出来

在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方法是得到一些数据

  1. 开始视频流这个方法返回的东西是一个strurl

  2. 然后给了打开视频流

  3. 然后下面就是解码的工作了

从相机得到数据,给了解码的方法

这个解码的方法解出来视频的数据给了下面得方法

显示,Numpy的库进行数据的变换,接着传给了我们的cv2,cv2使用imshow的方法显示出来

这个可能会看的清晰那么一些

上面把相机的连接,数据的解码什么的,封装了一个类。接着在写一个东西用来管理数据流的状态,比如拍张照片,停止这个事情什么的。

下面可以新建一个对象,这个对象其实

已经对上面的类进行了调用

"""QX10 interfacing code for python"""
import jsonimport requestsimport numpy as npimport cv2import threadingfrom 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比较老是觉得缺点东西

这个地方,网关有点毛病,我没有想明白。。。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
PC端微信HOOK并与Python对接
Python网络请求模块requests
Python接口自动化之接口依赖
Fabric动态生成主机列表和角色列表
新手也能玩的RumBot,自动智能推送内容
python接口测试:在一个用例文件中调用另一个用例文件中定义的方法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服