📚

iiif-prezi3を使って、動画に目次を付与する

2024/10/09に公開

概要

iiif-prezi3を使って、動画に目次を付与する方法に関する備忘録です。

セグメントの検出

Amazon Rekognitionのビデオセグメントの検出を用います。

https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/segments.html

以下などでサンプルコードが公開されています。

https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/segment-example.html

使用するデータ

『県政ニュース 第1巻』(県立長野図書館)を使用します。

https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177

マニフェストファイルへの反映

以下の記事などを参考に、マニフェストファイルが作成済みであるとします。

https://zenn.dev/nakamura196/articles/bf748ba5868e86

以下のようなスクリプトにより、マニフェストファイルにvttファイルを追加します。

from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config, HomepageItem, KeyValueString

#| export
class IiifClient:

    def load_manifest(self, manifest_path):
        with open(manifest_path, "r") as f:
            manifest_json = json.load(f)

        manifest = Manifest(**manifest_json)

        return manifest


    def add_segment(self, manifest_path):
        manifest = self.load_manifest(manifest_path)

        path = f"{self.input_dir}/output_segment.json"

        with open(path, "r") as f:
            data = json.load(f)

        range_id = f"{self.prefix}/range"

        range_toc = manifest.make_range(
            id=f"{range_id}/r", 
            label="Table of Contents"
        )

        canvas_id = manifest.items[0].id

        for s in data["Segments"]:

            s_type = s["Type"]

            if s_type != "SHOT":
                continue

            index = s["Shot Index"]

            start = s["Start Timestamp (milliseconds)"] / 1000
            end = s["End Timestamp (milliseconds)"] / 1000

            range_seg = range_toc.make_range(
                id=f"{range_id}/r{index}",
                label=f"Segment {index}",
            )

            range_seg.items.append({
                "id": f"{canvas_id}#t={start},{end}",
                "type": "Canvas"
            })

        output_path = f"{self.input_dir}/manifest_segment.json"

        with open(output_path, "w") as f:
            f.write(manifest.json(indent=2))

        return output_path
        

以下のようなマニフェストファイルが作成されます。

https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest_segment.json

{
  "@context": "http://iiif.io/api/presentation/3/context.json",
  "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest.json",
  "type": "Manifest",
  "label": {
    "ja": [
      "県政ニュース 第1巻"
    ]
  },
  "requiredStatement": {
    "label": {
      "ja": [
        "Attribution"
      ]
    },
    "value": {
      "ja": [
        "『県政ニュース 第1巻』(県立長野図書館)を改変"
      ]
    }
  },
  "homepage": [
    {
      "id": "https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177",
      "type": "Text",
      "label": {
        "ja": [
          "信州デジタルコモンズ 県立長野図書館所蔵資料"
        ]
      }
    },
    {
      "id": "https://jpsearch.go.jp/item/sdcommons_npl-02FT0102974177",
      "type": "Text",
      "label": {
        "ja": [
          "ジャパンサーチ"
        ]
      }
    }
  ],
  "items": [
    ...
  ],
  "structures": [
    {
      "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/range/r",
      "type": "Range",
      "label": {
        "ja": [
          "Table of Contents"
        ]
      },
      "items": [
        {
          "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/range/r0",
          "type": "Range",
          "label": {
            "ja": [
              "Segment 0"
            ]
          },
          "items": [
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas#t=0.0,5.338",
              "type": "Canvas"
            }
          ]
        },
        {
          "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/range/r1",
          "type": "Range",
          "label": {
            "ja": [
              "Segment 1"
            ]
          },
          "items": [
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas#t=5.372,6.74",
              "type": "Canvas"
            }
          ]
        },
        ...
        {
          "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/range/r151",
          "type": "Range",
          "label": {
            "ja": [
              "Segment 151"
            ]
          },
          "items": [
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas#t=618.651,619.586",
              "type": "Canvas"
            }
          ]
        }
      ]
    }
  ]
}

ビューアでの表示例

ビューアでの表示例は以下です。Theseus Viewerを使用しています。

https://theseusviewer.org/?iiif-content=https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest_segment.json

まとめ

IIIFを用いた動画ファイルへの目次の付与にあたり、参考になりましたら幸いです。

Discussion