Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9691

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

$
0
0
はじめに C#の知識が.Net Framework 3.5あたりで止まっているので、ちょっとまずいなと思っている黒髭和熊です。 まぁ、作るのには困らないんですけどね・・・ さて、今回ですが、Youtubeで動画を公開しているのですが、その動画のオープニングを作りたいなぁと思っていました。 で、昔から使ってるキャラクタを動かしたいなと思ったんですが、簡単にできないかなー?と思ったんです。 面倒なので、描いた絵をプログラムで動かせば思い通りにできるんじゃないか?ということで調べて作りました。 動画はこれ。 ちなみに、作った動画をDavinci Resolveで音をつけたりフェードアウトさせています。 そんなお話です。 使ったもの Visual Studio C# AForge.NET 概要 動画のオープニングだけじゃなくて、ほかの動画も作ることを考えています。 なので、アニメーションを行う部分は抽象化し、動画にする部分は共通の処理にしています。 ですが、そこはあまり重要ではないので触れません。(知りたい人がいれば書きます) 今回使用したAForgeをどう使っているかを紹介できればと思っています。 クラス図はこんな感じです。 Form1で管理して、描画は別のクラス、といった感じになります。 実際の画面はこんな感じ。 さて、処理についてですが、作ったプログラムに沿った形で説明していきます。 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 あ、最後に。 よかったら私のYoutubeのチャンネルも見てみてください。 そのうちこの記事の内容も動画にしようと思っています。

Viewing all articles
Browse latest Browse all 9691

Trending Articles