エンジニアとしての市場価値を測りませんか?PR

企業からあなたに合ったオリジナルのスカウトを受け取って、市場価値を測りましょう

8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C#で動画を作ってみた話

Last updated at Posted at 2022-01-30

#はじめに
C#の知識が.Net Framework 3.5あたりで止まっているので、ちょっとまずいなと思っている黒髭和熊です。
まぁ、作るのには困らないんですけどね・・・

さて、今回ですが、Youtubeで動画を公開しているのですが、その動画のオープニングを作りたいなぁと思っていました。
で、昔から使ってるキャラクタを動かしたいなと思ったんですが、簡単にできないかなー?と思ったんです。
面倒なので、描いた絵をプログラムで動かせば思い通りにできるんじゃないか?ということで調べて作りました。

動画はこれ。
ちなみに、作った動画をDavinci Resolveで音をつけたりフェードアウトさせています。

そんなお話です。

#使ったもの

#概要
動画のオープニングだけじゃなくて、ほかの動画も作ることを考えています。
なので、アニメーションを行う部分は抽象化し、動画にする部分は共通の処理にしています。
ですが、そこはあまり重要ではないので触れません。(知りたい人がいれば書きます)
今回使用したAForgeをどう使っているかを紹介できればと思っています。

クラス図はこんな感じです。
Form1で管理して、描画は別のクラス、といった感じになります。
image.png

実際の画面はこんな感じ。
image.png

さて、処理についてですが、作ったプログラムに沿った形で説明していきます。
AForgeの使用方法にあまり関係ないところがありますが、クラス図と比較しながら見ていただければと思います。

AbstructAnimationクラスを実装したChannelOpeningクラスをForm1に登録します。
ChannelOpeningクラスあオープニング動画の描画を行うクラスになります。

Form1.cs
        private VideoFileWriter videoWriter = null;

        private Thread thread = null;
        private Bitmap bmp = null;

        private AbstractAnimation currentAnime = null;

    // ・・・省略・・・

        private void Form1_Load(object sender, EventArgs e)
        {
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            cmbAnime.Items.Add(new AnimeTest(this));
            cmbAnime.Items.Add(new IngressHyperion(this));
            cmbAnime.Items.Add(new ChannelOpening(this));

            cmbAnime.SelectedIndex = 0;
        }

実行はボタンのクリックで開始します。
このタイミングで、AForge.Video.FFMPEG.VideoFileWriterのインスタンスを生成します。

Form1.cs
        private void btnExecute_Click(object sender, EventArgs e)
        {
    // ・・・省略・・・
               bmp = new Bitmap(AnimationConfig.bmpWidth, AnimationConfig.bmpHeight);

                // アニメーション初期化
                currentAnime.Initalize();

                if (AnimationConfig.isWriteMode == true)
                {
                    var text = txtLength.Text;
                    var movieLength = AnimationConfig.movieLength;
                    AnimationConfig.movieLength = movieLength;
                    AnimationConfig.writeFrameCnt = 0;
                    videoWriter = new VideoFileWriter();
                    videoWriter.Open(@"C:\data\test4.mp4", bmp.Width, bmp.Height, AnimationConfig.framerate, VideoCodec.MPEG4);
                }

VideoFileWriter.Open()メソッドで保存するファイル名や動画のサイズ、フォーマットを指定します。
ここで気を付けるべきはフォーマット。
AVIで保存すると結構大きなファイルになります。
フォーマットはVideoCodec列挙型で定義されています。
定義内容は公式ドキュメントのVideoCodec Enumerationを見てもらえばわかります。
私はVideoCodec.MPEG4を選択しています。
フレームレートはAnimationConfigクラスで60を指定しており、その値を利用しています。

ボタンを押したタイミングでスレッドを作成し、描画用メソッドdraw()を呼び出しています。
その中でChannelOpeningクラスの描画した内容をVideoFileWriterのWriteVideoFrameメソッドで書き込んでいます。

Form1.cs

    // ・・・省略・・・

                thread = new Thread((ThreadStart)delegate ()
                {
                    long tm = 0;
                    long frm = 0;
                    while (thread != null)
                    {
                        tm = DateTime.Now.Ticks;
                        draw();

    // ・・・省略・・・

        private void draw()
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                currentAnime.OnDraw(g);

                if (AnimationConfig.isWriteMode == true && videoWriter != null)
                {
                    videoWriter.WriteVideoFrame(bmp);
                }
            }
        }

書き込みはすごく簡単で、VideoFileWriter.WriteVideoFrame()メソッドに作成したビットマップを渡すだけです。
書き込みが終わったら、Close()メソッドで、VideoFileWriterを閉じればOKです。

Form1.cs
    videoWriter.Close();

#終わりに

ざっくりですが、C#で動画を作ってみた話を紹介しました。
Magick.NETも試したのですが、私の実装が悪かったせいか、動画を作れないことがあったので断念。
AForge.NETはそんなこともなく割と簡単に使えたので採用しました。
音もやればできるみたいですが、まぁ、音はDavinci Resolve使ったほうが楽だったので^^;

実際のコードはたぶんGithubに公開すると思います。
いつになるかわかりませんがw

Githubにリポジトリ作りました。
こちらになります。

あ、最後に。
よかったら私のYoutubeのチャンネルも見てみてください。
そのうちこの記事の内容も動画にしようと思っています。

8
7
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

Qiita Advent Calendar is held!

Qiita Advent Calendar is an article posting event where you post articles by filling a calendar 🎅

Some calendars come with gifts and some gifts are drawn from all calendars 👀

Please tie the article to your calendar and let's enjoy Christmas together!

8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?