Carrierwave + carrierwave-vips 利用時、webp の変換に対応する

carrierwave-vips を利用し、画像を変換する場合、libvips が対応しているフォーマットであっても、

class ImageUploader < CarrierWave::Uploader::Base
    process convert: "webp"
end

例えばこのように、jpg, jpeg, png 以外の、webp を指定してしまうと、ArgumentError が固定で発生する。

現在 gem "carrierwave-vips" で install できるバージョンでは、フォーマットがハードコードされていて、回避する手段がない。
git の master にコミットされているものでは、これに対する設定項目が増えているため、まず git ブランチから gem をインストールする必要がある。
github.com

gem "carrierwave-vips", github: "eltiare/carrierwave-vips"

さらに設定ファイルを追加する。

config/initializers/carrierwave_vips.rb

CarrierWave::Vips.configure do |config|
  config.sharpen_mask = [ [ -1, -1, -1 ], [ -1, 24, -1 ], [ -1, -1, -1 ] ]
  config.sharpen_scale = 16
  config.allowed_formats = %(jpg jpeg png webp)
end

libvips で heic フォーマットの変換に対応する

apt-get install libvips

で install した libvips は、heic フォーマットに対応していない。

例えば ruby-vips で使うような場合は、以下のようにソースコードからコンパイルする必要があります。

FROM ruby:3.2.2-slim as base

# ==============================
# libvips
# ==============================
FROM base as libvips

RUN set -ex \
  && apt-get update \
  && apt-get install -y curl automake libtool cmake libglib2.0-dev meson \
  && apt-get install -y libspng-dev libopenjp2-7-dev libjxl-dev librsvg2-dev libwebp-dev libtiff-dev libexif-dev libimagequant-dev libffi-dev

WORKDIR /usr/local/src

RUN curl -sL https://github.com/strukturag/libde265/archive/refs/tags/v1.0.15.tar.gz | tar -xz && \
    cd libde265-1.0.15 && \
    ./autogen.sh && \
    ./configure && \
    make && \
    make install

RUN curl -sL https://github.com/videolan/x265/archive/refs/tags/3.4.tar.gz | tar -xz && \
    cd x265-3.4/build && \
    cmake ../source && \
    make && \
    make install

# 1.17 だと実行時エラーが出る
RUN curl -sL https://github.com/strukturag/libheif/archive/refs/tags/v1.16.2.tar.gz | tar -xz && \
    cd libheif-1.16.2 && \
    mkdir build && \
    cd build && \
    cmake --preset=release .. && \
    make && \
    make install

RUN curl -sL https://github.com/libvips/libvips/archive/refs/tags/v8.15.1.tar.gz | tar -xz && \
    cd libvips-8.15.1 && \
    meson setup ./build && \
    cd build && \
    meson compile && \
    meson install

vuetify v-tabs 利用時、アニメーションを変更、停止する方法

ドキュメントには書いてないので、どうやってv3で切り替えアニメーションをオフにするのか調べたが、

https://vuetifyjs.com/en/api/v-tabs/#props

`transition="none"` `reverse-transition="none" `の2つを指定する。
v2では、`transition="false"` だけでよかったが、2つになっていました。
そもそも`v-tab-item` が `v-window-item` になっていますが、それはドキュメントに書いてあります。

<template>
  <v-card>
    <v-tabs
      v-model="tab"
      bg-color="primary"
    >
      <v-tab value="one">Item One</v-tab>
      <v-tab value="two">Item Two</v-tab>
      <v-tab value="three">Item Three</v-tab>
    </v-tabs>

    <v-card-text>
      <v-window v-model="tab">
        <v-window-item transition="none" reverse-transition="none" value="one">
          One
        </v-window-item>

        <v-window-item transition="none" reverse-transition="none" value="two">
          Two
        </v-window-item>

        <v-window-item transition="none" reverse-transition="none" value="three">
          Three
        </v-window-item>
      </v-window>
    </v-card-text>
  </v-card>
</template>

AWS copilot のバージョンを上げた後デプロイエラーが発生する

install されている copilot を、既存のプロジェクトで途中からアップデートした場合、
copilot deploy の実行時エラーが発生することがある。

✘ execute svc deploy: upload deploy resources for service app: put addons artifact to bucket stackset-hogehoge-in-pipelinebuiltartifactbuc-39393939zoo: upload manual/addons/app/bc123423423423423423495c78234234234.yml to bucket stackset-hogehoge-in-pipelinebuiltartifactbuc-39393939zoo: AccessDenied: Access Denied
	status code: 403, request id: HOGEHOGEHOGE2, host id: gvEGNa6FXnAHogeHOGEHOgeA8+Gt+mfwHOGE1D6Jl01/OM313J0Q=
Error: Process completed with exit code 1.

これは、copilot を実行しているユーザーでは無く、管理用の *****EnvManagerRole というロールに権限が無いため発生しています。
こちらのRoleに自動で権限を付け直すコマンドは無いため、手動で修正が必要です。

どのような権限を設定するべきかは、別の env を作るなどして、再度デプロイ。その時作られたRoleを参考に、違う部分を修正する必要があります。

AWS Elemental MediaConvert で、hls を 生成時、iOS で再生されない

動画をStreaming再生させたい時、AWS Elemental MediaConvert で hls に変換を行った。

