2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SORACOMAdvent Calendar 2023

Day 6

Azure App Serviceでソラカメのストリーミング再生を行う

Last updated at Posted at 2023-12-25

概要

当社でMicrosoft Azureを使ったSaaSを提供していて、
そこでソラカメを活用した見守りサービスの開発を行っています。
AWSを使ったソラカメのストリーミングの事例を参考に、
Azureを使ってストリーミング再生を行う例を書きたいと思います。

環境など

開発環境
・Visual Studio 2022

実行環境
・Azure App Service
・Logic App

使用するフレームワーク、ライブラリ等
・ASP .NET Core(.NET 7)
・dash.js(ストリーミング用)

システム構成

検証用に構築したシステム構成はこんな感じ。

画像1.png

手順

ソラカメを既に運用している前提です。

SORACOM プラットフォーム側の準備

①SAM ユーザー用ロール作成
ソラコムのコンソールで、APIアクセス用のロールを作成しておきます。
ここでは、SoracamWatcherRoleという名前のロールを作成しました。
ロールに設定する権限は以下のような感じ。

{
  "statements": [
    {
      "effect": "allow",
      "api": [
        "SoraCam:*Device*",
        "OAuth2:authorize",
        "Auth:*"
      ]
    }
  ]
}

②SAM ユーザー作成
APIアクセス用のSAMユーザーを作成し、先ほど作成したロールを割り当てます。
image.png

③ SAMユーザーの認証キー生成
SAMユーザーの認証設定で、認証キーを生成します。
生成時に表示される認証キーIDと認証キーシークレットをAPI呼び出し時に使用するので
忘れずコピーしておいてください。

image.png

Azure Logic Apps

ソラコムのAPIを呼び出すための処理を、ここではLogic Apps上で実装しました。
⇒今後使いまわしするかはさておき・・・。

Logic Appsは三つにわけて作成しています。
一旦ソラカメAPIのラッパーの位置づけで作成しています。

・soracam_auth SAMユーザーのAPIキーとトークン発行用
※本文のauthKeyとauthKeyIdには、先に生成した認証キーIDと認証キーシークレットを入れて下さい。
image.png

・soracam_devices ソラカメのデバイスリスト(カメラリスト)取得用
※上記のLogic Appsで取得したAPIキーとトークンを引数で受け取ります。
image.png

・soracam_streaming 対象ソラカメのストリーミングURL取得用
※上記のLogic Appsで取得したAPIキーとトークン、対象カメラのデバイスIDを引数で受け取ります。
image.png

Azure App Service

App ServiceはASP .NET Coreを使用したWebアプリをホストさせます。

Webアプリは、ページにデバイス(=カメラ)のリストを表示させ、
選択されたカメラのストリーミング用URLを取得を行って
動画の表示を行います。

といっても、動画の再生はライブラリのdash.jsにお任せで、
実質はLogic Appsを呼び出すのみとなります。
※さらに言うと、今回の実装のみで言えば、Static Web Appsで充分ですが・・・

①まず、Logic Appを呼び出すために、HttpClientサービスを追加

program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// この行を追加
builder.Services.AddHttpClient();

var app = builder.Build();

//・・・

②とりあえずIndexページにストリーム再生する処理を実装(ControllerはHome)。
変数名もエラー処理も適当すぎるのでご注意ください(汗)。

HomeController.cs
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IHttpClientFactory _httpClientFactory;

        public HomeController(ILogger<HomeController> logger,
            IHttpClientFactory httpClientFactory)
        {
            _logger = logger;
            _httpClientFactory = httpClientFactory;
        }

        public async Task<IActionResult> Index()
        {
            var httpClient = _httpClientFactory.CreateClient();

            // 認証
            var request = new HttpRequestMessage(
                        HttpMethod.Get,
                        "Logic Appsに作ったsoracam_authのURL");

            var response = await httpClient.SendAsync(request);
            if (!response.IsSuccessStatusCode)
            {
                // エラー処理
            }

            // コンテンツデータからトークンなどを取得
            using var contentStream = await response.Content.ReadAsStreamAsync();
            var authData = await JsonSerializer.DeserializeAsync<AuthData>(contentStream);

            // デバイスリスト取得
            var authParam = new DeviceListParam()
            {
                apiKey = authData.apiKey,
                token = authData.token,
            };

            var authDataJson = new StringContent(
                JsonSerializer.Serialize(authParam),
                Encoding.UTF8,
                Application.Json);

            var request2 = new HttpRequestMessage(
                        HttpMethod.Post,
                        "Logic Appsに作ったsoracam_devicesのURL")
            {
                Content = authDataJson
            };
           
            var response2 = await httpClient.SendAsync(request2);
            if (!response2.IsSuccessStatusCode)
            {
                // エラー処理
            }

            // コンテンツデータからデバイスリストを取得
            using var contentStream2 = await response2.Content.ReadAsStreamAsync();
            var devicesData = await JsonSerializer.DeserializeAsync<IEnumerable<DevicesData>>(contentStream2);

            ViewBag.DeviceList = new SelectList(devicesData, "deviceId", "name");

            return View();
        }


        [HttpPost]
        public async Task<IActionResult> GetStreamUrl(string deviceId)
        {
            var httpClient = _httpClientFactory.CreateClient();

            // 認証
            var request = new HttpRequestMessage(
                        HttpMethod.Get,
                        "Logic Appsに作ったsoracam_authのURL");

            var response = await httpClient.SendAsync(request);
            if (!response.IsSuccessStatusCode)
            {
                // エラー処理
            }

            // コンテンツデータからトークンなどを取得
            using var contentStream = await response.Content.ReadAsStreamAsync();
            var authData = await JsonSerializer.DeserializeAsync<AuthData>(contentStream);

            if (authData == null)
            {
                // エラー処理
            }

            // ストリーミングURL取得
            var authParam = new StreamURLParam()
            {
                apiKey = authData.apiKey,
                token = authData.token,
                deviceId = deviceId,
            };

            var authDataJson = new StringContent(
                JsonSerializer.Serialize(authParam),
                Encoding.UTF8,
                Application.Json);

            var request2 = new HttpRequestMessage(
                        HttpMethod.Post,
                        "Logic Appsに作ったsoracam_streamingのURL")
            {
                Content = authDataJson
            };

            var response2 = await httpClient.SendAsync(request2);
            if (!response2.IsSuccessStatusCode)
            {
                // エラー処理
            }

            using var contentStream2 = await response2.Content.ReadAsStreamAsync();
            var streamURLData = await JsonSerializer.DeserializeAsync<StreamURLData>(contentStream2);

            return Ok(streamURLData.playList[0].url);
        }

    }

実行画面

当社運営のレンタルスペース「BABY ROOM」の防犯用カメラを
ストリーミングしてみました。

image.png

余談

この記事は12/6に書く予定でしたが、
書き終えたのは結局アドベントカレンダー最終日(汗)。
その間に、SORACOMさんがストリーミング再生し放題の機能を提供開始したと
プレスリリースがありました。

ソラカメ、カメラのライブ映像を無制限で視聴・ダウンロードできる「ライブ視聴見放題」を提供開始

ソラカメの活用がますますしやすくなりそうです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?