aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/argaze/TobiiGlassesPro2/TobiiEntities.py91
-rw-r--r--src/argaze/utils/explore_tobii_sdcard.py9
2 files changed, 80 insertions, 20 deletions
diff --git a/src/argaze/TobiiGlassesPro2/TobiiEntities.py b/src/argaze/TobiiGlassesPro2/TobiiEntities.py
index e243a5a..a16700d 100644
--- a/src/argaze/TobiiGlassesPro2/TobiiEntities.py
+++ b/src/argaze/TobiiGlassesPro2/TobiiEntities.py
@@ -4,6 +4,9 @@ import datetime
import json
import gzip
import os
+
+from argaze.DataAnalysis import TimeStampedData
+
import cv2 as cv
TOBII_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S+%f'
@@ -18,9 +21,61 @@ TOBII_RECORDINGS_DIRNAME = "recordings"
TOBII_RECORD_FILENAME = "recording.json"
TOBII_SEGMENTS_DIRNAME = "segments"
-TOBII_SEGMENT_FILENAME = "segment.json"
+TOBII_SEGMENT_INFO_FILENAME = "segment.json"
TOBII_SEGMENT_VIDEO_FILENAME = "fullstream.mp4"
-TOBII_SEGMENT_LIVEDATA_FILENAME = "livedata.json.gz"
+TOBII_SEGMENT_DATA_FILENAME = "livedata.json.gz"
+
+class TobiiSegmentData:
+ """Handle Tobii Glasses Pro 2 segment data file."""
+
+ def __init__(self, segment_data_path):
+ """Load segment data from segment directory."""
+
+ self.__segment_data_path = segment_data_path
+ self.__ts_start = 0
+
+ def get_path(self):
+ return self.__segment_data_path
+
+ def load(self):
+
+ ts_data_dict = {}
+
+ # define a decoder function
+ def decode(json_item):
+
+ # accept only valid data (e.g. with status value equal to 0)
+ if json_item.pop('s', -1) == 0:
+
+ # convert timestamp into ms
+ ts = json_item.pop('ts') / 1000.0
+
+ # keep first timestamp to offset all timestamps
+ if self.__ts_start == 0:
+ self.__ts_start = ts
+
+ ts -= self.__ts_start
+
+ # ignore negative timestamp
+ if ts < 0:
+ return
+
+ # concatenate keys to get data signature
+ data_signature = '-'.join(json_item.keys())
+
+ # append a timestamped data buffer to store all data with same signature
+ if data_signature not in ts_data_dict.keys():
+ ts_data_dict[data_signature] = TimeStampedData.TimeStampedData()
+
+ # store data into the dedicated timestamped data buffer
+ ts_data_dict[data_signature][ts] = json_item
+
+ # start loading
+ with gzip.open(self.__segment_data_path) as f:
+ for item in f:
+ json.loads(item.decode('utf-8'), object_hook=decode)
+
+ return ts_data_dict
class TobiiSegmentVideo:
"""Handle Tobii Glasses Pro 2 segment video file."""
@@ -30,11 +85,11 @@ class TobiiSegmentVideo:
self.__segment_video_path = segment_video_path
- cap = cv.VideoCapture(self.__segment_video_path)
+ video = cv.VideoCapture(self.__segment_video_path)
- self.__width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
- self.__height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
- self.__fps = int(cap.get(cv.CAP_PROP_FPS))
+ self.__width = int(video.get(cv.CAP_PROP_FRAME_WIDTH))
+ self.__height = int(video.get(cv.CAP_PROP_FRAME_HEIGHT))
+ self.__fps = int(video.get(cv.CAP_PROP_FPS))
def get_path(self):
return self.__segment_video_path
@@ -49,7 +104,7 @@ class TobiiSegmentVideo:
return self.__fps
class TobiiSegment:
- """Handle Tobii Glasses Pro 2 segment info, data and video."""
+ """Handle Tobii Glasses Pro 2 segment info."""
def __init__(self, segment_path):
"""Load segment info from segment directory."""
@@ -57,16 +112,16 @@ class TobiiSegment:
self.__segment_id = os.path.basename(segment_path)
self.__segment_path = segment_path
- with open(os.path.join(self.__segment_path, TOBII_SEGMENT_FILENAME)) as f:
+ with open(os.path.join(self.__segment_path, TOBII_SEGMENT_INFO_FILENAME)) as f:
try:
item = json.load(f)
except:
- raise RuntimeError(f'JSON fails to load {self.__segment_path}/{TOBII_SEGMENT_FILENAME}')
+ raise RuntimeError(f'JSON fails to load {self.__segment_path}/{TOBII_SEGMENT_INFO_FILENAME}')
self.__length_us = int(item["seg_length_us"])
self.__calibrated = bool(item["seg_calibrated"])
- self.__time_start = datetime.datetime.strptime(item["seg_t_start"], TOBII_DATETIME_FORMAT)
- self.__time_stop = datetime.datetime.strptime(item["seg_t_stop"], TOBII_DATETIME_FORMAT)
+ self.__start_date = datetime.datetime.strptime(item["seg_t_start"], TOBII_DATETIME_FORMAT)
+ self.__stop_date = datetime.datetime.strptime(item["seg_t_stop"], TOBII_DATETIME_FORMAT)
def get_path(self):
return self.__segment_path
@@ -77,18 +132,18 @@ class TobiiSegment:
def get_length_us(self):
return self.__length_us
- def get_live_data_filepath(self):
- return os.path.join(self.__segment_path, self.__segment_id)
+ def get_start_date(self):
+ return self.__start_date
- def get_start_date_time(self):
- return self.__time_start
-
- def get_stop_date_time(self):
- return self.__time_stop
+ def get_stop_date(self):
+ return self.__stop_date
def is_calibrated(self):
return self.__calibrated
+ def get_data(self):
+ return TobiiSegmentData(os.path.join(self.__segment_path, TOBII_SEGMENT_DATA_FILENAME))
+
def get_video(self):
return TobiiSegmentVideo(os.path.join(self.__segment_path, TOBII_SEGMENT_VIDEO_FILENAME))
diff --git a/src/argaze/utils/explore_tobii_sdcard.py b/src/argaze/utils/explore_tobii_sdcard.py
index 7fd9032..0f0b01a 100644
--- a/src/argaze/utils/explore_tobii_sdcard.py
+++ b/src/argaze/utils/explore_tobii_sdcard.py
@@ -52,8 +52,13 @@ def main():
tobii_segment_video = tobii_segment.get_video()
print(f'Video width: {tobii_segment_video.get_width()}, height: {tobii_segment_video.get_height()}, fps: {tobii_segment_video.get_fps()}')
- #tobii_segment_data = tobii_segment.get_data()
- #print(f'Data width: {tobii_segment_data.get_width()}, height: {tobii_segment_data.get_height()}, fps: {tobii_segment_data.get_fps()}')
+ tobii_segment_data = tobii_segment.get_data()
+
+ data = tobii_segment_data.load()
+
+ for key in data.keys():
+ print(f'{key}: {len(data[key])} items')
+ print(f'{key} first item: {data[key].popitem()} items')
if __name__ == '__main__':