国立国会図書館 歴史的音源で公開されている音声をmp4に変換する

概要 国立国会図書館 歴史的音源(以下、れきおん)で公開されている音声をmp4に変換する機会がありましたので、備忘録です。 れきおんの提供形式 れきおんでは、m3u8形式のファイルが公開されていました。 例えば、以下の「講演:道徳、経済合一論(一)Union of Morality of Economy」を確認してみます。 https://rekion.dl.ndl.go.jp/pid/3574643 開発者ツールなどで確認すると、以下のURLからアクセスできることが確認できます。 https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8 このURLを構成するIDなどは、以下のAPIの返却結果の中で確認できました。 https://rekion.dl.ndl.go.jp/api/item/search/info:ndljp/pid/3574643 pidから上記のURLを取得するAPIの開発 上記のJSONを処理することで、m3u8ファイルのURLを取得します。 この部分をAPI化したので、試していただけますと幸いです。 https://iiif-demo-next.vercel.app/api/rekion/3574643 以下のような結果が得られます。 { "data": { "type": "rekion", "id": "3574643", "attributes": { "title": "講演:道徳、経済合一論(一)Union of Morality of Economy", "url": "https://rekion.dl.ndl.go.jp/pid/3574643", "hls": "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" } } } ソースコードは以下です。 https://github.com/nakamura196/iiif-demo-next/blob/main/src/app/api/rekion/[id]/route.ts ffmpegを使ってmp4に変換する 以下のようなコマンドにより、m3u8ファイルをmp4形式に変換できました。 ffmpeg -i "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" -c copy 3574643.mp4 まとめ 音声ファイルの利用にあたり、参考になりましたら幸いです。

2024年7月9日 · 1 分 · Nakamura

Rampをカスタマイズする

概要 Rampのカスタマイズ方法に関する備忘録です。カスタマイズの結果、以下のように、UIの一部を日本語化し、メディアプレイヤーとメタデータおよび文字起こしを左右に並べて表示します。また、クエリパラメータtを使って、音声の再生開始時間を指定できるようにします。 例えば、以下のURLから、140秒時点から再生することができます。 https://ramp-iiif.vercel.app/?iiif-content=https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json&t=140 以下がカスタマイズ前です。 セットアップ 以下の記事の参考にしてください。 カスタマイズ 音声の再生開始時間の指定 以下のマニュアルにおいて、startCanvasTimeプロパティが使えることがわかります。 https://samvera-labs.github.io/ramp/#!/IIIFPlayer そこで、以下のindex.jsファイルに対して、startCanvasTimeをクエリパラメータから取得する処理を追加します。 import React from 'react'; import ReactDOM from 'react-dom'; import App from './app'; // import config from './config'; const manifestURL = () => { const params = new URLSearchParams(window.location.search); // let url = `${config.url}/manifests/${config.env}/lunchroom_manners.json`; let url = "https://nakamura196.github.io/ramp_data/demo/3571280/manifest.json" if (params.has('iiif-content')) { url = params.get('iiif-content'); } return url; }; const startCanvasTime = () => { const params = new URLSearchParams(window.location.search); if (params.has('t')) { return parseFloat(params.get('t')); } return 0; } ReactDOM.render(<App manifestURL={manifestURL()} startCanvasTime={startCanvasTime()} />, document.getElementById('root')); そして、app.jsに対して、startCanvasTimeプロパティを与えます。これにより、クエリパラメータから、メディアの再生開始時間を指定できます。 ... <IIIFPlayer manifestUrl={manifestUrl} startCanvasTime={canvasTime} > ... 日本語化およびレイアウトの変更 上記と同様、demo/app.jsファイルを編集することで、日本語化およびレイアウトの変更を行うことができます。 Vercelへのデプロイ Build & Development Settingsを以下のように指定します。 Build Commandにnpm run demo:build、Output Directoryにdemo/distを設定します。 また、Node.js Versionを18.xにする必要がありました。20.xの場合、パッケージのインストール時にエラーが発生しました。 まとめ Rampの開発に関わる方々に感謝いたします。RampおよびIIIF Presentation API v3の利用にあたり、参考になりましたら幸いです。 ...

2024年7月9日 · 1 分 · Nakamura

Rampをローカルで起動する

概要 Rampをローカルで起動してみましたので、備忘録です。 背景 Rampは以下のように説明されています。 Interactive, IIIF powered audio/video media player React components library. (日本語訳)インタラクティブな、IIIF対応のオーディオ/ビデオメディアプレイヤーReactコンポーネントライブラリ 以下のGitHubリポジトリでソースコードが公開されています。 https://github.com/samvera-labs/ramp 起動 以下で起動できました。 git clone https://github.com/samvera-labs/ramp pnpm i pnpm demo 以下に記載があります。 https://github.com/samvera-labs/ramp?tab=readme-ov-file#styleguidist-development 以下の場合は、スタイルガイドのページが表示されますので、ご注意ください。 pnpm dev まとめ 参考になりましたら幸いです。

