aiohttp框架及其常用模块

[TOC] 简介 aiohttp是一个为Python提供异步HTTP 客户端/服务端编程,基于asyncio的异步库。他的核心功能如下: 同时支持客户端使用(可以理解为request的异步执行方式)和服务端使用。 同时支持服务端WebSockets组件和客户端WebSockets组件,开箱即用呦。 web服务器具有中间件,信号组件和可插拔路由的功能。 这个可插拔的路由意思就是说,你可以在代码运行的过程中增加某个接口,或者减少某个接口。 安装方式: pip install aiohttp 客户端例子: import aiohttp import asyncio import async_timeout async def fetch(session, url): with async_timeout.timeout(10): async with session.get(url) as response: return await response.text() async def main(): async with aiohttp.ClientSession() as session: html = await fetch(session, 'http://python.org') print(html) loop = asyncio.get_event_loop() loop.run_until_complete(main()) 服务端例子: from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(text=text) app = web.Application() app.router.add_get('/', handle) app.router.add_get('/{name}', handle) web.run_app(app) 常见扩展模块 模块名称 描述 aiohttp_session 处理用户会话 aiohttp-session-mongo aiomysql aiopg aioredis aiohttp_cors 解决跨域问题 aiojobs aiohttp_jinja2 aiobotocore aws文件存储服务器的异步模块 pytest-aiohttp aiohttp-swagger3 aioelasticsearch aiologstash aiokafka 更多可以去aio-libs github官方仓库查看 https://github.com/aio-libs ...

January 30, 2019

aiortc

[TOC] aiortc aiortc是 WebRTC 和 ORTC 的Python异步实现。 install apt install libavdevice-dev libavfilter-dev libopus-dev libvpx-dev pkg-config # ffmpeg >= 3.2 pip install aiortc example from aiortc import RTCPeerConnection, RTCSessionDescription from aiortc import VideoStreamTrack async def offer(paramse): # 解析 offer request_offer = RTCSessionDescription( sdp=params['sdp'], type=params['type']) # 创建一个连接class pc = RTCPeerConnection() pcs.add(pc) # 监听数据通道 @pc.on("datachannel") def on_datachannel(channel): # 监听接收数据 @channel.on("message") def on_message(message): message_recieve = json.loads(message) print("message_recieve:{message_recieve}") # 监听断开连接 @pc.on('iceconnectionstatechange') async def on_iceconnectionstatechange(): print(f'ICE connection state is {pc.iceConnectionState}') if pc.iceConnectionState == 'failed': await pc.close() pcs.discard(pc) @pc.on('track') def on_track(track): print('Track %s received' % track.kind) if track.kind == 'audio': # 接收语音数据 frame = await audio_track.recv() pass elif track.kind == 'video': local_video = VideoTransformTrack(track) pc.addTrack(local_video) @track.on('ended') async def on_ended(): print('Track %s ended' % track.kind) # 设置 请求端 连接信息: request_offer await pc.setRemoteDescription(request_offer) # 设置 响应端 连接信息: answer answer = await pc.createAnswer() await pc.setLocalDescription(answer) # 将 响应端 信息返回给 请求端: offer_result offer_result = json.dumps({'sdp': pc.localDescription.sdp, 'type': pc.localDescription.type}) return offer_result 更多例子: https://github.com/aiortc/aiortc/tree/master/examples

December 1, 2018

webrtc

