OpenCVというライブラリがあり、これで動画ファイルを扱えるようです。OpenCVを使って、動画ファイルからサイズ情報やサムネイルを取得してみました。
OpenCVをインストール
この記事の内容を試すには以下のコマンドのみで十分でした。Python環境整備済みのLinuxの前提です。
$ pip install opencv-python
私の環境でpipenv
でインストールしたら、バージョンは以下のようになりました。
$ pipenv install opencv-python
$ pipenv run pip list
Package Version
------------- --------
numpy 1.19.5
opencv-python 4.5.1.48
pip 20.3.3
setuptools 51.0.0
wheel 0.36.2
動画サイズや長さなどの情報を取得
動画ファイルから縦横サイズ、再生時間、コーデックの情報を取得します。
# OpenCVをインポート
import cv2
# サンプル動画ファイル
videoPath = "./sample.mp4"
cap = cv2.VideoCapture(videoPath)
# 横幅
print(f"width: {cap.get(cv2.CAP_PROP_FRAME_WIDTH)}")
# width: 600.0
# 高さ
print(f"height: {cap.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
# height: 360.0
# フレームレート
print(f"fps: {cap.get(cv2.CAP_PROP_FPS)}")
# fps: 30.0
# フレーム数
print(f"frame_count: {cap.get(cv2.CAP_PROP_FRAME_COUNT)}")
# frame_count: 639.0
# 再生時間
print(f"length: {cap.get(cv2.CAP_PROP_FRAME_COUNT) / cap.get(cv2.CAP_PROP_FPS)} s")
# length: 21.3 s
print("fourcc: " + int(cap.get(cv2.CAP_PROP_FOURCC)).to_bytes(4, "little").decode("utf-8"))
# fourcc: avc1
# コーデックの種類を4文字で表すコード
コーデックの種類を表すコードはfourccという4文字のコードです。
最初のフレームから画像ファイルを作成
動画ファイルの最初のフレームをNumpy配列で取得し、それを画像ファイルで書き出します。
import cv2
def buildVideoCaptures(videoPath, outputPath):
cap = cv2.VideoCapture(videoPath)
if not cap.isOpened(): return
# 最初のフレームを読み込む
_, img = cap.read()
# imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
# imgのshapeは (高さ, 横幅, 3)
# 画像ファイルで書き出す
# 書き出すときの画像フォーマットはファイル名から自動で決定
cv2.imwrite(outputPath, img)
buildVideoCaptures("./sample.mp4", "./thumbnail.jpg")
# PNG出力もOK
#buildVideoCaptures("./sample.mp4", "./thumbnail.png")
最初のフレームからサムネイルを作成
次は画像をリサイズして、サムネイルとして画像ファイルを作成します。cv2.resize
というメソッドでリサイズできます。
import cv2
def buildVideoCaptures(videoPath, outputPath):
cap = cv2.VideoCapture(videoPath)
if not cap.isOpened(): return
_, img = cap.read()
# imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
# imgのshapeは (高さ, 横幅, 3)
# 画像サイズを取得
width = img.shape[1]
height = img.shape[0]
# 縮小後のサイズを決定
newWidth = 100
newHeight = int(height * newWidth / width)
# リサイズ
img = cv2.resize(img, (newWidth, newHeight))
# 画像ファイルで書き出す
cv2.imwrite(outputPath, img)
buildVideoCaptures("./sample.mp4", "./thumbnail.jpg")
動画の途中からもサムネイルを作成
最初のフレームだけではなく、途中のフレームからも画像を取得します。再生時間を10分割して、10個のサムネイルを作成します。
import cv2
def buildVideoCaptures(videoPath, outputPath):
cap = cv2.VideoCapture(videoPath)
if not cap.isOpened(): return
# フレーム数を取得
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
for i in range(10):
# フレーム位置を設定
cap.set(cv2.CAP_PROP_POS_FRAMES, i * frame_count / 10)
_, img = cap.read()
# imgは読み込んだフレームのNumpy配列でのピクセル情報(BGR)
# imgのshapeは (高さ, 横幅, 3)
# 画像サイズを取得
width = img.shape[1]
height = img.shape[0]
# 縮小後のサイズを決定
newWidth = 100
newHeight = int(height * newWidth / width)
# リサイズ
img = cv2.resize(img, (newWidth, newHeight))
# 画像ファイルで書き出す
# ファイル名には連番を付ける
cv2.imwrite(outputPath % i, img)
buildVideoCaptures("./sample.mp4", "./thumbnail%d.jpg") # 出力ファイル名には連番を付ける