迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera

Author: Aric Wang

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第1张图片

 

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第2张图片

 

在闲鱼上买了个迷你无人机的图像模块,介绍说要用wificam app可以查看实时视频和控制。因为我想用电脑显示,或者开发自己的APP来控制和显示实时视频,于是逆向分析了一下在此记录。

首先抓包分析: 准备一台有双无线网卡的电脑和安装好wireshark,电脑一张无线网卡设置好AP,另一张无线网卡连FPV WIFI  相机。手机安装好wificam app(apk),并且该手机连到电脑建的热点。

让电脑开起路由功能。此时打开wificam app,就可以看到视频了。   用于wireshark抓一个完整的包,包括,开始,视频传输,结束的。

通过分析抓包可知:  UDP 8090用于控制, UDP 8080于来传输视频,probe出来,视频格式为MJPEG的VGA流。 使用 UDP分片传输JPEG思路挺不错的,效果了不错,毕竟是商用方案。

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第3张图片

向UDP 8090,发 AA 80 80 00 80 00 80 55 命令, 再向UPD 8080发 42 76 就开始实时视频。

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第4张图片

 结束也是类似,先向UDP 8090发命令,再向UDP 8080发 42 77就可以停止视频。

MJPEG通常使用TCP稳定的传输, 该项目的创意之处就是UDP分片传输,一帧一帧的传。

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第5张图片

抓包可以清析的看到一帧一帧的图片,最后一个包变小了,应该是传输剩余数据。

UDP分片也有引导头,包括JPEG的续号sequence number,1-255循环,只用了一个字节表示。头第二位用来表示该帧的最后一个分片 。

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第6张图片

02就是第二张图片的意思,01就是分片的最后一片。

下图可以看到,非最后分片, 第二位为0

迷你无人机 FPV WIFI CAMERA图传破解,mini drone WIFI camera_第7张图片

 UDP有大可能丢包,所以尾部也要处理一下,这里我猜了很多,以为是bcc crc8 crc-sum等等,原来只是little endian 的unsigned short。 那这就简单了!

 

 写个向标准输出,输出视频流的脚本:

udp_decode_std.py

 

#!/usr/bin/env python
import os,sys,time,socket
import select
import numpy as np
import struct, queue, _thread

UDP_PKT_SIZE= 2000

out_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
out_sock.bind(('0.0.0.0', 6666))

out_sock.sendto(b'\xaa\x80\x80\x00\x80\x00\x80\x55',("192.168.4.153", 8090))
out_sock.sendto(b'\x42\x76',("192.168.4.153", 8080))

      
def isValidJPEG():
    t_len = len(s_buf)
    if s_buf[0] == 0xff and s_buf[1] == 0xd8 and s_buf[t_len-1] == 0xd9 and s_buf[t_len-2] == 0xff:
        return True
    else:
        return False
  
def chk_tail(jpg_len, b_jpg_len):
    unpack_len = struct.unpack("


然后就可以用ffplay ffmpeg gstreamer来播放了

#ffplay 播放,有时延
python3 udp_decode_std.py | ffplay -

#low latency play
python3 udp_decode_std.py | ffmpeg -threads 1 -re -fflags nobuffer  -f mjpeg -i - -pix_fmt yuv420p -f sdl -

python3 wificam_udp_cam_stop.py 

#Gstreamer也可以播放,
python3 udp_decode_std.py  | gst-launch-1.0  filesrc location=/dev/stdin ! queue ! jpegdec ! autovideosink

 

当然也可以用opencv来显示实时视频:

#!/usr/bin/env python
import os,sys,time,socket
import select
import cv2
import numpy as np
import struct, queue, _thread

UDP_PKT_SIZE= 2000

out_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
out_sock.bind(('0.0.0.0', 6666))

out_sock.sendto(b'\xaa\x80\x80\x00\x80\x00\x80\x55',("192.168.4.153", 8090))
out_sock.sendto(b'\x42\x76',("192.168.4.153", 8080))

def decode_jpeg(buf):
    try:
        img = cv2.imdecode(np.fromstring(buf, dtype=np.uint8) ,cv2.IMREAD_COLOR)
        cv2.imshow('IMG', img)
        if cv2.waitKey(1) == 27:
            exit(0)
        #img = Image.fromarray(np.fromstring(buf, dtype=np.uint8) )
        #cv2.imshow(img) 
    except Exception as e:
        print(">>>>>>>>>> imdecode error!", e)
        pass
      
def isValidJPEG():
    t_len = len(s_buf)
    if s_buf[0] == 0xff and s_buf[1] == 0xd8 and s_buf[t_len-1] == 0xd9 and s_buf[t_len-2] == 0xff:
        return True
    else:
        return False
  
def chk_tail(jpg_len, b_jpg_len):
    unpack_len = struct.unpack("

 

 

 

你可能感兴趣的:(无人机,wifi,fpv)