# Hisui Cloud

この機能は現時点でアルファ版のため、正式リリース時には仕様が異なる場合があります。

## 概要

**Hisui バージョン**: 2025.3.2

Hisui Cloud は時雨堂がオープンソースで公開している録画合成ツール Hisui のクラウド版です。
Sora Cloud の機能の一つとして提供しています。Sora Cloud で録画したファイルを合成することができます。

## 注意

### 分割録画ファイルには非対応

Hisui Cloud では分割録画ファイルには非対応です。

> **注釈**
>
> 将来的には分割録画ファイルに対応する予定です。

### MP4 形式の録画ファイルには非対応

Hisui Cloud では Sora 2024.2.0 から利用可能な MP4 形式の録画ファイルには非対応です。

> **注釈**
>
> 将来的には MP4 形式の録画ファイルに対応する予定です。

### オブジェクトストレージのエグレス料金

Hisui Cloud ではオブジェクトストレージにアップロードした録画ファイルを再度ダウンロードします。
そのため、利用しているオブジェクトストレージのエグレス料金がかかる場合があります。

> **注釈**
>
> 将来的には Sora Cloud にて録画ストレージを提供することでエグレス料金がかからない仕組みを提供する予定です。

### 録画ファイル取得先のオブジェクトストレージ設定

オブジェクトストレージの設定はプロジェクトの設定で行い、録画機能と同じオブジェクトストレージ設定を使用します。
Hisui Cloud を使用する場合はオブジェクトストレージ設定に設定したアクセスキーに対してファイルの取得権限も必要です。

## 合成機能

録画したファイルを合成します。アルファ版の段階ではレイアウトは指定できず出力されるファイルは固定となります。
ベータ版にてレイアウトを指定可能にする予定です。正式リリース時にはレイアウトエディターを提供予定です。

### アルファ版で提供する機能

**プロファイルは正式リリース時には変更予定です**

- 一括合成ファイルのみ
- 出力されるファイルのプロファイルを選択可能- デフォルトは 0 です
  - profile_id: 0- 映像は VP9
    - 音声は Opus
    - コンテナは MP4
    - 解像度は 720p (1280x720)
    - ビットレートは 1000 Kbps
  - profile_id: 1- 映像は VP9
    - 音声は Opus
    - コンテナは MP4
    - 解像度は 1080p (1920x1080)
    - ビットレートは 1500 Kbps
  - profile_id: 2- 映像は AV1
    - 音声は Opus
    - コンテナは MP4
    - 解像度は 1080p (1920x1080)
    - ビットレートは 1000 Kbps

## 料金

Hisui Cloud を利用するのに追加料金は不要です。

> **注釈**
>
> 将来的に、合成ジョブを優先的に処理するための有料プランを用意する予定です。

## 管理コンソール

### Hisui Cloud の録画合成を開始する

管理コンソールの `Past recordings` から合成したい録画 ID をクリックします。
`Recording details` で 右上の `Go to Hisui Cloud Jobs` をクリックしてください。

![image](https://i.gyazo.com/c37e2e92c316bf05b78edf4cdf6dd001.png)

`Hisui Cloud Jobs` で `Create job` をクリックします。

![image](https://i.gyazo.com/7fab2da0a32c6ce46a68ea7cf6e2dea9.png)

ポップアップが表示されるのでプロファイルを選択し `Create Job` をクリックします。

![image](https://i.gyazo.com/efc9c1ee7d08c330eabdbaf3552d46f7.png)

これで Hisui Cloud の録画合成が開始されます。

## API

[プロジェクト Hisui Cloud API](project_api_hisui_cloud.html) をご確認ください。


## ウェブフック


### Sora Cloud ウェブフック hisui-job.started

録画合成開始時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "type": "hisui-job.started",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "status": "started",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```

### Sora Cloud ウェブフック hisui-job.composited

録画合成成功時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "type": "hisui-job.composited",
  "status": "composited",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "composited_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```

### Sora Cloud ウェブフック hisui-job.uploaded

録画合成ファイルのアップロード成功時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "type": "hisui-job.uploaded",
  "status": "uploaded",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "composited_timestamp": "<RFC3339>",
  "uploaded_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "s3_uri": "s3://<Bucket-Name>/<File-Path>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```

### Sora Cloud ウェブフック hisui-job.completed

録画合成処理の完了時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "type": "hisui-job.completed",
  "status": "completed",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "composited_timestamp": "<RFC3339>",
  "uploaded_timestamp": "<RFC3339>",
  "completed_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "s3_uri": "s3://<Bucket-Name>/<File-Path>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```

### Sora Cloud ウェブフック hisui-job.canceled

処理キャンセル時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "type": "hisui-job.canceled",
  "status": "canceled",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "canceled_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```


### Sora Cloud ウェブフック hisui-job.failed

処理失敗時に通知されます。

```json
{
  "id": "<Base32-UUIDv4>",
  "hisui_job_id": "<Base32-UUIDv4>",
  "timestamp": "<RFC3339>",
  "type": "hisui-job.failed",
  "status": "failed",
  "error_code": "<String>",
  "project_id": "<String>",
  "org_id": "<UUID>",
  "recording_id": "<Base32-UUIDv4>",
  "channel_id": "<String>",
  "queued_timestamp": "<RFC3339>",
  "started_timestamp": "<RFC3339>",
  "failed_timestamp": "<RFC3339>",
  "output_audio_codec_type": "<String>",
  "output_audio_bit_rate": "<Integer>",
  "output_video_codec_type": "<String>",
  "output_video_bit_rate": "<Integer>",
  "output_container_type": "<String>",
  "output_resolution": "<String>",
  "recording_duration_s": "<Integer>",
  "output_duration_s": "<Integer>"
}
```
