Как мне декодировать данные, когда я не знаю конкретной кодировки - PullRequest
0 голосов
/ 19 февраля 2019

Я получаю данные, используя сервер OSC, и данные выглядят так:

b'Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'Muse-C46F/elements/alpha_relative\x00\x00\x00,ffff\x00\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00'
b'Muse-C46F/elements/alpha_session_score\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Я пытаюсь декодировать 4 числа с плавающей запятой из этих закодированных последовательностей.

Это мойвесь код:

print('Program Initiated')
UDP_IP = "192.168.2.57"
UDP_PORT = 4000

sock = socket.socket(socket.AF_INET,  # Internet
                socket.SOCK_DGRAM)  # UDP
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
    if 'alpha' in str(data):
        print(struct.unpack('>32s8sffff', data))

Я видел похожий вопрос и использовал print(struct.unpack('>32s8sffff', data)), но я получаю unpack requires a buffer of 56 bytes как ошибку.

1 Ответ

0 голосов
/ 19 февраля 2019

Эти сообщения OSC состоят из трех частей:

  • Адрес (который должен начинаться с b'/')
  • Строка тега типа, начинающаяся с b',',и определяет тип и количество аргументов, следующих за
  • Аргументы сообщений, как определено строкой тега типа.

В данных, представленных в вопросе, каждое сообщение состоит из 36или 40 байтов адреса, затем 5 байтов строки типа тега.Независимо от начальной запятой строка типа тега состоит из четырех 'f', поэтому мы ожидаем, что аргументы будут состоять из четырех чисел с плавающей запятой, по 16 байт (по 4 на каждую поплавок).

Каждое сообщение имеет несколько дополнительных байтов после16 требуется для четырех поплавков;давайте предположим *, что это отступы, которые можно отбросить.

Таким образом, структурный формат будет следующим: переменное количество символов адреса, пять символов типа тега и четыре числа с плавающей точкой.

Тогда код, необходимый для извлечения данных, выглядит следующим образом:

$ cat osc.py

  import struct

  data = [
     b"Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
     b"Muse-C46F/elements/alpha_relative\x00\x00\x00,ffff\x00\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x7f\xc0\x00\x00\x
     b"Muse-C46F/elements/alpha_session_score\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
     b"Muse-C46F/elements/alpha_absolute\x00\x00\x00,ffff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
  ]

  if __name__ == "__main__":
      for msg in data:
          num_address_bytes = msg.index(b",")
          num_argument_bytes = len(msg) - (num_address_bytes + 5)
          num_extra_bytes = num_argument_bytes - 16
          address, type_, *floats = struct.unpack(
              ">{}s5s4f".format(num_address_bytes), msg[:-num_extra_bytes]
          )
          print(address, type_, floats)

Этот вывод генерируется:

b'Muse-C46F/elements/alpha_absolute\x00\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]
b'Muse-C46F/elements/alpha_relative\x00\x00\x00' b',ffff' [1.7796490496925177e-43, -2.000030279159546, -2.000030279159546, -2.000030279159546]
b'Muse-C46F/elements/alpha_session_score\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]
b'Muse-C46F/elements/alpha_absolute\x00\x00\x00' b',ffff' [0.0, 0.0, 0.0, 0.0]

* Обычно делать плохие предположения.Если на сервере OSC есть документация, проверьте, не отличаются ли его форматы от OSC spec .

...