3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Windows】【Python】X(旧Twitter)にOpenCVで書き出した動画をアップロードしたい

Last updated at Posted at 2025-12-23

この記事はOpenCV Advent Calendar 2025の24日目の記事です。

はじめに

X(旧Twitter)は、アウトプットを行うには最も手軽なプラットフォーム(の一つ)です。
しかし、OpenCV で何も考えずに VideoWriter()で動画を出力して、X にアップロードしようとすると、以下のようにアップロードできないことが多いですね👀

image.png

サンプルコード:videowriter01.py
import cv2
import numpy as np

# 動画設定
WIDTH = 640
HEIGHT = 480
FPS = 30
DURATION_SEC = 5

# VideoWriter初期化
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
writer = cv2.VideoWriter("videowriter01.mp4", fourcc, FPS, (WIDTH, HEIGHT))

# フレームごとに色を変化させて動画を書き出す
total_frames = FPS * DURATION_SEC
for i in range(total_frames):
    hue = int((i / total_frames) * 180)
    hsv = np.full((HEIGHT, WIDTH, 3), (hue, 255, 255), dtype=np.uint8)
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

    writer.write(bgr)

writer.release()

Q.なぜ?

A.OpenCVの mp4v 書き出しは(環境にもよるが)MPEG-4 Part2 で、X がサポートしているのは H.264 (MPEG-4 Part10 / AVC) だから

なので、FFmpegがインストールされている環境であれば、以下のように変換するか

サンプルコード:videowriter02.py
import os
import cv2
import numpy as np
import subprocess

# 動画設定
WIDTH, HEIGHT = 640, 480
FPS = 30
DURATION_SEC = 5

TEMP_FILE = "videowriter01.mp4"
OUTPUT_FILE = "videowriter02.mp4"

# VideoWriter初期化
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
writer = cv2.VideoWriter(TEMP_FILE, fourcc, FPS, (WIDTH, HEIGHT))

# フレームごとに色を変化させて動画を書き出す
total_frames = FPS * DURATION_SEC
for i in range(total_frames):
    hue = int((i / total_frames) * 180)
    hsv = np.full((HEIGHT, WIDTH, 3), (hue, 255, 255), dtype=np.uint8)
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

    writer.write(bgr)

writer.release()

# FFmpegでH.264(yuv420p)に変換
subprocess.run([
    "ffmpeg", "-y", "-i", TEMP_FILE,
    "-c:v", "libx264", "-pix_fmt", "yuv420p",
    OUTPUT_FILE
], check=True)


# 一時ファイルを削除
os.remove(TEMP_FILE)

Windows環境であれば、Cisco の OpenH264(cisco/openh264/releases/tag/v1.8.0)からopenh264-1.8.0-win64.dllを取得してきて、スクリプトと同じディレクトリに配置し、以下を実行するのもありです(LinuxとかMacも同様だっけ?)

サンプルコード:videowriter03.py
"""時間経過で色が変化する動画を生成(OpenCVのみ・Twitter対応)"""

import cv2
import numpy as np

# 動画設定
WIDTH, HEIGHT = 640, 480
FPS = 30
DURATION_SEC = 5
OUTPUT_FILE = "videowriter03.mp4"

# H.264コーデック(avc1)でVideoWriter初期化
fourcc = cv2.VideoWriter_fourcc(*"avc1")
writer = cv2.VideoWriter(OUTPUT_FILE, fourcc, FPS, (WIDTH, HEIGHT))

# フレームごとに色を変化させて書き出し
total_frames = FPS * DURATION_SEC
for i in range(total_frames):
    hue = int((i / total_frames) * 180)
    hsv = np.full((HEIGHT, WIDTH, 3), (hue, 255, 255), dtype=np.uint8)
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    
    writer.write(bgr)

writer.release()

しかし、opencv-python が想定している OpenH264 のバージョンは古いですね、、、👀
※最新は2.5.1ですが、Xが要求するのは標準的なH.264のため、1.8.0で十分ではあります

ちなみに、横長動画

画像処理していると、以下のように入力動画と処理動画を横に並べて眺めたいことありますよね?
あるよね👀?
ちなみに以下は、LLIE(Low-Light Image Enhancement)で暗闇画像を補正した例です。

image.png

これを X にアップロードしようとすると「アップロードしようとした動画の縦横比が大きすぎます」となり、アップロードできません。

image.png

Q.なぜ?

A.エラー文の通りですが、X では 1:3 〜 3:1 の縦横比のみ対応しているため

3:1に収まるように縦方向に結合するか、トリミングして横方向に結合するとアップロードできます。

確認のため、以下のように複数解像度で動画を生成してみました。

サンプルコード:videowriter04.py
import os
import cv2
import numpy as np

OUTPUT_DIR = "output"
FPS = 30
DURATION_SEC = 3
BASE = 720

# Twitter対応: 1:3 〜 3:1 の境界付近
RESOLUTIONS = [
    (int(BASE * 2.9), BASE, "wide_2.9_ok"),
    (int(BASE * 3.0), BASE, "wide_3.0_boundary"),
    (int(BASE * 3.1), BASE, "wide_3.1_ng"),
    (BASE, int(BASE * 2.9), "tall_2.9_ok"),
    (BASE, int(BASE * 3.0), "tall_3.0_boundary"),
    (BASE, int(BASE * 3.1), "tall_3.1_ng"),
]

os.makedirs(OUTPUT_DIR, exist_ok=True)

for width, height, name in RESOLUTIONS:
    filepath = os.path.join(OUTPUT_DIR, f"{name}.mp4")
    print(f"生成中: {name} ({width}x{height})")

    fourcc = cv2.VideoWriter_fourcc(*"avc1")
    writer = cv2.VideoWriter(filepath, fourcc, FPS, (width, height))

    for i in range(FPS * DURATION_SEC):
        hue = int((i / (FPS * DURATION_SEC)) * 180)
        hsv = np.full((height, width, 3), (hue, 255, 255), dtype=np.uint8)
        bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
        writer.write(bgr)

    writer.release()

image.png

image.png

比率 解像度例 アップロード
2.9:1 2088x720 ✅ OK
3.0:1 2160x720 ✅ OK
3.1:1 2232x720 ❌ NG
1:2.9 720x2088 ✅ OK
1:3.0 720x2160 ✅ OK
1:3.1 720x2232 ❌ NG

その他、動画要件など

X に動画をアップロードする場合は以下の要件👀

項目 要件
映像コーデック H.264
ピクセルフォーマット YUV 4:2:0(yuv420p)のみ
フレームレート 60fps以下
音声コーデック AAC LC(音声がある場合)
アカウント/環境 最大動画長さ 備考
通常アカウント 140秒(2分20秒)
Premium(Web/iOS) 最大4時間 16GB上限など制限あり
Premium(Android) 最大10分 AndroidはiOSより厳しめ

※さらに補足
GOP構造(極端に長いGOPやOpen GOP)や moov atom の位置などによって、
アップロード時点で弾かれるケースもありそうです。
ただし、OpenCV単体ではこれらの設定を細かく制御するのが難しく、検証対象外としています。
FFmpegで再エンコードするのが無難です。

以上。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?