9
6

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 3 years have passed since last update.

FFmpegを利用して1枚の画像と音声ファイルから動画を作成する

Last updated at Posted at 2020-08-09

はじめに

FFmpegを利用して1枚の画像と音声ファイルから動画を作成します。

FFmpegのダウンロード

公式サイトからプログラムを入手します
https://ffmpeg.org/

FFmpegのコマンド

FFmpegで1枚の画像と音声ファイルから動画を作成するコマンドです

ffmpeg -loop 1 -i sample.jpg -i sample.mp3 -vcodec libx264 -acodec aac -ab 160k -ac 2 -ar 48000 -pix_fmt yuv420p -shortest output.mp4

コマンドオプションの説明

コマンド 説明
-loop 1で静止画を繰り返す
-i 入力ファイル。画像を先に
-vcodec 動画コーデック
-acodec 音声コーデック
-ab 音声ビットレート
-ac 音声チャンネル数
-ar 音声サンプリングレート
-pix_fmt yuv420p
-shortest 入力の短い方(音声)に動画時間を合わす
output.mp4 出力ファイル名

最小オプションのコマンド

ffmpeg -loop 1 -i sample.jpg -i sample.mp3 -pix_fmt yuv420p -shortest output.mp4

-rは25、-abと-acと-arは入力通りになる

Webで動かす

ffmpeg.wasmを使用してWebで動かす。
夢のような話ですが、ブラウザ上でエンコードします。

<form id="form">
  音声<input id="audio" type="file" required><br>
  画像<input id="image" type="file" required><br>
  <button id="button">音声と画像から動画を作成する</button>
</form>
<video id="video" controls></video>

<script>
form.onsubmit = function(event){
    event.preventDefault()
    button.disabled = true

    ffmpeg('-y', '-loop', 1, '-i', image.files[0], '-i', audio.files[0], '-pix_fmt', 'yuv420p', '-shortest', 'out.mp4')
    .then( mp4 => video.src = URL.createObjectURL(mp4) )
    .finally( () => button.disabled = false )
}

async function ffmpeg(...command){ // https://github.com/ffmpegwasm/ffmpeg.wasm
    await import('https://unpkg.com/@ffmpeg/ffmpeg@0.9.6/dist/ffmpeg.min.js')
    const ffmpeg = FFmpeg.createFFmpeg({logger: e => console.log(e.message)})

    if (!ffmpeg.isLoaded()){
        await ffmpeg.load()
    }

    for(var [i,v] of command.entries()){
        if(v instanceof Blob){
            ffmpeg.FS('writeFile', String(i), new Uint8Array(await v.arrayBuffer()))
            v = i
        }
        command[i] = String(v)
    }

    await ffmpeg.run(...command)

    return new File([ffmpeg.FS('readFile', v).buffer], v)
}
</script>

きちんと動作するが、エンコードが遅くて実用性に欠ける。
コマンドを工夫するのだろうが分からない。試しに「-r 1」とすると動画時間が狂う

上記のコードですが、少し作り込んでFFmpegのラッピング関数ffmpegを作っている。

  • コマンドを1つ1つ引数に渡す。入力ファイルは直接渡し、出力ファイル名を最後に渡す
  • この関数は非同期であり、成功時はFileオブジェクトが返る

バッチファイルで動かす

音声+画像ファイルをBATファイルにD&Dし、起動させることもできる。

音声と画像から動画作成.bat
@echo off
rem https://qiita.com/economist/items/bb325e8d23e0b3521c65

ffmpeg -loop 1 -i %1 -i %2 -pix_fmt yuv420p -shortest "%~dpn2.mp4"

pause

注意する点として、先に音声ファイルを選択する必要がある
音声ファイルを選択→画像ファイルを選択→両方一緒にBATファイルにD&D

出力ファイル名は音声ファイルで決まる。画像ファイルに合わせたい場合は%~dpn1.mp4

9
6
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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?