1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ESP32でmp4動画を再生する方法、ファイル転送方法

1
Last updated at Posted at 2026-06-30

概要

 ESP32でmp4動画を再生させる手法を説明します。また、PCからESP32へファイル転送する方法も合わせて紹介します。

image.png


動画再生の実行例を以下リンク先でご紹介しております。
 動作動画1:https://youtube.com/shorts/8US4eWBNk24
 動作動画2:https://youtu.be/QakuN59XoTw

はじめに

 ESP32ではmp4動画を直接再生することはできません。よって、mp4ファイルをmjpegファイルに変換する必要があります。つまり、mjpegファイルにして、画像をコマ送りにして動画にするイメージです。
 変換するために、ffmpegを使用します。WindowsPCでコンソールを立ち上げ、以下コマンドでインストールしてください。

winget install ffmpeg

次に動画を変換します。以下例はtest.mp4という動画を、フレームレート5、128×128の解像度(ご使用のディスプレイ解像度に合わせてください)で、test.mjpegに変化する例です。
Windowsコンソールで実行し、変換してください。

ffmpeg -i test.mp4 -t 5 -vf "scale=128:128,fps=8" -an -c:v mjpeg -q:v 10 -f mjpeg test.mjpg

尚、変換後の動画ファイルのサイズは、ESP32側のメモリサイズの関係で1MB程度とする必要があります。

 次に動画ファイルをESP32へ転送するためのプラグインをAruduinoIDEへインストールします。以下リンクでプラグイン(arduino-littlefs-upload-1.6.3.vsix)をダウンロードします。

https://github.com/earlephilhower/arduino-littlefs-upload/releases

ダウンロードしたファイルを、ご自分のPluginフォルダへコピーしてください。まだPluginフォルダが無い場合は作成してください。

C:\Users\xxxxx\.arduinoIDE\Plugins

次にご自分のプログラムのプロジェクトにdataフォルダを作成し、そこに動画ファイルtest.mjpegをコピーしておきます。以下作成例。
image.png

次に、AruduinoIDEを起動します。

Ctrl+Shift+P を押し、「Upload LittleFS to Pico/ESP8266/ESP32」を選択すると転送が開始されます。
※この時シリアルモニタなどを利用している場合は転送できないので、切断してから上記実行してください。

尚、ESP32内のファイルを削除した場合は、dataフォルダ内のファイルを削除し、再度Ctrl+Shift+P を押し、「Upload LittleFS to Pico/ESP8266/ESP32」を選択で、ESP32内のファイルが消えます。

動画再生プログラム例

動画再生プログラム例を紹介いたします。ESP32 devKitにST7735ディスプレイを接続して表示する場合の例になります。

#include <Arduino.h>
#include <LittleFS.h>
#include <TFT_eSPI.h>
#include <TJpg_Decoder.h>

//========== ユーザー設定 ==========
#define TFT_ROTATION 3          // 向き(0-3)
#define FRAME_DELAY  65        // fps調整(ms)
#define JPG_SCALE    1          // 1=等倍 / 2=1/2

// JPEG最大サイズ
#define MAX_JPEG (48 * 1024)

//========== グローバル ==========
TFT_eSPI tft = TFT_eSPI();
uint8_t jpgBuf[MAX_JPEG];

//========== JPEG描画 ==========
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bmp) {
 tft.pushImage(x, y, w, h, bmp);
 return true;
}

//========== MJPEGから1フレーム読み出し ==========
bool readJpg(File &f, size_t &len) {
 len = 0;
 int prev = -1;

 while (f.available()) {
   int c = f.read();
   if (c < 0) break;

   if (len == 0) {
     if (prev == 0xFF && c == 0xD8) { // SOI
       jpgBuf[0] = 0xFF;
       jpgBuf[1] = 0xD8;
       len = 2;
     }
   } else {
     if (len >= MAX_JPEG) return false;
     jpgBuf[len++] = c;

     if (prev == 0xFF && c == 0xD9) { // EOI
       return true;
     }
   }
   prev = c;
 }
 return false;
}

//========== setup ==========
void setup() {
 Serial.begin(115200);

 // TFT初期化
 tft.init();
 tft.setRotation(TFT_ROTATION);
 tft.setSwapBytes(true);
 tft.fillScreen(TFT_BLACK);

 // FS初期化
 if (!LittleFS.begin()) {
   Serial.println("LittleFS error");
   while (1);
 }

 // JPEGデコーダ設定
 TJpgDec.setCallback(tft_output);
 TJpgDec.setJpgScale(JPG_SCALE);

 Serial.println("MJPEG start");
}

//========== loop ==========
void loop() {
 File f = LittleFS.open("/test.mjpg", "r");
 if (!f) return;

 while (true) {
   size_t len;
   if (!readJpg(f, len)) break;

   TJpgDec.drawJpg(0, 0, jpgBuf, len);

   delay(FRAME_DELAY);
 }

 f.close();
}
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?