※当サイトの記事には、広告・プロモーションが含まれます。

Azure Media ServicesのAssetの仕様が微妙な件

nazology.net

gigazine.net

強化学習の行き着く果てに突然変異が起こり得ることは無きにしも非ずな気はするので、何とも言えませんが、人の手による制御ができなくなるかもしれない脅威さえ防げるのであれば、何を信じても良い気はしますが。

が、どちらの主張も科学的に説明のしようがないところが哀しいかな...

ニューラルネットワークについて、ブラックボックス過ぎるというね...

円周率がいつまで経っても導き出せなかったり、新しい素数がどれだけあるのか分からなかったりする状況に似てる気がする、結局答えが分かってないから、何を言ったとしても検証する術が無いというね。

科学者だからと言って、常に科学的に根拠のある説明ができるわけではないってことですかね...。

Azure Media ServicesのAssetの仕様が微妙な件

公式のドキュメントによりますと、

docs.microsoft.com

⇧ Azure Media Servicesを利用して、動画ファイルを元に動画のストリーミングを実現するために必要な基本的な構成のイメージ図があり、『Asset(資産)』ありきで、『Asset(資産)』についてはAzure Blob Storageで管理されるってことだと思うのですが、『Asset(資産)』についてちゃんと説明して欲しい...

Azure Media ServicesとAzure Blob Storageの関係がふわっとしちゃってるのね...

何と言うか、

stackoverflow.com

docs.microsoft.com

⇧ 海外でも話題に上がってはいますと。

分からんけど、普通に考えて、Azure Blob StorageのBLOBが階層構造を持てるようになってるんだから、

⇧ 上図みたいな構成で管理みたいなことを期待するし、1つのBLOBコンテナー使う理由はこういうことを実現したいに尽きると思うんだけど...

そもそも、

⇧ 上図みたいに、AssetとBLOBコンテナーが1対1になってないといけないとしたら、もう仕様がいけてないとしか思えないんだが...
まさか、天下のMicrosoftさんがそんな吐き気を催す邪悪な仕様に甘んじてるはずがないと思うんだが、どうもネットの情報を見る限り、上図のような認識がメジャーな気がして恐ろしい...

公式のドキュメントによりますと、

docs.microsoft.com

アセットは Azure Storage アカウント内の BLOB コンテナーにマップされ、アセット内のファイルはブロック BLOB としてそのコンテナーに格納されます。

https://docs.microsoft.com/ja-jp/azure/media-services/latest/assets-concept

アセット名は一意である必要があります。 Media Services v3 のリソース名 (アセット、ジョブ、変換など) には、Azure Resource Manager の名前付け規則が適用されます。 詳細については、「名前付け規則」を参照してください。

https://docs.microsoft.com/ja-jp/azure/media-services/latest/assets-concept

⇧ 説明が微妙過ぎる...

確認したいのは、AssetとBLOBコンテナーが、1:1なのか、多:1でもいけるのかどうかってとこだと思うんよね...

「名前付け規則」を確認すると、

Naming conventions

Azure Media Services v3 resource names (for example, Assets, Jobs, Transforms) are subject to Azure Resource Manager naming constraints. In accordance with Azure Resource Manager, the resource names are always unique. Thus, you can use any unique identifier strings (for example, GUIDs) for your resource names.

https://docs.microsoft.com/ja-jp/azure/media-services/latest/media-services-apis-overview#naming-conventions

Media Services resource names can't include: '<', '>', '%', '&', ':', '\', '?', '/', '*', '+', '.', the single quote character, or any control characters. All other characters are allowed. The max length of a resource name is 260 characters.

https://docs.microsoft.com/ja-jp/azure/media-services/latest/media-services-apis-overview#naming-conventions

⇧ 最大で260文字だそうな。

そして、「/」が使えないところを見ると、Azure Media Servicesのリソースは階層構造を持てないことになりそう...

残すは、Azure Blob Storage側で、Azure Media Servicesのリソースを1つのフォルダーで管理できるのかってことになってきますかね。

で、話は「名前付け規則」に戻り、Azure Blob Storageの説明を見ると、

docs.microsoft.com

  • コンテナー名の長さは、3 ~ 63 文字にする必要があります。

https://docs.microsoft.com/ja-JP/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata

⇧ う~ん、AssetとBLOBコンテナーはマップされるとあるのに、Asset名とBLOBコンテナー名の文字数が一致しないんだが...

この時点で嫌な予感しかしない...

もうMicrosoft さんのドキュメント、カオス過ぎて辛い...

  • Blob 名は、Azure Storage の blob について、少なくとも1文字で、長さが1024文字以下でなければなりません。

https://docs.microsoft.com/ja-JP/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata

⇧ BLOB名は1024文字、サブフォルダーとかネストさせたら、すぐに1024文字なんか超えそうな気がするけど...

