🐈

@samvera/rampビューアのFiles/Markersタブの使用方法

2024/10/17に公開

概要

IIIF Audio/Visualに対応したビューアの一つである@samvera/rampビューアのFiles/Markersタブの使用方法について調べたので備忘録です。

マニュアル

Filesについては、以下に記載がありました。

https://samvera-labs.github.io/ramp/#supplementalfiles

また、Markersについては、以下に記載があります。

https://samvera-labs.github.io/ramp/#markersdisplay

使用するデータ

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

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

Filesタブ

renderingプロパティを読むと記載されています。renderingプロパティについては、以下のCookbookにも掲載されています。

https://iiif.io/api/cookbook/recipe/0046-rendering/

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

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

        japan_search_id = manifest.homepage[1].id.split("/")[-1]

        japan_search_api_url = f"https://jpsearch.go.jp/api/item/{japan_search_id}"

        rendering = ResourceItem(
            label={
                "ja": ["アイテム参照API"],
            },
            id=japan_search_api_url,
            type="Dataset",
            format="application/json"
        )

        manifest.rendering = rendering

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

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

        return output_path

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

{
  "@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巻』(県立長野図書館)を改変"
      ]
    }
  },
  "rendering": [
    {
      "id": "https://jpsearch.go.jp/api/item/sdcommons_npl-02FT0102974177",
      "type": "Dataset",
      "label": {
        "ja": [
          "アイテム参照API"
        ]
      },
      "format": "application/json"
    }
  ],
...
}

ビューアでの表示例は以下です。

なお、renderingプロパティは、Clover IIIFでは以下のように表示されました。

Markersタブ

時間情報を持ったhighlightingmotivationのアノテーションが表示されると記載されています。

以下のようなスクリプトにより、マニフェストファイルにhighlightingmotivationのアノテーションを追加します。

def add_highlight(self, manifest_path, threshold=400):
        manifest = self.load_manifest(manifest_path)

        label_path = f"{self.input_dir}/output_label.json"

        if os.path.exists(label_path):

            with open(label_path, "r") as f:
                label_seg = json.load(f)

            canvas = manifest.items[0]

            labels = label_seg["Labels"]

            anno_page = canvas.annotations[0]

            anno_page_id = anno_page.id

            # duration = 100

            canvas_width = canvas.width
            canvas_height = canvas.height

            for i in tqdm(range(len(labels))):
                label = labels[i]

                if "Timestamp" not in label:
                    continue

                start = label["Timestamp"] / 1000
                # end = start + duration
                name = label["Label"]["Name"]

                if "Instances" not in label["Label"]:
                    continue

                instances = label["Label"]["Instances"]

                for j in range(len(instances)):

                    anno_id = f"{anno_page_id}/a{i}-{j}"

                    bb = instances[j]["BoundingBox"]

                    x = bb["Left"] * canvas_width
                    y = bb["Top"] * canvas_height
                    w = bb["Width"] * canvas_width
                    h = bb["Height"] * canvas_height

                    anno = Annotation(
                        id=anno_id,
                        motivation="highlighting",
                        # target=f"{canvas.id}#xywh={x},{y},{w},{h}&t={start},{end}",
                        target=f"{canvas.id}#t={start}&xywh={x},{y},{w},{h}",
                        # target=f"{canvas.id}#t={start}",
                        body={
                            "type": "TextualBody",
                            "value": name,
                            "format": "text/html",
                        }
                    )            

                    anno_page.add_item(
                        anno
                    )

                if threshold > 0 and i > threshold:
                    break

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

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

        return output_path

注意点として、targetを以下のように記載すると表示されませんでした。

target=f"{canvas.id}#xywh={x},{y},{w},{h}&t={start},{end}",

以下のように、#t=を含み、開始点のみを含む形式が必要なようでした。xywhは任意です。

target=f"{canvas.id}#t={start}&xywh={x},{y},{w},{h}",

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

{
  "@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": [
    {
      "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas",
      "type": "Canvas",
      "height": 480,
      "width": 640,
      "duration": 619.61962,
      "items": [
        {
          "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page",
          "type": "AnnotationPage",
          "items": [
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page/annotation",
              "type": "Annotation",
              "motivation": "painting",
              "body": {
                "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/video.mp4",
                "type": "Video",
                "height": 480,
                "width": 640,
                "duration": 619.61962,
                "format": "video/mp4"
              },
              "target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas"
            }
          ]
        }
      ],
      "annotations": [
        {
          "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2",
          "type": "AnnotationPage",
          "items": [
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2/a1",
              "type": "Annotation",
              "label": {
                "ja": [
                  "WebVTT Transcript (machine-generated)"
                ]
              },
              "motivation": "supplementing",
              "body": {
                "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/video.vtt",
                "type": "Text",
                "format": "text/vtt"
              },
              "target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas"
            },
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2/a69-0",
              "type": "Annotation",
              "motivation": "highlighting",
              "body": {
                "type": "TextualBody",
                "value": "Blackboard",
                "format": "text/html"
              },
              "target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas#t=21.021&xywh=33.72299909591675,23.859649300575256,555.8640289306641,422.45238304138184"
            },
            {
              "id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2/a71-0",
              "type": "Annotation",
              "motivation": "highlighting",
              "body": {
                "type": "TextualBody",
                "value": "Blackboard",
                "format": "text/html"
              },
              "target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas#t=21.521&xywh=5.045213103294373,5.737994760274887,627.296028137207,472.2190475463867"
            },
...
}

注意点として、1つのアノテーションリストのみが処理対象となっていました。そのため、supplementingmotivationのアノテーションと同じ配列に格納しています。

ビューアでの表示例は以下です。以下のように表形式でマーカーが表示されました。マーカーの名前に付与されたリンクをクリックすることで、指定された時間に遷移しました。

また、上記ではsupplementingのアノテーションは表示されず、それらはTrasnscriptsタブにのみ表示されました。

まとめ

IIIF A/Vにおけるアノテーションの取り扱い等について、参考になりましたら幸いです。

Discussion