特徴 - AWS Elemental MediaConvert | AWS

変換後の動画情報や変換状態は、EventBridge から取得出来るが、COMPLETE event に含まれる、変換後のURLが2種類ある。

これのどちらを使えばいいのかわからなかった。

API 送信先 - Amazon EventBridge

この中の2つ、outputFilePaths playlistFilePaths

playlistFilePaths から手に入る URL であっても、Android のブラウザや PC の Safari、PC の VLCなどでは普通に再生出来る。
ただし、iOSsafari では 壊れたファイルのような表示になる。

outputFilePaths から手に入る URL では、問題なく再生された。

ちなみに、playlistFilePaths のファイルの中には、outputFilePaths のファイル名が書かれている。

React で Swiper を使うため、react-id-swiper を利用したが動かない

react-id-swiper@4.0.0 を利用したときに、不具合があったり、使いづらかったりした点がありました。

スタイルが反映されない

swiper@6.8.4 であれば以下のように書けば、スタイルが反映されますが、 swiper@7.0.6 では、

@import "swiper/swiper-bundle.css";

のような styleの読み込みがエラーになります。
そもそもバージョンにかかわらず、style は、グローバルに読み込むしか方法がなく、styled-components や、CSS modules を利用することができないのは不便です。

pagination、navigation などが機能しない

pagination、navigation を利用する場合は、option に指定するだけでは機能せず、以下のように設定しなければ動かない。

import { Pagination, Navigation, Swiper } from "swiper";
Swiper.use([ Pagination, Navigation ])

しばらく更新もないので、今後も修正されない可能性がありそうです。

Deep Link / App Links / Universal Link / Firebase Dynamic Links 使い分け

アプリを作るとき、URLをクリックしたときに、アプリがインストールされていれば、アプリを立ち上げたい。
このとき最も良い方法をまとめます。

Deep Link

用途

特定の技術を説明した言葉ではなく、アプリの特定のページを開くことが出来るリンクを表す。

実装方法

以下に説明する方法のいずれでも実現可能です。

App Links または Universal Link

用途

特定のURLを開くとき、アプリがあればアプリを起動、なければ通常通りWebブラウザで表示、という実装をしたい場合に利用します。
リンクを選択時、アプリ選択画面が表示されない点がポイントです。

実装時の注意点

iOSは、https://{domain}/ などですでにWebブラウザでページを見ているときに、https://{domain}/items/1 などのUniversal Link をクリックした場合、domain が同じであれば、アプリは反応しない
・アプリ内で https://{domain}/items/1 のような Universal Link を起動させた場合、Webブラウザが起動する

実装方法

Android: intent-filter と android:autoVerify="true" の設定、検証URL https://{domain}/.well-known/assetlinks.json
iOS: Associated Domains の applinks に、ドメインの設定、検証URLの作成 https://{domain}/.well-known/apple-app-site-association

https://developer.android.com/training/app-links/verify-site-associations
https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html

Firebase Dynamic Links

アプリを開く挙動の場合、技術的には、App Links または Universal Link が使われています。
Googleによって、特定のWebページをブラウザで開く / ストアを開く / アプリを開く、が自動でハンドリングされる機能です。

利用イメージとしては、短縮URLサービスのように、事前にWebページの登録をし、ユニークURLを発行します。リンク選択時に、いずれかにリダイレクトするような挙動です。

実装時の注意点

短縮URLと同じように、ユニークURL発行後に、パラメーターを追加することが出来ない
具体例では、https://sample.page.link/items のようなユニークURLを作成した場合、https://sample.page.link/items?id=1 にアクセスしアプリが起動しても、id=1 の部分がアプリから認識できません。

・ユニークURLは、そのページに直接アクセスすることは出来ない
必ず別URL、ストア、アプリのいずれかに遷移をします。
すでにWebサービスがあり、そのURLにアクセスした場合、アプリがインストールされていたらアプリで開く、としたい場合には利用できません。ユニークURL自体は、ページとして表示できないからです。

アプリやサーバー上で、動的にユニークURLの発行をすることが出来るので、idなどパラメーターの付加が必要であれば、idの数ぶん、動的であったり、事前にユニークURLを作成したりする必要があります。

ちなみに、ただの短縮URLのサービスとして使うことも出来ます。

実装方法

DeepLinkの設定と、Firebase上などでユニークURLの発行が必要です。
https://firebase.google.com/docs/dynamic-links?hl=ja

URLスキーム

用途

昔から存在する、リンクでアプリを起動する方法で、
メーラーやMap のような、ツールのアプリを作る場合に有用です。

map:// のように定義し、機能が同じであれば、別アプリであっても 同じ URL scheme をつかうのがよく、例えば Mapアプリであれば、どのアプリでも map:// に対応していれば、使う側は好きなアプリを選んでインストールできるため便利です。
つまり重複を前提に使います。

特定のURLスキームに対応するアプリが複数あった場合は、起動時に選択画面がでるため、ユーザーは一手間かかります。1つだけの場合にはアプリ選択は表示されません。

実装方法

iOS: URL Scheme に、独自の scheme を記載する。
Android: intent-filter に、httpsではなく、独自の sheme を記載する。


結果として、 Firebase Dynamic Links、Universal Link or App Links 両方の実装をすることになると思います。