公式のAzure Media Services v3 APIJavaのサンプルで、Assetを作成してる部分を確認したところ、azure-resourcemanager-mediaservicesという依存関係で追加されるjarの中のクラスで、

■C:\Users\Toshinobu\.m2\repository\com\azure\resourcemanager\azure-resourcemanager-mediaservices\1.1.0-beta.2\azure-resourcemanager-mediaservices-1.1.0-beta.2.jar - com.azure.resourcemanager.mediaservices.implementation.AssetsClientImpl.class

    /**
     * Creates or updates an Asset in the Media Services account.
     *
     * @param resourceGroupName The name of the resource group within the Azure subscription.
     * @param accountName The Media Services account name.
     * @param assetName The Asset name.
     * @param parameters The request parameters.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws ManagementException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return an Asset.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    private Mono<Response<AssetInner>> createOrUpdateWithResponseAsync(
        String resourceGroupName, String accountName, String assetName, AssetInner parameters, Context context) {
        if (this.client.getEndpoint() == null) {
            return Mono
                .error(
                    new IllegalArgumentException(
                        "Parameter this.client.getEndpoint() is required and cannot be null."));
        }
        if (this.client.getSubscriptionId() == null) {
            return Mono
                .error(
                    new IllegalArgumentException(
                        "Parameter this.client.getSubscriptionId() is required and cannot be null."));
        }
        if (resourceGroupName == null) {
            return Mono
                .error(new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null."));
        }
        if (accountName == null) {
            return Mono.error(new IllegalArgumentException("Parameter accountName is required and cannot be null."));
        }
        if (assetName == null) {
            return Mono.error(new IllegalArgumentException("Parameter assetName is required and cannot be null."));
        }
        if (parameters == null) {
            return Mono.error(new IllegalArgumentException("Parameter parameters is required and cannot be null."));
        } else {
            parameters.validate();
        }
        final String accept = "application/json";
        context = this.client.mergeContext(context);
        return service
            .createOrUpdate(
                this.client.getEndpoint(),
                this.client.getSubscriptionId(),
                resourceGroupName,
                accountName,
                assetName,
                this.client.getApiVersion(),
                parameters,
                accept,
                context);
    }    

⇧ 上記のメソッドがInterfaceで定義されてたのだけど、

■com.azure.resourcemanager.mediaservices.implementation.AssetsClientImpl.AssetsService

        @Headers({"Content-Type: application/json"})
        @Put(
            "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Media/mediaServices"
                + "/{accountName}/assets/{assetName}")
        @ExpectedResponses({200, 201})
        @UnexpectedResponseExceptionType(ManagementException.class)
        Mono<Response<AssetInner>> createOrUpdate(
            @HostParam("$host") String endpoint,
            @PathParam("subscriptionId") String subscriptionId,
            @PathParam("resourceGroupName") String resourceGroupName,
            @PathParam("accountName") String accountName,
            @PathParam("assetName") String assetName,
            @QueryParam("api-version") String apiVersion,
            @BodyParam("application/json") AssetInner parameters,
            @HeaderParam("Accept") String accept,
            Context context);

⇧ 結局、リクエスト先で何してるか分からんやん...

だからこそドキュメントをしっかり書いて欲しいのよ...

一番知りたいのは、Assetが作成される時にマップされるBLOBコンテナー名がどうなるかってとこなんですけど...

実際に、Javaのプログラムで実行した結果は、

■Asset名

output-2cbf63df-4810-4b30-85c8-496aecf35106    

■BLOBコンテナー名

asset-cb68987d-736d-4490-936e-ef10d76a9b6b 

⇧ 何と言うことでしょう...

Asset名を指定して作成したところで、BLOBコンテナー名は適当に命名されて作成されてしまってるという...

絶望しかないんだが...

結局、Azure Media Services v3 APIJavaを使って、Azure Blob Storageで階層構造のBLOBとして、Azure Media Services のAssetを管理できるかどうかが分からんではないか...

ちなみに、Azure Media Servicesのサンプルについてissue上げてるんだけど、

github.com

⇧ 何の反応も無いというね...

まぁ、

qiita.com

これはAzureのサポートに問い合わせて要望は出しましたが、結局のところ実装の改善は行われませんでした。

AMS v3でCMAFが突然追加されて困った話 - Qiita

⇧ Azureのサポート経由でも、残念仕様が改善されないようなので、致し方ないのかな...

ただ、issueに上げたのはバグだと思うんで、回答が欲しいところではありますが...

Microsoftさん、もうちょっと頑張って欲しい...

まぁ、世界的な大企業にとってみたら、小さな島国の1ユーザーの意見なんて何の価値もないのかもしらんけどもね...

毎度モヤモヤ感が半端ない...

今回はこのへんで。