動画生成AIサービス「Dream Machine」をWeb APIで呼び出してみた

[Supership](https://supership.jp/)の名畑です。[らんま1/2のOP](https://www.youtube.com/watch?v=RFYP-tY6xOg)が本編に先駆けて公開され、[じゃじゃ馬にさせないで](https://ja.wikipedia.org/wiki/%E3%81%98%E3%82%83%E3%81%98%E3%82%83%E9%A6%AC%E3%81%AB%E3%81%95%E3%81%9B%E3%81%AA%E3%81%84%E3%81%A7)の思い出が全力で甦ってくる。

## はじめに

6月に「[話題の動画生成AIサービス「Dream Machine」を使って女性の画像を動かしてみたら自然すぎて恐くなりもした](https://qiita.com/nabata/items/b956febcf4fddf8344fc)という記事を書きました。

アメリカの**Luma Labs**による[Dream Machine](https://lumalabs.ai/dream-machine)の素晴らしさを紹介した記事でした。

当時はブラウザ上での動画生成だったのですが、先日Web APIが公開されました。
ということで呼び出してみましたというのが今回の記事です。

## ログインからクレジット購入まで

![dmapi_img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/fa452267-b5ee-9f60-ec46-58fdbac9b21b.png)

Googleアカウントでログインします。

![dmapi_img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/fc5c4bf3-48e8-a065-d1dd-428bb4de7518.png)

**Billing & Credits**のページの**Add More Credits**からクレジットを購入可能です。$5〜$500の間で金額を指定できます。金額について詳しくは「[Dream Machine API Pricing](https://lumalabs.ai/dream-machine/api/pricing)」のページをご覧ください。

## API Key作成

![dmapi_img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/f38b49e8-0d9d-efd1-e8eb-4e1972a413cc.png)

API Keyを作成しておきましょう。
以下の説明の通り、API Keyは後からは確認ができませんので、生成時に必ず保持するようにしてください。

> It is your responsibility to record the key below as you will not be able to view it again.


## 環境設定

私の端末のOSは[macOS 14 Sonoma](https://www.apple.com/jp/macos/sonoma/)です。

Pythonのバージョンは以下です。

```shell-session
$ python --version
Python 3.12.2
```

[Python SDK](https://docs.lumalabs.ai/docs/python)を入れておきます。

```shell-session
$ pip install lumaai
```

サンプルコードの実行に用いるため、[requests](https://pypi.org/project/requests/)も入れておきます。

```shell-session
$ pip install requests
```

バージョンを確認しておきました。

```shell-session
$ pip list | grep -e lumaai -e requests 
lumaai             1.0.2
requests           2.31.0
```

ハードコーディングを避けるため、先ほどのAPI Keyは**LUMAAI\_API\_KEY**という環境変数名で保存しておきました。

```shell-session
export LUMAAI_API_KEY=ここに取得したAPI Keyを書く
```

## テキストからの動画生成

[Python SDKのGuideのText to Videoの項](https://docs.lumalabs.ai/docs/python#text-to-video)を参考にして、まずはテキストからの動画生成をしてみます。より詳しくは[API Reference](https://docs.lumalabs.ai/reference/ping-1)などをご覧ください。

```python
import os
from lumaai import LumaAI
import requests

client = LumaAI(
    auth_token=os.environ.get("LUMAAI_API_KEY")  # API Keyの取得
)

generation = client.generations.create(
    prompt="A teddy bear in sunglasses playing electric guitar and dancing",
    aspect_ratio="16:9",
    loop=True # Trueだとループ対応
)

# stateはqueued, dreaming, completed, failedのいずれかの値を取る
while generation.state != "failed":
    generation = client.generations.get(generation.id)  # 再取得
    if generation.state == "completed":
        response = requests.get(generation.assets.video)
        with open(generation.id + ".mp4", "wb") as file:
            file.write(response.content)
        break
        
# これまでのリクエスト一覧は以下で取得可能
# print(client.generations.list())
```

プロンプトは「**A teddy bear in sunglasses playing electric guitar and dancing**」です。「**エレキギターを弾きながら踊っているサングラスをかけたテディベア**」ですね。

アスペクト比は16:9を指定しました。
また、ループしても不自然のない動画となるように、**loop**にTrueを指定しました。最初のフレームと最後のフレームが一致するということのようです。

実際に生成された動画は以下です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/T8jdaAy1FvY?si=8vqoB762rbXELW7h" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

プロンプト通りの動画が作成されています。
素晴らしいです。

## 画像からの動画生成

同じく[Python SDKのGuideのImage to Videoの項](https://docs.lumalabs.ai/docs/python#image-to-video)を参考にして、画像からの動画生成も行ってみます。

> You should upload and use your own cdn image urls, currently this is the only way to pass an image

とのことなので、現在においては、どこかurlが発行されるサーバ上に画像をアップしておく必要があります。

今回は以下の画像をサーバ上におきました。

![dmapi_original.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/3d9832c8-64d2-9d63-fee2-7fc7e0801e27.png)

最初のフレームと最後のフレームの両方に別画像を生成できますが、今回は最初のフレームのみとします。

コードは以下です。プロンプトは「**Japanese woman smiling**」つまり「**笑っている日本人女性**」としました。今回はループ指定をはずしてみました。

```python
import os
from lumaai import LumaAI
import requests

client = LumaAI(
    auth_token=os.environ.get("LUMAAI_API_KEY")  # API Keyの取得
)

generation = client.generations.create(
    prompt="Japanese woman smiling",
    keyframes={
        "frame0": {
            "type": "image",
            "url": "ここに画像urlを指定する"
        }
    }
)

# stateはqueued, dreaming, completed, failedのいずれかの値を取る
while generation.state != "failed":
    generation = client.generations.get(generation.id)  # 再取得
    if generation.state == "completed":
        response = requests.get(generation.assets.video)
        with open(generation.id + ".mp4", "wb") as file:
            file.write(response.content)
        break
```

生成した動画は以下です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Qf0r_hWTyeQ?si=g6L3nJPsAatnJhCU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

こちらもプロンプトがきちんと反映されていますね。

本当に、AIで生成されたものを目にする度、すごい時代になったと感じます。

## 最後に

コードだけで完結するのが嬉しいです。

動画周りはもっと色々と遊んでみたい。

## 宣伝

[SupershipのQiita Organization](https://qiita.com/organizations/supership-inc)を合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。

Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方は[Supership株式会社 採用サイト](https://supership.jp/recruit/)よりご確認ください。