2024年7月8日 · 1 分 · Nakamura

Mirador 3でScroll Viewを使う

概要 Mirador 3でScroll Viewを使う方法についての備忘録です。 以下、「鹿児嶋征討記之内 高瀬口河通ノ戦争野津公聯隊旗を取返ス図(国立国会図書館所蔵)」を例としています。 このIIIFマニフェストは3つのキャンバス(画像)から構成されており、通常の表示方法(Single, 単一モード)では、画像ごとに表示されます。 これを3つ繋げて表示することを目指します。 デモ 以下からお試しいただけます。 https://nakamura196.github.io/mirador-multi-image/ IIIFマニフェストファイルについては、国立国会図書館で公開されているIIIFマニフェストファイルを一部変更しています。 変更前 https://dl.ndl.go.jp/api/iiif/1301543/manifest.json 変更後 https://nakamura196.github.io/mirador-multi-image/manifest.json 変更箇所として、今回の記事の目的であるScroll表示と直接関係がありませんが、画像が右から左に表示されるように、"viewingDirection": "right-to-left"を追加しています。 Miradorの設定 Mirador 2では事前設定なしにScroll Viewが使えましたが、Mirador 3のデフォルト設定では、Scroll Viewは無効化されているようでした。 https://projectmirador.org/embed/?iiif-content=https://nakamura196.github.io/mirador-multi-image/manifest.json そこで、Mirador 3の初期設定を以下のように修正します。 https://github.com/nakamura196/mirador-multi-image/blob/main/docs/index.html const config = { id: "mirador", windows: [ { manifestId: "./manifest.json", }, ], language: "ja", window: { sideBarOpenByDefault: true, defaultSideBarPanel: "info", defaultView: "scroll", views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }], }, }; Mirador.viewer(config); ポイントは、views: [{ key: "single" }, { key: "gallery" }, { key: "scroll" }]です。ここで、Scroll Viewを追加することで、以下のように選択肢として表示されるようになりました。 参考 defaultView未指定時のバグ デフォルト表示を未指定の場合、上記の例ではSingle(単一)表示が使用されますが、その状態からScroll Viewボタンを押すと、表示がうまく切り替わらないケースがありました。 この問題について、上記のように、defaultView: "scroll"を設定しておくことで回避できました。根本的な解決方法は改めて調査したいと思います。 ...

2024年7月6日 · 1 分 · Nakamura

Traefikでhttpsにリダイレクトさせる

概要 以下の記事でTraefikを使ったhttps化したコンテナの運用例を紹介しました。 ただ、(現在は修正済み)http接続をhttps接続にリダイレクトする設定が漏れており、80ポートにアクセスすると、not foundになっていました。 この点の修正方法に関する備忘録です。 変更前 log: # level: DEBUG entryPoints: web: address: :80 websecure: address: :443 api: dashboard: true providers: docker: exposedByDefault: false certificatesResolvers: myresolver: acme: email: aaa@bbb storage: /acme.json caServer: https://acme-v02.api.letsencrypt.org/directory # caServer: https://acme-staging-v02.api.letsencrypt.org/directory httpChallenge: entryPoint: web 変更後 log: # level: DEBUG entryPoints: web: address: :80 http: redirections: entryPoint: to: websecure schema: https permanent: true websecure: address: :443 api: dashboard: true providers: docker: exposedByDefault: false certificatesResolvers: myresolver: acme: email: na.kamura.1263@gmail.com storage: /acme.json caServer: https://acme-v02.api.letsencrypt.org/directory # caServer: https://acme-staging-v02.api.letsencrypt.org/directory httpChallenge: entryPoint: web entryPointsの部分について、以下のようにリダイレクトの設定を追加しています。 ...

2024年7月4日 · 1 分 · Nakamura

Chromeでサイズが大きい動画が再生できない

概要 Chromeにおいて、サイズが大きい動画が再生できないことがありました。一方、Safariでは再生できました。 開発者ツールで確認すると、ダウンロードがキャンセルされていました。 ビューア部分は以下のようになっています。 <video controls="controls" preload="none" style="width: 620px; height: 465px;" width="100%" height="100%"> <source src="https://omeka.aws.ldas.jp/files/original/c486fe4ae8d926034678fa11b0d6b2fd55b0e695.mp4" type="video/quicktime" title="undefined"> </video> このHTMLは、以下の記事で紹介した、Omeka S + IIIF Serverの組み合わせによって作成されたものです。 原因 先ほどのhtmlを確認すると、type="video/quicktime"となっており、拡張子はmp4となっていますが、中身は異なる(movファイル?)ことがわかります。 おそらく動画の拡張子のみが変更され、Omeka Sに登録された際、Omeka Sが中身からtypeを指定したように思われます。 Safariで再生できたのも、これが原因かと思われます。 対処法 例えば、macの場合は、以下によりmp4に変換できます。 brew install ffmpeg ffmpeg -i aaa.mov aaa.mp4 まとめ Omeka Sなどで動画ファイルを配信する際の参考になりましたら幸いです。

