meekworth / pylwdrone

Python module to communicate with a lewei camera module.
Apache License 2.0
19 stars 4 forks source link

Getting Video Frames From PCAP #8

Closed TrevorHurst closed 1 year ago

TrevorHurst commented 1 year ago

Could there be a feature where you take a PCAP of the live stream from the camera and process that data to create a new .h264 file?

TrevorHurst commented 1 year ago

This is what I have, the video result is cut off from the top, leaving the bottom half smudged data, it has to be something with how I'm reading the data in!

import pyshark
import pylwdrone
import pylwdrone.responses

xSWITCHER = True
capture = pyshark.FileCapture("Cap.pcap")
with open("Result.h264", 'wb') as out:
    for packet in capture:
        try:
            if packet.ip.src == '192.168.0.1':
                if 'tcp' in packet:
                    if 'data' in packet:
                        data =  packet.data.data
                        data = bytes.fromhex(data)
                        flag, size, count, gphoto = struct.unpack_from('<LLQL', data)
                        frame_bytes = bytearray(data)
                        su = pylwdrone.responses.VideoFrameUnmunger(3, 4, 5)
                        su.unmunge(frame_bytes, size, count)
                        out.write(frame_bytes)
        except:
            pass

to capture the PCAP file I connected through the drone and used pylwdrone to stream the data and wireshark to capture the packets. to run this I'm doing ffplay -i Result.h264

Any help is appreciated

TrevorHurst commented 1 year ago

If anyone's curious I got it to work! Here's the code:

import pyshark
import pylwdrone
import pylwdrone.responses
import pylwdrone.command

data = b''
xSWITCHER = True
capture = pyshark.FileCapture("Cap.pcap")
for packet in capture:
    try:
        if packet.ip.src == '192.168.0.1':
            if 'tcp' in packet:
                if 'data' in packet:
                    data+= bytes.fromhex(packet.data.data)
    except:
        pass

def recv(x):
    global data
    out = data[:x]
    data = data[x:]
    print(x, len(out), len(data))
    return out

# Assume all data is in bytes
def getFrame(data):
    try:
        hdr = pylwdrone.command.Command.from_bytes(recv(pylwdrone.command.Command.HDR_LEN))
    except:
        return None, None
    body_bytes = recv(hdr.get_arg(pylwdrone.command.Command.HDR_ARG_BODYSZ))
    if hdr.cmdtype == pylwdrone.command.CommandType.heartbeat:
        return getFrame(data)
    if hdr.cmdtype == pylwdrone.command.CommandType.retreplayend:
        return None, None
    return hdr, body_bytes

i = 0
with open("Result.h264", 'wb') as out:
    print("starting_Write")
    while True:
        hdr, frame_packet = getFrame(data)
        if frame_packet is None:
            break
        stream_type = hdr.get_arg(pylwdrone.command.Command.HDR_ARG_STREAM_TYPE)
        dec1 = hdr.get_arg(pylwdrone.command.Command.HDR_ARG_STREAM_DEC1)
        dec2 = hdr.get_arg(pylwdrone.command.Command.HDR_ARG_STREAM_DEC2)
        fu = pylwdrone.responses.VideoFrameUnmunger(stream_type, dec1, dec2)
        try:
            out.write(pylwdrone.VideoFrame.from_bytes(fu, frame_packet).frame_bytes)
        except:
            pass
print("DONE!!!")