[TOC] webrtc WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准 官方教程 mozilla学习地址 重要API WebRTC原生APIs文件是基于WebRTC规格书[21]撰写而成,这些API可分成Network Stream API、 RTCPeerConnection、Peer-to-peer Data API三类。 Network Stream API MediaStream:MediaStream用来表示一个媒体数据流。 MediaStreamTrack在浏览器中表示一个媒体源。 RTCPeerConnection RTCPeerConnection:一个RTCPeerConnection对象允许用户在两个浏览器之间直接通讯。 RTCIceCandidate:表示一个ICE协议的候选者。 RTCIceServer:表示一个ICE Server。 Peer-to-peer Data API DataChannel:数据通道(DataChannel)接口表示一个在两个节点之间的双向的数据通道。 WebRTC协议 ICE 交互式连接建立Interactive Connectivity Establishment (ICE) 是一个允许你的浏览器和对端浏览器建立连接的协议框架。在实际的网络当中,有很多原因能导致简单的从A端到B端直连不能如愿完成。这需要绕过阻止建立连接的防火墙,给你的设备分配一个唯一可见的地址(通常情况下我们的大部分设备没有一个固定的公网地址),如果路由器不允许主机直连,还得通过一台服务器转发数据。ICE通过使用以下几种技术完成上述工作。 STUN NAT的会话穿越功能Session Traversal Utilities for NAT (STUN) (缩略语的最后一个字母是NAT的首字母)是一个允许位于NAT后的客户端找出自己的公网地址,判断出路由器阻止直连的限制方法的协议。 客户端通过给公网的STUN服务器发送请求获得自己的公网地址信息,以及是否能够被(穿过路由器)访问。 NAT 网络地址转换协议Network Address Translation (NAT) 用来给你的(私网)设备映射一个公网的IP地址的协议。一般情况下,路由器的WAN口有一个公网IP,所有连接这个路由器LAN口的设备会分配一个私有网段的IP地址(例如192.168.1.3)。私网设备的IP被映射成路由器的公网IP和唯一的端口,通过这种方式不需要为每一个私网设备分配不同的公网IP,但是依然能被外网设备发现。 一些路由器严格地限定了部分私网设备的对外连接。这种情况下,即使STUN服务器识别了该私网设备的公网IP和端口的映射,依然无法和这个私网设备建立连接。这种情况下就需要转向TURN协议。 TURN 一些路由器使用一种“对称型NAT”的NAT模型。这意味着路由器只接受和对端先前建立的连接(就是下一次请求建立新的连接映射)。 NAT的中继穿越方式Traversal Using Relays around NAT (TURN) 通过TURN服务器中继所有数据的方式来绕过“对称型NAT”。你需要在TURN服务器上创建一个连接,然后告诉所有对端设备发包到服务器上,TURN服务器再把包转发给你。很显然这种方式是开销很大的,所以只有在没得选择的情况下采用。 SDP 会话描述协议Session Description Protocol (SDP) 是一个描述多媒体连接内容的协议,例如分辨率,格式,编码,加密算法等。所以在数据传输时两端都能够理解彼此的数据。本质上,这些描述内容的元数据并不是媒体流本身。 ...

December 1, 2018

wave librosa pyaudio

[TOC] wave wave 模块提供了一个处理 WAV 声音格式的便利接口。它不支持压缩/解压,但是支持单声道/立体声。 install pip install wave example # 读取音频文件数据 def read_wav(audio_name): with wave.open(audio_name, 'rb') as rf: frames = [] frame = rf.readframes(3200) while frame: frames.append(frame) frame = rf.readframes(3200) return frames # 保存音频文件数据 def write_wav(save_file, frames, CHANNELS=1, SIMPLE_SIZE=2, RATE=16000): if save_file is not None: wf = wave.open(save_file, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(SIMPLE_SIZE) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close() wave可以读取和保存音频文件,但是不能做时频处理、特征提取等问题,如果你读取rate=16000的文件,保存为rate=8000的文件,音频的时长增加了一倍,播放速度降低了一倍。 参考:https://docs.python.org/zh-cn/3/library/wave.html#module-wave Librosa Librosa 是一个用于音频、音乐分析、处理的python工具包,一些常见的时频处理、特征提取、绘制声音图形等功能应有尽有,功能十分强大。 install pip install librosa # conda install conda install -c conda-forge librosa example # 改变频谱并保存 def change_sample_rate(read_file, save_file, orig_sr=48000, target_sr=8000): y, sr = librosa.load(read_file, sr=orig_sr) y_16k = librosa.resample(y, sr, target_sr) librosa.output.write_wav(save_file, y_16k, target_sr) 参考: http://librosa.github.io/librosa/tutorial.html ...

November 17, 2018

flask框架及其常用模块

[TOC]

November 10, 2018

ffmepg

[TOC] FFmpeg ffmpeg也可以读取文件和从设备中读取视频信号,还可以从多个音视频文件中读取,然后输出多个音视频文件。 centos yum install ffmpeg # centos系统自带的ffmpeg一般都是 2.x的版本,很难满足现在很多需求,可以添加其他第三方源来安装,或者编译安装。 yum install yum-utils yum-config-manager --add-repo https://negativo17.org/repos/epel-multimedia.repo yum remove libva1-1.3.1-11.el7.x86_64 yum install ffmpeg ubuntu sudo apt install ffmpeg conda # conda安装的ffmpeg值存在于当前env环境中。 conda install ffmpeg 语法格式如下: ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ... # 从视频文件读取 -i test.avi # 从设备读取 -i /dev/video0 # 从视频流读取 -i rtsp://your_ip:port/ # 设置尺寸 -s 640*480 # 输出为文件,直接在后面写出文件名即可 ffmpeg -f video4linux -r 10 -i /dev/video0 test.asf # 输出到视频流 ffmpeg -i /dev/video0 -f mpegts -codec:v mpeg1video http://localhost:8081/supersecret ffmpeg功能强大,参数巨多。详情请看ffmpeg官方文档 ...

October 25, 2018

opencv

