GCP Video Intelligence APIの返り値nanos秒オブジェクトが、'datetime.timedelta' object has no attribute 'nanos'エラーで扱えない件

##*nano*を取り出して、したいこと

次のサイトにならい、各フレームが動画の最初のフレームから何分何秒後のフレームなのかを、PythonのDataFrameに格納してみようと思いました。

- [Video Intelligence APIで動画の物体検出をする](https://qiita.com/yoh_n/items/9a60d46e976e7884960f)

>```Python:
if cap.isOpened():
    fps = cap.get(cv2.CAP_PROP_FPS)
    for sec in df['FrameTime']:
        # fpsと秒から何フレーム目かを計算する
        cap.set(cv2.CAP_PROP_POS_FRAMES, round(fps * sec))
>```

上記のサイトに書かれている通り、「各フレームが動画の最初のフレームから何分何秒後のフレームなのか」がわかれば、動画のフレームレート数と合わせて、各フレームが動画中の何フレーム目のフレームなのかも、計算で求めることができます。

###__*AttributeError: 'datetime.timedelta' object has no attribute 'nanos'*エラーが発生__

``` Python3:
>>> import json
>>> from google.cloud import videointelligence
>>> from google.oauth2 import service_account
>>> service_account_key_name = "electroncgpvision-8bf54f743c93.json"
>>> info = json.load(open(service_account_key_name))
>>> creds = service_account.Credentials.from_service_account_info(info)
>>> video_client = videointelligence.VideoIntelligenceServiceClient(credentials=creds)
>>> features = [videointelligence.Feature.OBJECT_TRACKING]
>>> path = './olympic.mp4'
>>> import io
>>> 
>>> with io.open(path, 'rb') as file:
...     input_content = file.read()
... 
>>>
>>> operation = video_client.annotate_video(
...     request={"features": features, "input_content": input_content}
... )
>>>
>>> timeout = 300
>>> result = operation.result(timeout=timeout)

>>> 
>>> 
>>> import types
>>> print(type(result))
<class 'google.cloud.videointelligence_v1.types.video_intelligence.AnnotateVideoResponse'>
>>>
```

```Python3:
>>> for object_annotation in object_annotations:
...     for frame in object_annotation.frames:
...             box = frame.normalized_bounding_box
...             result_table.append([
...             object_annotation.entity.description,
...             object_annotation.confidence,
...             object_annotation.segment.start_time_offset.seconds + object_annotation.segment.start_time_offset.nanos / 1e9,
...             object_annotation.segment.end_time_offset.seconds + object_annotation.segment.end_time_offset.nanos / 1e9,
...             frame.time_offset.seconds + frame.time_offset.nanos / 1e9,
...             box.left,
...             box.top,
...             box.right,
...             box.bottom,
...             [box.left, box.top, box.right, box.bottom],
...             object_annotation.entity.entity_id
...             ])
... 
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 

```


```Python3:
>>> start_time_offset_listp = [object.segment.start_time_offset for object in object_list]
>>> start_time_offset_list = [object.segment.start_time_offset for object in object_list]
>>> len(start_time_offset_list)
1143
>>> 
>>> start_time_offset_list[0:2]
[datetime.timedelta(0), datetime.timedelta(seconds=1, microseconds=201200)]
>>> 
>>> print(start_time_offset_list[0:2])
[datetime.timedelta(0), datetime.timedelta(seconds=1, microseconds=201200)]
>>> 
>>> start_time_seconds_list = [object.segment.start_time_offset.seconds for object in object_list]
>>> len(start_time_seconds_list)
1143
>>> print(start_time_seconds_list[0:2])
[0, 1]
>>> 
>>> print(start_time_seconds_list[0:10])
[0, 1, 2, 4, 5, 7, 7, 7, 7, 7]
>>> 
>>> start_time_nanos_list = [object.segment.start_time_offset.nanos for object in object_list]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

```Python3:
>>> start_time_offset_list = [object.segment.start_time_offset for object in object_list]
>>> print(start_time_offset_list[0])
0:00:00
>>> 
>>> print(start_time_offset_list[0].seconds)
0
>>> 
>>> print(start_time_offset_list[0].nanos)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 

```

##*nano*を取り出して、したいこと

次のサイトにならい、各フレームが動画の最初のフレームから何分何秒後のフレームなのかを、PythonのDataFrameに格納してみようと思いました。

- [Video Intelligence APIで動画の物体検出をする](https://qiita.com/yoh_n/items/9a60d46e976e7884960f)

>```Python:
if cap.isOpened():
    fps = cap.get(cv2.CAP_PROP_FPS)
    for sec in df['FrameTime']:
        # fpsと秒から何フレーム目かを計算する
        cap.set(cv2.CAP_PROP_POS_FRAMES, round(fps * sec))
>```

上記のサイトに書かれている通り、「各フレームが動画の最初のフレームから何分何秒後のフレームなのか」がわかれば、動画のフレームレート数と合わせて、各フレームが動画中の何フレーム目のフレームなのかも、計算で求めることができます。

動画のフレーム数は、Pythonで出力できます。

- [OpenCVの動画プロパティを取得する](https://qiita.com/takahiro_itazuri/items/e740f0a1b5165fafa6ac)

>```Python:
># fps
fps = video.get(cv2.CAP_PROP_FPS)
>```

先ほどのサイトでは、以下の部分でfpsを取得しています。

> fps = cap.get(cv2.CAP_PROP_FPS)

その上で、先ほどのサイトでは、以下の最後の行の次の部分で「あるフレームが動画内で何フレーム目に位置するフレームなのか」を計算しています。

> round(fps * sec)

あるフレームが、動画の最初から数えて1,000sec経過後に登場するシーン（フレーム）であり、この動画が、15fps（1秒間に15フレーム表示される）のとき、「あるフレーム」は、動画の最初から数えて、1,000*15 = 15,000フレーム目に位置する計算になります。

そして、__*cap.set()*メソッド__で、「あるフレーム」に「現在のフレーム位置」を移動させて、OpenCV2を使って、目的のフレーム画像を取得しています。

>```Python:
if cap.isOpened():
    fps = cap.get(cv2.CAP_PROP_FPS)
    for sec in df['FrameTime']:
        # fpsと秒から何フレーム目かを計算する
        cap.set(cv2.CAP_PROP_POS_FRAMES, round(fps * sec))
>```



cap.set()メソッドの仕様は、次の通りです。

- __第一引数： 「フレームの現在位置」を指す*cv2.CAP_PROP_POS_FRAMES*__を指定する。
- __第二引数： 動画の最初から数えたフレーム数__を渡す。

その結果、「フレームの現在位置」が、「あるフレーム」になるよう、位置指定が行われます。

- [Python, OpenCVで動画を読み込み（ファイル・カメラ映像）](https://note.nkmk.me/python-opencv-videocapture-file-camera/)

> print(cap.set(cv2.CAP_PROP_POS_FRAMES, 100))
> このCAP_PROP_POS_FRAMESは動画の現在位置を表すプロパティ。後述。

#解決策を探索中

以下のサイトを見て、解決策を模索中です。

- https://living-sun.com/ja/python/733171-how-to-create-a-pandastimestamp-from-datetimedatetime-object-and-nanoseconds-value-python-datetime-pandas-timestamp.html
- https://qiita.com/KMiura95/items/fb50d3afa37b57ef9346
- https://qapicks.com/question/64383923-75880e0e5a4c
- https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_timedelta.html

#計算を伴わない以下もエラー

####エラー

```Python3:
>>> for object_annotation in object_annotations:
...     for frame in object_annotation.frames:
...             box = frame.normalized_bounding_box
...             result_table.append([
...                     object_annotation.entity.description,
...                     object_annotation.confidence,
...                     object_annotation.segment.start_time_offset.seconds,
...                     object_annotation.segment.start_time_offset.nanos,
...                     object_annotation.segment.end_time_offset.seconds,
...                     object_annotation.segment.end_time_offset.nanos,
...                     frame.time_offset.seconds,
...                     frame.time_offset.nanos,
...                     box.left,
...                     box.top,
...                     box.right,
...                     box.bottom,
...                     [box.left, box.top, box.right, box.bottom],
...                     object_annotation.entity.entity_id
...             ])
... 
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

####エラー

```Python3:
>>> tmp = [object_annotation.segment.start_time_offset.nanos for object_annotation in object_annotations]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

####エラー

```Python3:
>>> tmp = [float(object_annotation.segment.start_time_offset.nanos) for object_annotation in object_annotations]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

####エラー

```Python3:
>>> tmp = [str(object_annotation.segment.start_time_offset.nanos) for object_annotation in object_annotations]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

####エラー

```Python3:
>>> tmp = [int(object_annotation.segment.start_time_offset.nanos) for object_annotation in object_annotations]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
AttributeError: 'datetime.timedelta' object has no attribute 'nanos'
>>> 
```

####__*nanos*__呼出しがない処理は走る

```Python3:
>>> tmp = [object_annotation.segment.start_time_offset.seconds for object_annotation in object_annotations]
>>> len(tmp)
1142
>>> tmp[0:10]
[0, 1, 2, 4, 5, 7, 7, 7, 7, 7]
>>> 
```