見出し画像

プログラムでテキストから動画 生成方法

割引あり

はじめに

背景

この記事はDell-Eを使って画像生成を行い、その画像にGoogle Cloud Text-to-Speechを使って音声を付与し、最後にffmpegを使って動画を生成するシステムを構築するための手順をまとめたものです。

私が試しに作成した作品はこちらです:

※ホラー系ですのでご注意ください…

このシステムを用いることで、簡単に映像作品を大量に生成することが可能になります。

主な技術

このシステムを利用するために活用される技術について説明します。

  • Python : 本システムのコア部分はPythonで書かれており、その柔軟性と豊富なライブラリがシステムの強力な基盤となっています。

  • Docker : 環境構築やデプロイを容易にするために、Dockerを活用します。Dockerを用いることで、開発環境を短時間で構築することが可能です。

  • Google Cloud Platform(GCP) : 音声生成にはGCPを使用します。

  • OpenAI : 映像作成にdall-eを利用し、補助的にGPTを利用しています。

  • FFMPEG : テキストから生成した画像・映像周りを加工するためにFFMPEGを使用します。

  • DALL-E : テキストから画像を生成するためにDALL-Eを使用します。

目次

この本は以下のような構成になっています。

1. ソースコードの解説とソースコード自体  
2. 環境構築方法  
3. 利用方法  

基本的にソースコードをコピーしていただき、環境構築を行えば、すぐに本システムを動かすことができます。
また、記載についてはオプションの変更方法も含めて追記していく予定です。

必要な契約と費用

このシステムを動かすためには、以下の契約が必要です。

  • Google Cloud Platform(GCP)のアカウント

    • Speech-to-Text API を利用可能なこと

  • OpenAIのアカウント

実際の契約については具体的に環境構築の部分で説明をさせていただいております。

問い合わせについて

私のTwitterアカウントの方に問い合わせいただければと思います。

https://twitter.com/HashitoZ

不具合や改善点などありましたら、お気軽にご連絡ください。


ソースコードの概要

この章では、本システムのソースコードを紹介します。
この章と次の実行方法に関する章を確認すれば、本システムを自身の環境で動かすことができるようになるでしょう。

ソースコードの構成

ソースコードは以下のような構成になっています。

ffmpeg_common.py

ffmpegを利用するための共通処理をまとめたファイルです。
生成された画像と音声を結合する処理などが含まれています。

gpt.py

chat gptを利用するための共通処理をまとめたファイルです。

image_common.py

画像編関係の処理をまとめたファイルです。
画像内にテキストを追加したり、画像サイズを変換したりする処理が含まれています。

text_to_speech.py

google cloud text to speechを利用するための共通処理をまとめたファイルです。
text to speechを利用することで、テキストを音声に変換することができます。

dall_e.py

openaiのdall-eを利用するための共通処理をまとめたファイルです。
dall-eを利用することで、テキストから画像を生成することができます。
※あとでも説明しますが性的な表現や暴力的な表現が含まれる場合は画像生成に失敗する可能性があります。

main.py

本システムのメイン処理をまとめたファイルです。
基本的にはベースとなるjsonファイルを読み込み、その内容に従って処理を実行します。

ffmpeg_common.py

概要

このソースはffmpegを利用するための共通処理をまとめたファイルです。
生成された画像と音声を結合する処理などが含まれています。
`ffmpegio`というライブラリを利用し、ffmpegの処理をpythonから実行しています。

ソースコード

import ffmpegio  
import uuid  
import os  
  
# videosに含まれるファイルパスのリストを参考に、動画を結合します。  
# dst_pathに結合後の動画のファイルパスを指定します。  
def video_join(videos,dst_path=False):  
    if(not dst_path):  
        dst_path="movie/"+str(uuid.uuid4())+".mp4"  
  
    temp_file="temp_"+str(uuid.uuid4())+".txt"  
    with open(temp_file,mode='w') as f:  
        f.write("".join(list(map(lambda x: "\nfile "+x,videos))))  
  
    ffmpegio.ffmpeg([  
        '-f','concat',  
        '-i',temp_file,  
        '-safe','0',  
         dst_path])  
    os.remove(temp_file)  
    return dst_path  
  
  
# 画像と音声を結合します。  
# image_fnに画像のファイルパスを指定します。  
# audio_fnに音声のファイルパスを指定します。  
# dst_pathに結合後の動画のファイルパスを指定します。  
def img_audio_to_movie(image_fn,audio_fn,dst_path=False):  
    if(not dst_path):  
        dst_path="movie/"+str(uuid.uuid4())+".avi"  
    # ffmpeg -y -loop 1 -r 30000/1001 -i img/5f5e25bf-2c04-4abe-baf0-201ba837b3fa.png -i speech/4f8fdff2-737b-4e29-9360-21fbe14457bc.mp3 -vcodec libx264 -acodec aac -strict experimental -ab 320k -ac 2 -ar 48000 -pix_fmt yuv420p -shortest out.mp4  
    ffmpegio.ffmpeg(  
        [  
            '-y',  
            '-loop','1',  
            '-r','30000/1001',     # フレームレート(30000/100)  
            '-i', image_fn,  
            '-i', audio_fn,  
            '-vcodec','mpeg4',       # ビデオコーデック(H.264)  
            '-acodec','pcm_s16le',   # オーディオコーデック(mp3)  
            '-tune', 'stillimage',   # 静止画に最適化  
            '-strict','experimental',# 先行機能を利用する  
            '-ab','320k',            # 音声のビットレート  
            '-ac','2',               # 音声チャンネル数を指定  
            '-ar','48000',           # 音声のサンプリングレート  
            '-pix_fmt','yuv420p',    # ピクセルフォーマット(yuv420p)  
            '-shortest',             # 入力の小さい方に合わせる  
            '-safe','0',             # ファイルの相対パスを取得  
            dst_path  
        ]  
    )  
    return dst_path  
  
# お試し実行するためのコードです。  
# demo_dataフォルダにある画像と音声を結合します。  
# 対象のフォルダやファイルがない場合は失敗するため、事前に準備してください。  
# また、出力先としてmovieフォルダを作成しておく必要があります。  
# 実行は`python ffmpeg_common.py`で行えます。  
if __name__ == "__main__":  
    img_audio_to_movie(  
        "demo_data/XA.png",  
        "demo_data/BA.mp3"  
        )  
    video_join(  
        ['demo_data/AA.mp4',  
        'demo_data/AB.mp4']  
        )  
  

ここから先は

16,136字 / 30画像

この記事が気に入ったらサポートをしてみませんか?