[TOC] opencv opencv既可以从视频文件读取,也可以从视频设备上获取 install pip install opencv-python how to use import cv2 # video_capture = cv2.VideoCapture("/home/alex/1.mp4") # video_capture = cv.CaptureFromFile('rtsp://192.168.1.2:8080/out.h264') video_capture = cv2.VideoCapture(0) while True: _, frame = video_capture.read() cv2.imshow("image", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break 可以从本地文件,视频设备,或者远程视频流中获取视频信号。 # 查看本地视频设备号 $ ls /dev/video* /dev/video0 常见实用示例 # 图片读写 def image_detector(self, imname, wait=0): # 读取图片 image = cv2.imread(imname) # 得到新的图片image result = self.detect(image) self.draw_result(image, result) # 显示图片 # cv2.imshow('Image', image) # cv2.waitKey(wait) # 保存图片 cv2.imwrite(imname.replace(".jpg", "_result.jpg"), image) # 写入视频 def camera_detector(self, cap, wait=10): # 获取 原视频的fps,fourcc编码,height,wieght等信息 fps = int(cap.get(cv2.CAP_PROP_FPS)) # fourcc = int(cap.get(cv2.CAP_PROP_FOURCC)) fourcc = cv2.VideoWriter_fourcc(*'MJPG') height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) weidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) print("fourcc: ", fourcc) # 创建新的写入writer videowriter = cv2.VideoWriter('test/test.avi', fourcc, fps, (weidth, height)) # 读取一帧图片 ret, frame = cap.read() while frame is not None: # 得到新的图片image result = self.detect(frame) self.draw_result(frame, result) # cv2.imshow('Camera', frame) # if cv2.waitKey(wait) & 0xFF == ord('q'): # break # 写入一帧图片 videowriter.write(frame) # 读取下一帧图片 ret, frame = cap.read() # 释放writer videowriter.release() # 调用 camera_detector cap = cv2.VideoCapture(video_read) detector.camera_detector(cap, wait=1) opencv mac error 正常情况下,在mac上面使用opencv是没有问题的,但是在Python子进程中使用opencv会发现子进程的代码会无厘头的没有结果。参考 这里 ,不要问我怎么知道的 /(ㄒoㄒ)/~~ ...

October 24, 2018

k8s学习笔记-26-kubeasz+ansible部署集群

[TOC] 官方学习文档:https://github.com/easzlab/kubeasz 1、环境说明 IP 主机名 角色 虚拟机配置 192.168.56.11 k8s-master deploy、master1、lb1、etcd 4c4g 192.168.56.12 k8s-master2 master2、lb2 4c4g 192.168.56.13 k8s-node01 etcd、node 2c2g 192.168.56.14 k8s-node02 etcd、node 2c2g 192.168.56.110 vip 系统内核 3.10 docker版本 18.09 k8s版本 1.13 etcd版本 3.0 2、准备工作 四台机器,全部执行: yum install -y epel-release yum update -y yum install python -y deploy节点安装ansible并配置密钥认证 yum install -y ansible ssh-keygen for ip in 11 12 13 14;do ssh-copy-id 192.168.56.$ip;done deploy节点编排K8S [root@k8s-master ~]# git clone https://github.com/gjmzj/kubeasz.git [root@k8s-master ~]# mv kubeasz/* /etc/ansible/ 可以根据自己所需版本,下载对应的tar包,这里我下载1.13 经过一番折腾,最终把k8s.1-13-5.tar.gz的tar包放到了depoly上 ...

October 5, 2018

k8s学习笔记-25-Helm程序包管理器

