Scratch-guiのデフォルトプロジェクトのアセット置き場を変える方法


※ 当ページには【広告/PR】を含む場合があります。
2020/11/01

以前、
独自のScratchアプリをAWS S3から公開するための方法を解説しました。

実際にはまだ画像ファイルなどのアセットファイルの置き場所に少し課題がありました。

今回はさらに突っ込んで、このアセットファイルの置き場所を変更するための手順を深堀してみようと思います。


合同会社タコスキングダム|タコキンのPスクール【Pschool厳選】Scratchを学べるオンライン・駅前プログラミングスクール5選

はじめに

以前、Scratch3.0の開発者向けのソースコードプロジェクトscratch-guiを利用して、Scratchアプリそのものを公開するためのデフォルトプロジェクトを置き換える方法を解説しました。

課題としてデフォルトプロジェクトを置き換えただけでは、画像データや音源はscratchの共有アセット置き場(
https://assets.scratch.mit.edu/internalapi/asset)に置かれてしまうようです。

合同会社タコスキングダム|タコキンのPスクール

これはscratch3では原則として
scratch.mit.edu(クラウド側)への保存しなければならない仕様のためです。

簡単に言ってしまうと、Scratchの公式サイトにアップロードされたファイルは全て問答無用でみんなの財産として扱われます。

この辺がScratchアプリ開発の悩ましい問題で、最近の更新された
ぴぽや倉庫さんの利用規約のScratchの項目が分かりやすいと思います。

ライセンス付きの有料の画材を購入した人がそれを使ってScratch3のアプリを公式サイトから公開してしまった場合、
画材の購入元の利用規約によっては規約違反になってしまいます。

大抵の場合には、購入した画材の利用規約に従えばよいのですが、中にはクリエイティブ・コモンズなどの面倒なライセンスが付いているものもあります。

Scratch3は三条項BSDライセンス(BSD-3-clause)に基づいているため、開発中のプロジェクト内に色々なライセンスのファイルが存在してくると、そのライセンス同士の衝突する・しないなどアプリ開発とは関係の薄いところに気を配っていかなくてはなりません。

せめて画像置き場は自分専用のストレージにおけると、ライセンスの無用な衝突の問題を分けて考えることができるので、少し気が楽になりそうです。

そんなニーズに応えるためなのか分かりません。

scratch-guiには救済措置としてデフォルトのアセット置き場のURLを変更はできるようになっています。

今回はプライベートのAWS S3のバケット内にプロジェクトのアセットを置いて、そこからScratch3アプリが正常に起動することを検証します。


合同会社タコスキングダム|タコキンのPスクール【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ

AWS S3でアセット用のバケットを作成

※この記事ではAWSでのクラウドストレージを利用した方法を紹介します。

他のクラウドストレージやCDNからでも
https://...からアクセスできるエンドポイントがあれば同じように設定できると思います。

AWSを利用するのでなければこの節はスキップして、次に節からお読みください。

まずはAWS S3のコンソールから空のバケットを作成します。

このバケットにとりあえず
projectという空のフォルダを追加しておきます。

プロジェクトのファイル(
.sb3)を解凍して、中身のアセット(png/svg/wavなど)をこのprojectフォルダにアップロードしておきます。

合同会社タコスキングダム|タコキンのPスクール

外部からアクセスできるようにするためバケットポリシーの追加とCORS設定を行います。

合同会社タコスキングダム|タコキンのPスクール

バケットから
[アクセス許可]タブの[バケットポリシー]および[Cross-Origin Resource Sharing(CORS)]を設定します。

今回は特定のサイトからのみアクセスはせずに、どこのオリジンからでもGETのみ許可するようにしております。

GETのみを許可する時点でこのプロジェクトは
読み込み専用になります。

アプリの開発も自分専用のクラウドストレージ無いで行いたいときにはここから更に
POSTなどのメソッドを許可する必要があります。

細かくアクセスコントロールしたい場合には各自の用途に応じた設定に修正してください。

バケットポリシー:

            
            {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Accsess Policy 1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}
        
CROS設定:

            
            [
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
        
特にここでは設定していませんが、AllowedOriginsに特定のサイトを指定することで、他からのダウンロードは制限することも可能です。

さて、この時点でこのバケットからアクセスが可能かcurlで適当なファイルを取得して試してみます。

            
            $ curl https://s3-ap-northeast-1.amazonaws.com/バケット名/project/8c84d0a54dc6d808c08b06f4f3880e62.svg
<svg version="1.1" width="7.579999923706055" height="11.640000343322754" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="3.4549999237060547 1.0399999618530273 7.579999923706055 11.640000343322754">
#...中略
  </g>
</svg>
        
レスポンスが返ってきているようなので、AWS S3からファイルが供給できている状態になりました。


scratch-guiの修正

デフォルトではプロジェクトのプロジェクトファイル・アセットファイルが以下のように配置されている仕様です。

            
            project.json:
    https://projects.scratch.mit.edu/[project_id値]
assets:
    https://assets.scratch.mit.edu/internalapi/asset/[resource_id.(png|svg|wav)]/get/
        
これを先程の設定したような任意のクラウドストレージを参照するようにしていきます。

project-fetcher-hoc.jsx

まずはリソースファイルのホスト先の情報が格納されている
project-fetcher-hoc.jsxを覗いてみます。このファイルはscratch-gui/src/lib/project-fetcher-hoc.jsxにあります。

このコードの中身に以下の部分を探します。

            
            //...中略
ProjectFetcherComponent.defaultProps = {
    assetHost: 'https://assets.scratch.mit.edu',
    projectHost: 'https://projects.scratch.mit.edu'
};
//...以下略
        
この設定がデフォルトのアセット置き場のURLの設定になります。

先程のAWS S3バケットに仕込みなおすと、

            
            //...中略
ProjectFetcherComponent.defaultProps = {
    // assetHost: 'https://assets.scratch.mit.edu',
    // projectHost: 'https://projects.scratch.mit.edu'
    assetHost: 'https://s3-ap-northeast-1.amazonaws.com/<バケットの名前>/project',
    projectHost: 'https://s3-ap-northeast-1.amazonaws.com/<バケットの名前>/project'
};
//...以下略
        
でデフォルトのリソースファイル置き場が変更できました。

storage.js

もう一つ修正すべきなのが、
storage.jsという保存先のアクセス方法を実装しているファイルです。場所はscratch-gui/src/lib/storage.jsにあります。

デフォルトでは、

            
            //...中略
setProjectHost (projectHost) {
    this.projectHost = projectHost;
}
getProjectGetConfig (projectAsset) {
    return `${this.projectHost}/${projectAsset.assetId}`;
}
getProjectCreateConfig () {
    return {
        url: `${this.projectHost}/`,
        withCredentials: true
    };
}
getProjectUpdateConfig (projectAsset) {
    return {
        url: `${this.projectHost}/${projectAsset.assetId}`,
        withCredentials: true
    };
}
setAssetHost (assetHost) {
    this.assetHost = assetHost;
}
getAssetGetConfig (asset) {
    return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
}
getAssetCreateConfig (asset) {
    return {
        // There is no such thing as updating assets, but storage assumes it
        // should update if there is an assetId, and the asset store uses the
        // assetId as part of the create URI. So, force the method to POST.
        // Then when storage finds this config to use for the "update", still POSTs
        method: 'post',
        url: `${this.assetHost}/${asset.assetId}.${asset.dataFormat}`,
        withCredentials: true
    };
}
//...以下略
        
という部分が、そのままではgetAssetGetConfigメソッド返すURLが専用のWeb Api形式になっています。

そこで
AWS S3に合わせるように書き換えます。

            
            //...中略
getAssetGetConfig (asset) {
    // return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
    return `${this.assetHost}/${asset.assetId}.${asset.dataFormat}`;
}
//...以下略
        
ここらへんはアセット置き場として利用したいクラウドストレージのアクセス方法によって異なるエンドポイントになるかも知れません。

その際は
storage.jsを多少変更することになると思います。

これでScratch-guiをビルドして、デフォルトのプロジェクトを読み込んだ際に、指定したクラウドストレージからリソースが読み込まれていたら設定完了です。

合同会社タコスキングダム|タコキンのPスクール


合同会社タコスキングダム|タコキンのPスクール【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ

まとめ

今回はスクラッチプロジェクトのアセットファイルの置き場所をカスタマイズする方法を解説しました。

特に今回のテクニックでは、スクラッチアプリは公開したいけれど、そこで利用している一部のライセンス付きの画像のアクセスは制限したい場合に役立つと思います。