2024年7月4日 · 1 分 · Nakamura

Omeka SのSetEnv APPLICATION_ENVのproductionとdevelopmentの違い

Omeka Sでのエラー詳細の表示を有効にする手順は次の通りです。この設定を行うことで、「Omeka S has encountered an error」というページに具体的なエラーメッセージと詳細が表示されるようになります。また、PHPレベルのエラーや警告もページ上に表示されるようになります。これは開発中に問題の特定と解決を容易にするためのものですが、セキュリティ上の理由から本番環境では使用しないことが推奨されます。 エラー詳細の表示を有効にする手順 .htaccessファイルを見つける : Omeka Sのインストールフォルダのメインディレクトリに.htaccessファイルがあります。このファイルはWebサーバーの設定をカスタマイズするために使用されるものです。 .htaccessファイルを編集する : .htaccess ファイルをテキストエディタで開きます。 ファイル内の次の行を探します。 SetEnv APPLICATION_ENV "production" * この行を次のように変更します。 SetEnv APPLICATION_ENV "development" 変更を保存してサーバーを再起動する : 変更を保存した後、Webサーバーを再起動する必要がある場合があります。これはサーバーの設定に依存します。 この変更により、Omeka Sは「開発」モードで実行されるようになり、エラーが発生した際には詳細な情報が表示されるようになります。これは問題の診断と解決に非常に役立ちますが、セキュリティ上のリスクも伴うため、公開環境では使用しないようにしてください。

2024年7月4日 · 1 分 · Nakamura

TraefikでHTTPS化した複数コンテナを運用する

概要 TraefikでHTTPS化した複数コンテナを運用する方法に関する備忘録です。 https://github.com/traefik/traefik 背景 これまで、jwilder/nginx-proxyとjrcs/letsencrypt-nginx-proxy-companionを使い、以下のような構成で運用していました。 プロキシ version: '3' # proxy services: nginx-proxy: image: jwilder/nginx-proxy container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - html:/usr/share/nginx/html - dhparam:/etc/nginx/dhparam - vhost:/etc/nginx/vhost.d - certs:/etc/nginx/certs:ro - /var/run/docker.sock:/tmp/docker.sock:ro - /srv/docker/nginx-proxy-with-encrypt/log:/var/log/nginx labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" restart: always letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion container_name: nginx-proxy-lets-encrypt depends_on: - "nginx-proxy" volumes: - certs:/etc/nginx/certs:rw - vhost:/etc/nginx/vhost.d - html:/usr/share/nginx/html - /var/run/docker.sock:/var/run/docker.sock:ro volumes: certs: html: vhost: dhparam: networks: default: external: name: common_link コンテナ 以下は、Djangoの例です。 ...

2024年7月4日 · 2 分 · Nakamura

Omeka S GoogleAnalyticsモジュールの不具合対応

概要 Omeka Sにおいて、Google Analyticsを有効するにするためのモジュールとして、Google Analyticsがあります。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/ 本モジュールを有効化した際、以下のエラーメッセージが表示されるケースがありました。 Undefined index: additional_snippet in (...) /modules/GoogleAnalytics/Module.php on line 316 これについて、以下のIssueも上がっていました。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/issues/9 本件の対応方法について共有します。 対応方法 以下のように変更します。 https://github.com/Libnamic/Omeka-S-GoogleAnalytics/pull/10/commits/0123ce557d0f38834c5c37fa1ac9c986c87cbc90 具体的には、以下です。 変更前 if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) $extra_snippet = $settings['additional_snippet']; } if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) $extra_snippet = $settings['additional_snippet']; } 変更後 if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) // Assuming this is part of the code where you handle the extra snippet if (isset($settings['additional_snippet']) && !empty($settings['additional_snippet'])) { $extra_snippet = $settings['additional_snippet']; } else { $extra_snippet = ''; // Default value if 'additional_snippet' key is not set } } if (empty($extra_snippet)) { $settings = $this->getServiceLocator()->get('Omeka\Settings'); $settings = $settings->get('googleanalytics', ''); if ($settings != null) // Assuming this is part of the code where you handle the extra snippet if (isset($settings['additional_snippet']) && !empty($settings['additional_snippet'])) { $extra_snippet = $settings['additional_snippet']; } else { $extra_snippet = ''; // Default value if 'additional_snippet' key is not set } } まとめ 上記の変更が完全に正しいか自信はありませんが、プルリクエストも出しておきました。 ...

2024年7月3日 · 1 分 · Nakamura