[TOC] 1、Helm的概念和架构 每个成功的软件平台都有一个优秀的打包系统,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。 **思考??**Helm 到底解决了什么问题?为什么 Kubernetes 需要 Helm? Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。 举个例子,我们需要部署一个MySQL服务,Kubernetes则需要部署以下对象: ① 为了能够让外界访问到MySQL,需要部署一个mysql的service; ②需要进行定义MySQL的密码,则需要部署一个Secret; ③Mysql的运行需要持久化的数据存储,此时还需要部署PVC; ④保证后端mysql的运行,还需要部署一个Deployment,以支持以上的对象。 针对以上对象,我们可以使用YAML文件进行定义并部署,但是仅仅对于单个的服务支持,如果应用需要由一个甚至几十个这样的服务组成,并且还需要考虑各种服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。 Helm的核心术语: Chart:一个helm程序包,是创建一个应用的信息集合,包含各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。可以将Chart比喻为yum中的软件安装包; Repository:Charts仓库,用于集中存储和分发Charts; Config:应用程序实例化安装运行时所需要的配置信息; Release:特定的Chart部署于目标集群上的一个实例,代表这一个正在运行的应用。当chart被安装到Kubernetes集群,就会生成一个release,chart可以多次安装到同一个集群,每次安装都是一个release。 Helm的程序架构: Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,如下图: helm:客户端,GO语言编写,实现管理本地的Chart仓库,可管理Chart,与Tiller服务进行交互,用于发送Chart,实例安装、查询、卸载等操作。 Tiller:服务端,通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg,合并生成release,完成部署。 简单的说:Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。 2、部署Helm helm部署文档 Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装 (1)下载helm [root@k8s-master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz --no-check-certificate [root@k8s-master ~]# tar -xf helm-v2.9.1-linux-amd64.tar.gz [root@k8s-master ~]# cd linux-amd64/ [root@k8s-master linux-amd64]# ls helm LICENSE README.md [root@k8s-master linux-amd64]# mv helm /usr/bin [root@k8s-master linux-amd64]# helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"} (2)部署Tiller helm第一次init时,需要链接api-server并进行认证,所以在运行helm时,会去读取kube-config文件,所以必须确认当前用户存在kube-config文件。 ...

September 25, 2018

k8s学习笔记-24-Prometheus监控

[TOC] 1、Prometheus概述 除了前面的资源指标(如CPU、内存)以外,用户或管理员需要了解更多的指标数据,比如Kubernetes指标、容器指标、节点资源指标以及应用程序指标等等。自定义指标API允许请求任意的指标,其指标API的实现要指定相应的后端监视系统。而Prometheus是第一个开发了相应适配器的监控系统。这个适用于Prometheus的Kubernetes Customm Metrics Adapter是属于Github上的k8s-prometheus-adapter项目提供的。其原理图如下: 要知道的是prometheus本身就是一监控系统,也分为server端和agent端,server端从被监控主机获取数据,而agent端需要部署一个node_exporter,主要用于数据采集和暴露节点的数据,那么 在获取Pod级别或者是mysql等多种应用的数据,也是需要部署相关的exporter。我们可以通过PromQL的方式对数据进行查询,但是由于本身prometheus属于第三方的 解决方案,原生的k8s系统并不能对Prometheus的自定义指标进行解析,就需要借助于k8s-prometheus-adapter将这些指标数据查询接口转换为标准的Kubernetes自定义指标。 Prometheus是一个开源的服务监控系统和时序数据库,其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件Prometheus服务器定期从静态配置的监控目标或者基于服务发现自动配置的目标中进行拉取数据,新拉取到的数据大于配置的内存缓存区时,数据就会持久化到存储设备当中。Prometheus组件架构图如下: 如上图,每个被监控的主机都可以通过专用的exporter程序提供输出监控数据的接口,并等待Prometheus服务器周期性的进行数据抓取。如果存在告警规则,则抓取到数据之后会根据规则进行计算,满足告警条件则会生成告警,并发送到Alertmanager完成告警的汇总和分发。当被监控的目标有主动推送数据的需求时,可以以Pushgateway组件进行接收并临时存储数据,然后等待Prometheus服务器完成数据的采集。 任何被监控的目标都需要事先纳入到监控系统中才能进行时序数据采集、存储、告警和展示,监控目标可以通过配置信息以静态形式指定,也可以让Prometheus通过服务发现的机制进行动态管理。下面是组件的一些解析: 监控代理程序:如node_exporter:收集主机的指标数据,如平均负载、CPU、内存、磁盘、网络等等多个维度的指标数据。 kubelet(cAdvisor):收集容器指标数据,也是K8S的核心指标收集,每个容器的相关指标数据包括:CPU使用率、限额、文件系统读写限额、内存使用率和限额、网络报文发送、接收、丢弃速率等等。 API Server:收集API Server的性能指标数据,包括控制队列的性能、请求速率和延迟时长等等 etcd:收集etcd存储集群的相关指标数据 kube-state-metrics:该组件可以派生出k8s相关的多个指标数据,主要是资源类型相关的计数器和元数据信息,包括制定类型的对象总数、资源限额、容器状态以及Pod资源标签系列等。 Prometheus 能够直接把 Kubernetes API Server作为服务发现系统使用进而动态发现和监控集群中的所有可被监控的对象。这里需要特别说明的是,Pod 资源需要添加下列注解信息才能被Prometheus 系统自动发现并抓取其内建的指标数据。 1) prometheus. io/ scrape: 用于 标识 是否 需要 被 采集 指标 数据, 布尔 型 值, true 或 false。 2) prometheus. io/ path: 抓取 指标 数据 时 使用 的 URL 路径, 一般 为/ metrics。 3) prometheus. io/ port: 抓取 指标 数据 时 使 用的 套 接 字 端口, 如 8080。 另外, 仅 期望 Prometheus 为 后端 生成 自定义 指标 时 仅 部署 Prometheus 服务器 即可, 它 甚至 也不 需要 数据 持久 功能。 但 若要 配置 完整 功能 的 监控 系统, 管理员 还需 要在 每个 主机 上 部署 node_exporter、 按需部署其他特有类型的 exporter 以及Alertmanager。 ...

September 19, 2018