ユピテルY-300dPの画像から加速度データを得る

最近、ドライブレコーダーを買いました。 ユピテル YupiteruY-300dPです。 発売は2021年と少々古いのですが、性能が良く値段が手頃なので気に入っています。 このドラレコは衝突や急ブレーキ、急ハンドルなどで異常な加速度を検知した場合、 前後40秒のデータを別フォルダに格納する機能がついています。 その際に加速度の閾値を適切に決めないと頻繁にアラーム音とともに動作してしまうので 設定を調整する必要があります。 画像をPCで確認するプログラムとのことで、 調べてみると字幕データとしてフレームごとに記録されているようです。 というわけでPythonコードを書いてみました。

# AVI Audio Video Interface
# RIFF Resource Interchange File Format

import struct

#
# Read RIFF Header
#
def read_RIFF_header(f):
    buffer = f.read(12)
    riff, size, type = struct.unpack('<4sI4s', buffer)
    if riff != b'RIFF' or type != b'AVI ':
        raise ValueError('Not a valid AVI file')
    return size

def read_list(f, read_data=True):
    buffer = f.read(12)
    id, size, type = struct.unpack('<4sI4s', buffer)
    if id != b'LIST':
        raise ValueError('Not LIST.')
    if read_data:
        buffer = f.read(size - 4)
        if size % 2 == 1:
            f.read(1) # Read one more byte if size is odd.
        return size, type, buffer
    return size, type

def read_chunk(f, read_data=True):
    buffer = f.read(8)
    id, size = struct.unpack('<4sI', buffer)
    if read_data:
        buffer = f.read(size)
        if size % 2 == 1:
            f.read(1) # Read one more byte if the size is odd.
        return id, size, buffer
    return id, size

file = '~~~.avi'
f = open(file, 'rb')
#
# Check RIFF Header
#
size = read_RIFF_header(f)
size, type = read_list(f, read_data=False)
if type != b'hdrl':
    raise ValueError('list_type is not hdrl.')
#
# Main AVI Header
#
id, size, buffer = read_chunk(f)
if id != b'avih':
    raise ValueError('chunk_type is not avih.')
#
# Stream Header Lists
# fccType = 'vids', 'auds', 'txts'
#
for i in range(3):
    size, type, buffer = read_list(f)
    if type != b'strl':
        raise ValueError('list_type is not strl.')
#
# JUNK Chunks
#
for i in range(2):
    id, size, buffer = read_chunk(f)
    if id != b'JUNK':
        raise ValueError('chunk_type is not JUNK.')
#
# movi List
#
movi_size, type = read_list(f, read_data=False)
if type != b'movi':
    raise ValueError('listtype is not movi.')


current_size = 0
ax_list = []
ay_list = []
az_list = []
while current_size < movi_size:
    id, size, buffer = read_chunk(f)
    if id == b'02tx':
        f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
            ax, ay, az, n, speed, latitude, longitude, unix_time = struct.unpack('<13fI3fI', buffer)
        ax_list.append(ax)
        ay_list.append(ay)
        az_list.append(az)
        print(ax, ay, az, n, speed, latitude, longitude, unix_time)
    current_size += size

f.close()

私が購入したドラレコの型番はY-300dpなのですが、 LaBoon!!さんのサイトでは、 同様なハードが様々な型番(WDT700c, SN-TW9900d, SN-TW9800d, Y-300C, Y-300R, Y-210R, SN-TW99c, SN-TW84d)で販売されているとの事で、 ひょっとしたらこれらのドラレコでもデータが抽出できるかもしれません。