Amazon S3とRoute 53を使ってリダイレクトする

概要 あるURLから他のURLにリダイレクトさせる必要があり、Amazon S3とRoute 53を使用して実現することができたので、備忘録です。 方法 この方法では、S3バケットを使ってリダイレクトを行い、DNS設定にはRoute 53を使用します。以下にその手順を説明します。 ステップ1: Amazon S3バケットの設定 Amazon S3で新しいバケットを作成します。バケット名はリダイレクトさせたいドメイン名と一致させます(例:example.com)。 バケットのプロパティで「静的ウェブサイトホスティング」を選択します。 「静的ウェブサイトホスティング」のオプションで、「リダイレクト要求」を選び、リダイレクト先のURL(http://example.net など)を入力します。 ステップ2: Route 53でのDNS設定 Route 53で、リダイレクトするドメイン名のホストゾーンを開きます。 新しいレコードセットを作成します。レコードのタイプは A を選択します。 「エイリアス」を「はい」に設定します。 エイリアスターゲットとして、ステップ1で設定したS3バケットの静的ウェブサイトホスティングのエンドポイントを選択します(例:example.com.s3-website-us-east-1.amazonaws.com)。 これで、指定したドメインにアクセスがあった場合、設定したURLにリダイレクトされるようになります。この方法は、簡単でありながら効果的にドメインから別のURLへのリダイレクトを実現することができます。 まとめ 参考になりましたら幸いです。

2024年7月3日 · 1 分 · Nakamura

Docker版のOmeka SでCORS対応を行う

概要 Docker版のOmeka Sで、以下の記事のようにCORS対応を実施した際、サーバエラーが発生しました。その備忘録を記載します。 Dockerfile 以下のようなDockerfileを対象とします。 FROM php:apache LABEL maintainer="Satoru Nakamura <na.kamura.1263@gmail.com>" RUN a2enmod rewrite ENV DEBIAN_FRONTEND noninteractive RUN apt-get -qq update && apt-get -qq -y upgrade RUN apt-get install -y \ zlib1g-dev \ libpng-dev \ libjpeg-dev \ libfreetype6-dev \ imagemagick \ unzip \ wget # PHP extensions RUN docker-php-ext-install -j$(nproc) iconv pdo pdo_mysql mysqli gd RUN docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/ # Download Omeka-s ARG version=4.1.1 RUN wget https://github.com/omeka/omeka-s/releases/download/v${version}/omeka-s-${version}.zip -O /var/www/omeka-s-${version}.zip \ && unzip -q /var/www/omeka-s-${version}.zip -d /var/www/ \ && rm /var/www/omeka-s-${version}.zip \ && rm -rf /var/www/html/ \ && mv /var/www/omeka-s/ /var/www/html/ COPY ./.htaccess /var/www/html/.htaccess # Configure volumes and permissions COPY ./database.ini /var/www/html/volume/config/ RUN mkdir -p /var/www/html/volume/files/ \ && rm /var/www/html/config/database.ini \ && ln -s /var/www/html/volume/config/database.ini /var/www/html/config/database.ini \ && rm -Rf /var/www/html/files/ \ && ln -s /var/www/html/volume/files/ /var/www/html/files \ && chown -R www-data:www-data /var/www/html/ \ && find /var/www/html/volume/ -type f -exec chmod 600 {} \; VOLUME /var/www/html/volume/ CMD ["apache2-foreground"] 原因と対策 以下を追記する必要がありました。 ...

2024年7月2日 · 1 分 · Nakamura

Omeka SのIIIF ServerモジュールでのCORSエラー

概要 Omeka SのIIIF Serverモジュールを使ってIIIFマニフェストを配信した際、外部のビューア等で以下のCORSエラーが発生しました。 Access to fetch at 'https://xxx/iiif/2/09fd29d5-8497-4def-a64d-ca104284f90d/manifest' from origin 'https://universalviewer.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 本記事では、Omeka SでのCORSエラーへの対策について紹介します。 対策 https://github.com/Daniel-KM/Omeka-S-module-IiifServer?tab=readme-ov-file#cors-cross-origin-resource-sharing 以下を追加しました。 SetEnv APPLICATION_ENV "production" ... </FilesMatch> Header setIfEmpty Access-Control-Allow-Origin "*" Header setIfEmpty Access-Control-Allow-Headers "origin, x-requested-with, content-type" Header setIfEmpty Access-Control-Allow-Methods "GET, POST" これにより、CORSの問題を解決することができました。 ...

2024年7月2日 · 1 分 · Nakamura

LEAF Writer:スキーマのカスタマイズ

概要 LEAF Writerのカスタマイズ方法に関する調査記録です。 https://gitlab.com/calincs/cwrc/leaf-writer/leaf-writer 今回はスキーマのカスタマイズ方法に関する備忘録です。以下のように、日本語訳などを表示することを目指します。 以下は、カスタマイズ前の表示です。以下のスキーマに基づき、多くの要素が英語の説明とともに表示されます。 https://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng 方法 以下のように、スキーマファイルを指定します。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/xml/lw/01.xml 具体的には、以下です。 <?xml-model href="https://kouigenjimonogatari.github.io/lw/tei_genji.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> LEAF Writerはこのスキーマファイルを読み込み、validationや使用可能な要素の提示を行うようでした。 これはLEAF Writerに特化した機能ではなく、Oxygen XML Editorのような一般的なXMLエディタにおいても同じように動作することが多いようです。 (参考)LEAF Writerのカスタマイズ 上述したように、LEAF Writerでは、ロードしたXMLファイルで指定されたスキーマを参照するため、エディタとスキーマは疎結合な構成になっています。 しかし、LEAF Writer側で事前に定義したスキーマ以外を参照する場合、以下のようなダイアログが表示され、「ADD SCHEMA」ボタンから、独自に定義したスキーマの情報をLEAF Writerに教える必要があります。 上記の登録処理を行えば問題ありませんが、LEAF Writer側に事前に定義を追加しておきたい場合には、LEAF Writerをカスタマイズする必要があります。 具体的には、以下のように修正を加えることで、LEAF Writer側に指定したスキーマおよびCSSを事前登録できました。 https://gitlab.com/nakamura196/leaf-writer/-/commit/dc5108978bc3013a80965913d74e729daf6941f2 packages/cwrc-leafwriter/src/config/schemas.tsファイルに以下を追加しました。 ... { id: 'teiGenji', name: 'TEI Genji', mapping: 'tei', rng: ['https://kouigenjimonogatari.github.io/lw/tei_genji.rng'], css: ['https://kouigenjimonogatari.github.io/lw/tei_genji.css'], }, ... これにより、指定したスキーマがLEAF Writerに事前登録され、以後、同じスキーマを参照する際には、上記の追加設定は不要になりました。 まとめ TEIおよびLEAF Writerなどのツールにおけるスキーマの取り扱いについて、参考になりましたら幸いです。

2024年6月29日 · 1 分 · Nakamura

Google スプレッドシート + GAS(Google Apps Script)でonEditが2回実行されてしまう

概要 GAS(Google Apps Script)を使って、Google スプレッドシートの編集時に追加処理を行うスクリプトを用意した際に、Google スプレッドシートの編集によって、onEdit関数が2回実行されるケースがありました。 原因と解決策 原因は、スプレッドシートの編集時のトリガーとしてもonEdit関数を選択していることが原因でした。 onEdit関数は予約済みの関数であるため、トリガーの設定を行う必要がありませんでした。 まとめ 同様の事象でお困りの方の参考になりましたら幸いです。

2024年6月28日 · 1 分 · Nakamura

RDF、TurtleやJSON-LD、およびIIIFマニフェストファイルなどの関係を理解する

概要 IIIFマニフェストがJSON-LDで記述されていることを確認するため、他のフォーマットに変換してみましたので、備忘録です。 RDFと、JSON-LDやTurtleなどのファイルフォーマットの関係、およびJSON-LDによって記述されているIIIFマニフェストファイルとの関係など、参考になりましたら幸いです。 対象 今回は、NDLデジタルコレクションで公開されている以下のマニフェストファイルを対象にします。 https://dl.ndl.go.jp/api/iiif/3437686/manifest.json 変換 EASY RDF Converterを使用します。 https://www.easyrdf.org/converter 以下のように、IIIFマニフェストファイルのURLを指定して、Input FormatにJSON-LD、Output FormatにTurtleを指定します。 結果、以下のように変換されました。 @prefix ns0: <http://iiif.io/api/presentation/2#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . @prefix dc: <http://purl.org/dc/terms/> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix exif: <http://www.w3.org/2003/12/exif/ns#> . @prefix dc11: <http://purl.org/dc/elements/1.1/> . @prefix ns1: <http://rdfs.org/sioc/services#> . @prefix doap: <http://usefulinc.com/ns/doap#> . @prefix oa: <http://www.w3.org/ns/oa#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . <https://dl.ndl.go.jp/api/iiif/3437686/manifest.json> a <http://iiif.io/api/presentation/2#Manifest> ; ns0:attributionLabel "国立国会図書館 National Diet Library, JAPAN"^^xsd:string ; ns0:hasRanges ( <https://dl.ndl.go.jp/api/iiif/3437686/range/1> <https://dl.ndl.go.jp/api/iiif/3437686/range/2> <https://dl.ndl.go.jp/api/iiif/3437686/range/3> <https://dl.ndl.go.jp/api/iiif/3437686/range/4> <https://dl.ndl.go.jp/api/iiif/3437686/range/5> <https://dl.ndl.go.jp/api/iiif/3437686/range/6> <https://dl.ndl.go.jp/api/iiif/3437686/range/7> <https://dl.ndl.go.jp/api/iiif/3437686/range/8> <https://dl.ndl.go.jp/api/iiif/3437686/range/9> <https://dl.ndl.go.jp/api/iiif/3437686/range/10> <https://dl.ndl.go.jp/api/iiif/3437686/range/11> <https://dl.ndl.go.jp/api/iiif/3437686/range/12> <https://dl.ndl.go.jp/api/iiif/3437686/range/13> <https://dl.ndl.go.jp/api/iiif/3437686/range/14> <https://dl.ndl.go.jp/api/iiif/3437686/range/15> <https://dl.ndl.go.jp/api/iiif/3437686/range/16> ) ; ns0:hasSequences ( _:genid18 ) ; ns0:metadataLabels ( _:genid20 _:genid22 _:genid24 _:genid26 _:genid28 _:genid30 _:genid32 _:genid34 _:genid36 _:genid38 _:genid40 ) ; dc:rights <https://dl.ndl.go.jp/ja/iiif_license.html> ; rdfs:label "校異源氏物語. 巻一"^^xsd:string ; rdfs:seeAlso <https://dl.ndl.go.jp/api/oaipmh?verb=GetRecord&metadataPrefix=dcndl_porta&identifier=oai:dl.ndl.go.jp:info:ndljp/pid/3437686> ; foaf:logo <https://dl.ndl.go.jp/img/logo/ndldc/iiif-logo.png> . <https://dl.ndl.go.jp/api/iiif/3437686/range/1> a ns0:Range ; ns0:hasCanvases ( <https://dl.ndl.go.jp/api/iiif/3437686/canvas/3> ) ; rdfs:label "校異源氏物語 卷一"^^xsd:string . <https://dl.ndl.go.jp/api/iiif/3437686/canvas/3> a ns0:Canvas ; ns0:hasImageAnnotations ( _:genid43 ) ; rdfs:label "3"^^xsd:string ; exif:height 4706 ; exif:width 6890 . <https://dl.ndl.go.jp/api/iiif/3437686/range/2> a ns0:Range ; ns0:hasCanvases ( <https://dl.ndl.go.jp/api/iiif/3437686/canvas/19> ) ; rdfs:label "目次"^^xsd:string . <https://dl.ndl.go.jp/api/iiif/3437686/canvas/19> a ns0:Canvas ; ns0:hasImageAnnotations ( _:genid46 ) ; rdfs:label "19"^^xsd:string ; exif:height 4706 ; exif:width 6890 . ... RDF/XMLにも変換してみます。 ...

2024年6月28日 · 2 分 · Nakamura

校異源氏物語・本文テキストデータリポジトリで公開しているTEI/XMLを一部更新しました。

概要 以下のリポジトリで校異源氏物語のTEI/XMLファイルを公開しています。 https://github.com/kouigenjimonogatari ここで公開しているTEI/XMLに対して、一部変更を加えましたので、備忘録です。 フォルダ構成 修正前のファイルは以下に格納しています。これまでから変更はありません。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/tree/master/tei 更新したファイルは以下に格納しました。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/tree/master/xml/lw 後述する修正を加えたXMLファイルが格納されています。 修正内容 スキーマの追加 以下のrngファイルを追加しました。 <?xml-model href="https://kouigenjimonogatari.github.io/lw/tei_genji.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> このrngファイルは、使用するタグを限定し、かつ日本語訳を追加したものです。Romaで作成しており、rngファイルへの変換前のoddファイルもリポジトリに格納しています。 https://github.com/kouigenjimonogatari/kouigenjimonogatari.github.io/blob/master/lw/tei_genji.odd Romaの使い方等については、以下を参考にしてください。 これにより、例えばOxygen XML EditorやLEAF Writerなどにおいて、候補として表示されるタグが限定され、一部日本語訳が表示されるようになります。 LEAF Writerでの表示例は以下をご確認ください。 https://leaf-writer.leaf-vre.org/edit?provider=github&owner=kouigenjimonogatari&ownerType=organization&repo=kouigenjimonogatari.github.io&path=xml%2Flw&filename=01.xml CSSの追加 以下のcssファイルを追加しました。 <?xml-stylesheet type="text/css" href="https://kouigenjimonogatari.github.io/lw/tei_genji.css"?> 上記のスキーマの追加と同様、Oxygen XML EditorやLEAF Writerなどにおいて、追加したcssファイルに基づく表示に変更されました。 revisionDescの追加 revisionDesc要素を追加しました。今後の修正内容を記録していく予定です。 <revisionDesc status="published"> <change when="2024-06-28" who="#snakamura">pb要素のfacs属性を修正しました。facsimile要素を修正しました。</change> </revisionDesc> pb要素の変更 pb要素の記述方法を以下のように修正しました。 <pb corresp="#zone_0005" facs="https://dl.ndl.go.jp/api/iiif/3437686/R0000022/0,0,3445,4706/full/0/default.jpg" n="5"/> facs属性に対して、画像のURLを与えることで、LEAF Writerなどにおいて、Image Viewerの利用が可能になりました。 facsimile要素の記述方法の変更 IIIFマニフェストやキャンバスとの対応付の方法について、以下のガイドラインを参考に、修正しました。 https://github.com/TEI-EAJ/jp_guidelines/wiki/IIIF画像とのリンク#2024-年度版 以下に、変更前と変更後を示します。 変更前 <facsimile> <surfaceGrp facs="https://dl.ndl.go.jp/api/iiif/3437686/manifest.json"> <surface> <graphic n="https://dl.ndl.go.jp/api/iiif/3437686/canvas/22" url="https://dl.ndl.go.jp/api/iiif/3437686/R0000022/full/full/0/default.jpg" /> <zone xml:id="zone_0005" lrx="3445" lry="4706" ulx="0" uly="0" /> </surface> 変更後 <facsimile sameAs="https://dl.ndl.go.jp/api/iiif/3437686/manifest.json"> <surface lrx="6890" lry="4706" sameAs="https://dl.ndl.go.jp/api/iiif/3437686/canvas/22" ulx="0" uly="0" xml:id="f001"> <graphic height="4706px" sameAs="https://dl.ndl.go.jp/api/iiif/3437686/R0000022" url="https://dl.ndl.go.jp/api/iiif/3437686/R0000022/full/full/0/default.jpg" width="6890px"/> <zone lrx="3445" lry="4706" ulx="0" uly="0" xml:id="zone_0005"/> </surface> IIIF Image APIの情報や画像のサイズに関する情報が追加され、より機械的に利用しやすい形になったかと思います。 ...

2024年6月28日 · 1 分 · Nakamura

カスタマイズしたMirador 4をnpmパッケージとして公開する

概要 カスタマイズしたMirador 4をnpmパッケージとして公開する機会がありましたので、備忘録です。 Fork 以下の公式サイトからリポジトリをForkします。 https://github.com/projectmirador/mirador 以下のようになります。 ブランチを作成する クローンし、ブランチを作成します。 git clone https://github.com/nakamura196/mirador cd mirador git checkout -b feature-add-immediately-property 以下のように出力されます。 Switched to a new branch 'feature-add-immediately-property' 開発 以下で紹介したような改修を加えます。 テスト テストして、問題がないか確認します。 pnpm test コミット git add . git commit -a -m "feat: add immediately property" マージ masterブランチに戻って、feature-add-immediately-propertyの内容をマージする git checkout master git merge feature-add-immediately-property push masterブランチの変更内容をpushしておきます。 git push publish 以下のコマンドにより、ローカルの変更を一時的に無視するようにします。(他に良い方法がありそうです…) git update-index --assume-unchanged package.json パッケージ名を別名に変更します。 { "name": "@nakamura196/mirador", "version": "4.0.0-alpha.3", "description": "An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.", "main": "dist/cjs/src/index.js", "module": "dist/es/src/index.js", "files": [ "dist" ], "sideEffects": false, ... publishします。 ...

2024年6月27日 · 1 分 · Nakamura

Mirador 4の拡大・縮小・回転の挙動を確認する

概要 Mirador 4の拡大・縮小・回転の挙動を変更する必要があり、その変更方法に関する備忘録です。 セットアップ 以下により、ローカルでMirador 4を起動します。 git clone https://github.com/projectmirador/mirador cd mirador pnpm i pnpm start ポート4444で起動します。 zoomIn時の処理のカスタマイズ 一例ですが、zoomInボタンをクリックした際の処理を以下のように変更してみます。 ... handleZoomInClick() { const { windowId, updateViewport, viewer } = this.props; updateViewport(windowId, { // zoom: viewer.zoom * 2, zoom: viewer.zoom * 1.1, // 追加 rotation: viewer.rotation + 5, // 追加 x: viewer.x * 1.1, // 追加 y: viewer.y * 1.1, // 追加 }); } ... 結果、zoomInボタンを押した際に、中心が少しずれながら、拡大・回転が行われることがわかります。 https://youtu.be/wn1WxpTVpS4 これを応用することで、Mirador 3の拡大・縮小・回転等のカスタマイズを行うことができます。 immediateの設定 上記の例では、拡大や回転が完了するまで少し時間がかかっていました。これを即座に行いたい場合、以下のOpenSeadragonViewer.jsのcomponentDidUpdateをカスタマイズします。 viewerConfigオブジェクトのimmediatelyプロパティに基づき、拡大縮小や回転を即座に実施するかを設定できるようにします。 ... componentDidUpdate(prevProps, prevState) { const { viewerConfig, canvasWorld, } = this.props; const { viewer } = this.state; this.apiRef.current = viewer; if (prevState.viewer === undefined) { if (viewerConfig) { viewer.viewport.panTo(viewerConfig, true); viewer.viewport.zoomTo(viewerConfig.zoom, viewerConfig, true); viewerConfig.degrees !== undefined && viewer.viewport.setRotation(viewerConfig.degrees); viewerConfig.flip !== undefined && viewer.viewport.setFlip(viewerConfig.flip); } this.addAllImageSources(!(viewerConfig)); return; } if (!this.infoResponsesMatch(prevProps.infoResponses) || !this.nonTiledImagedMatch(prevProps.nonTiledImages) ) { viewer.close(); const canvasesChanged = !(isEqual(canvasWorld.canvasIds, prevProps.canvasWorld.canvasIds)); this.addAllImageSources((canvasesChanged || !viewerConfig)); } else if (!isEqual(canvasWorld.layers, prevProps.canvasWorld.layers)) { this.refreshTileProperties(); } else if (viewerConfig && !this.osdUpdating) { const { viewport } = viewer; const immediately = viewerConfig.immediately || false; if (viewerConfig.x !== viewport.centerSpringX.target.value || viewerConfig.y !== viewport.centerSpringY.target.value) { viewport.panTo(viewerConfig, immediately); } if (viewerConfig.zoom !== viewport.zoomSpring.target.value) { viewport.zoomTo(viewerConfig.zoom, viewerConfig, immediately); } if (viewerConfig.rotation !== viewport.getRotation()) { viewport.setRotation(viewerConfig.rotation, immediately); } if (viewerConfig.flip !== viewport.getFlip()) { viewport.setFlip(viewerConfig.flip); } } } ... そして、先のZoomControls.jsにおいて、immediately: trueを追加します。 ...

2024年6月26日 · 2 分 · Nakamura

zenodoで資料を公開する

概要 zenodoの使い方を学ぶにあたり、資料を登録してみましたので、備忘録です。登録した資料に付与されたDOIは以下です。 https://zenodo.org/doi/10.5281/zenodo.12508032 DOI DOIについては、最新のバージョンにアクセスできるものと、各バージョンに付与されるものがあり、上記のDOIは前者の者です。バージョン1は以下です。 https://zenodo.org/doi/10.5281/zenodo.12508033 バージョンについては、以下の記事も参考にしてください。 バージョン ファイルの追加や更新を行わない限り、バージョンを変更する必要はなさそうでした。PDFをアップロードした際にDOIが付与され、その後にメタデータを編集しても、バージョンに変更はありませんでした。 このメタデータの更新については、画面右下の「Technical metadata」で確認できました。バージョン1が作成されたのは6/23ですが、6/24に更新されていることが確認できます。 エクスポート JSON-LD いくつかのフォーマットでエクスポートできますが、JSON-LDによる出力もサポートされていました。 { "@context": "http://schema.org", "@id": "https://doi.org/10.5281/zenodo.12508033", "@type": "https://schema.org/PresentationDigitalDocument", "identifier": "https://doi.org/10.5281/zenodo.12508033", "name": "AIPを作成・利用するツール紹介", "creator": [ { "name": "Nakamura, Satoru", "givenName": "Satoru", "familyName": "Nakamura", "affiliation": [ { "@type": "Organization", "name": "The University of Tokyo" } ], "@id": "https://orcid.org/0000-0001-8245-7925", "@type": "Person" } ], "author": [ { "name": "Nakamura, Satoru", "givenName": "Satoru", "familyName": "Nakamura", "affiliation": [ { "@type": "Organization", "name": "The University of Tokyo" } ], "@id": "https://orcid.org/0000-0001-8245-7925", "@type": "Person" } ], "publisher": { "@type": "Organization", "name": "Zenodo" }, "datePublished": "2024-06-23", "dateModified": "2024-06-24T01:00:09.177651+00:00", "temporal": [ "2024-06-21" ], "inLanguage": { "alternateName": "jpn", "@type": "Language", "name": "Japanese" }, "contentSize": "2.47 MB", "size": "2.47 MB", "license": "https://creativecommons.org/licenses/by/4.0/legalcode", "url": "https://zenodo.org/records/12508033" } これをEASY RDF ConverterでRDF/XMLに変換した結果は以下です。schema.orgを中心に使用されていることがわかります。 ...

2024年6月25日 · 4 分 · Nakamura

macOSでnbdev使用時のエラー対応

概要 macOSでnbdevを使用した際、以下のエラーが発生しました。 nbdev_prepare objc[48348]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. objc[48348]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug. Traceback (most recent call last): ... concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending. このエラーへの対応に関する備忘録です。 ...

2024年6月24日 · 1 分 · Nakamura