質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

リサイズ

コントロール、ウィンドウ、フォームやスクリーンのサイズ変更を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4303閲覧

opencv-pythonで動画ファイルをリサイズして容量を小さくしたいのにむしろ大きくなってしまう

papapai

総合スコア12

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

リサイズ

コントロール、ウィンドウ、フォームやスクリーンのサイズ変更を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/09/03 16:41

環境・やりたいこと

  • Windows10
  • Anaconda
  • python3.10

mp4ファイルの容量を小さくしたい

試したこと

opencv-pythonを使って以下のようにリサイズしました。
画素数を下げることと、fpsを下げることをしています。
fourccなどについてはよく理解できてません。

python

1import cv2 2#リサイズしたいファイル:input_filepath 3 4resize = 2 #ファイルサイズを2分の1にしたい 5resize = resize**0.5 #ルート2 6cap = cv2.VideoCapture(input_filepath) 7 8#生成する無音動画ファイルのパス 9temp_videopath = f".\\temp_video.mp4" 10 11#動画のプロパティを取得 12width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 13height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) 14fps = cap.get(cv2.CAP_PROP_FPS) 15 16#動画をリサイズ 17fourcc = cv2.VideoWriter_fourcc('m','p','4','v') 18min_fps = 30 19if fps <= min_fps: 20 writer = cv2.VideoWriter(temp_videopath,fourcc, fps, (int(width/resize), int(height/resize))) 21else: 22 writer = cv2.VideoWriter(temp_videopath,fourcc, min_fps, (int(width/resize), int(height/resize))) 23while True: 24 ret, frame = cap.read() 25 if not ret: 26 break 27 cv2.imshow("Frame", frame) 28 frame = cv2.resize(frame,(int(width/resize), int(height/resize))) 29 writer.write(frame) 30writer.release() 31cap.release() 32print("リサイズ完了") 33 34#この後音声を抽出したり結合したりするが割愛

発生している問題

期待していた通りに容量が減ることもあるが、リサイズ前よりも後の方がサイズが大きくなってしまうことがある
245MB→432MBに増加するなど。
これをどうにかしたいのですが、方法が分かりません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2022/09/03 21:45 編集

resizeやfps変更をしないで、単に別ファイル名に書き込むだけの場合は、ファイルサイズはだいたい同じになるのでしょうか?
papapai

2022/09/04 12:22

resizeやfps変更をしないで~についてですが、この場合もファイルサイズは大きくなってしまいます。 コーデックについては、mp4がどのようなコーデックを持つのかを知らないので分かりません...コンテナとかいろいろあるみたいですが、調べてみてもよく分かりませんでした。
jbpb0

2022/09/04 13:25 編集

私が紹介したWebページの 「OpenCVにおけるコーデックの確認方法」 に、コーデックの調べ方が解説されてます その方法で元動画のコーデックを調べて、それがもし「'm','p','4','v'」とは違ったら、元動画と同じコーデックを指定して、resizeやfps変更をしないで保存したら、ファイルのサイズはどうなりますでしょうか?
papapai

2022/09/04 14:23

動画のコーデックは['a', 'v', 'c', '1']になってました。 resize=1,fpsそのままでavc1でリサイズするように↓のようにしてみましが、246MBのファイルが292MBになりました。 fourcc_int = int(cap.get(cv2.CAP_PROP_FOURCC)) original_fourcc = list((fourcc_int.to_bytes(4, 'little').decode('utf-8'))) print(original_fourcc) fourcc = fourcc_int writer = cv2.VideoWriter(temp_videopath,fourcc, fps, (int(width/resize), int(height/resize))) 実行してみると、下記のようなメッセージが出てきました。 Failed to load OpenH264 library: openh264-1.8.0-win64.dll Please check environment and/or download library: https://github.com/cisco/openh264/releases
jbpb0

2022/09/05 01:18 編集

> Failed to load OpenH264 library: openh264-1.8.0-win64.dll が出てる場合は、「'a', 'v', 'c', '1'」(H.264)で保存できてません 「'a', 'v', 'c', '1'」(H.264)で保存するための方法は、 https://blog.shikoan.com/opencv-h264/#OpenH264%E3%81%8C%E5%BF%85%E8%A6%81 の「OpenH264が必要」を見てください 「'a', 'v', 'c', '1'」(H.264)でresizeやfps変更をしないで保存したら、「'a', 'v', 'c', '1'」(H.264)の元動画と同じくらいのファイルサイズになるのではないですかね 元動画とだいたい同じファイルサイズで保存できれば、resizeで画素数を減らせばファイルサイズが小さくなることが期待できます
papapai

2022/09/05 10:31

ありがとうございます。 ダウンロードして実行してみました。OpenH264 Video Codec provided by Cisco Systems, Inc.との表示が出たので['a', 'v', 'c', '1']でリサイズできたのでしょうが、ファイルサイズはむしろ246MB→1.28GBに大きくなってしまいました...
jbpb0

2022/09/05 11:39

保存したファイルを再度opencvで読み出してエンコードを調べたら、「'a', 'v', 'c', '1'」でしょうか?
papapai

2022/09/05 11:50

保存したファイルを絶対パスで指定してエンコードを調べましたが、 828601953、['a', 'v', 'c', '1'] でした。
jbpb0

2022/09/06 02:50

当方のmacでやってみました https://mixkit.co/free-stock-video/portrait-of-a-woman-in-a-pool-1259/ から動画ファイルをダウンロードしました ファイルサイズは 48MB でした pythonで下記を実行したら、動画ファイルのエンコードは「'a', 'v', 'c', '1'」でした import cv2 cap = cv2.VideoCapture("./mixkit-portrait-of-a-woman-in-a-pool-1259.mp4") fourcc_org_int = int(cap.get(cv2.CAP_PROP_FOURCC)) fourcc_org = list((fourcc_org_int.to_bytes(4, 'little').decode('utf-8'))) print(fourcc_org) そこで、 fourcc = cv2.VideoWriter_fourcc('a','v','c','1') として、resizeやfps変更をしないで writer = cv2.VideoWriter(temp_videopath, fourcc, fps, (width, height)) としてから、 while True: ret, frame = cap.read() if not ret: break writer.write(frame) と、無加工で動画ファイルを作成したら、できたファイルのサイズは 47.3MB となり、元動画ファイルの 48MB に近いサイズになりました (上記コードは必要最小限だけ書いてます) こんな感じになると予想してたのですが、 > ファイルサイズはむしろ246MB→1.28GBに大きく ですか 当方のmacで実行した際は、エラーが出なかったので「OpenH264」をインストールする必要はありませんでした 当方のmac内で使われたものと「OpenH264」で、性能に違いがあるのかもしれません
papapai

2022/09/06 03:57

同じ縦横同じfpsの動画のサイズに影響を与える要素って、fourccだけなんでしょうか。 jpegみたいな品質の設定とかはないんですかね?
papapai

2022/09/06 04:23

フレーム書き込み処理の所は私のだと下のようになっているんですが、jbpb0さんのと同じ書き方をしても結果って変わりませんかね resize=1 while True: ret, frame = cap.read() if not ret: break cv2.imshow("Frame", frame) frame = cv2.resize(frame,(int(width/resize), int(height/resize))) writer.write(frame)
papapai

2022/09/06 04:25

resize=1 while True: 空白ret, frame = cap.read() 空白if not ret: 空白空白break 空白cv2.imshow("Frame", frame) 空白frame = cv2.resize(frame,(int(width/resize), int(height/resize))) 空白writer.write(frame)
jbpb0

2022/09/06 08:30 編集

> jpegみたいな品質の設定とかはないんですかね? ビットレートを変えたら、ファイルサイズは変わります https://jbjbgame.com/post-5623/ https://github.com/opencv/opencv/issues/8961 https://stackoverflow.com/questions/38686359/opencv-videowriter-control-bitrate 当方のmacで確認した > できたファイルのサイズは 47.3MB となり、元動画ファイルの 48MB に近いサイズになりました では、ビットレートは下記の通りで、だいたい同じでした ・元ファイル:25715 kb/s ・opencvで作成したファイル:25359 kb/s > ファイルサイズはむしろ246MB→1.28GBに大きく の元動画ファイルと、opencvで作成した動画ファイルのそれぞれで、 右クリック→プロパティ→詳細 でビットレートを確認 https://pc-kaizen.com/windows10-check-the-bit-rate-of-the-video してみてください 元動画ファイルよりもビットレートが増えてるのかも
jbpb0

2022/09/06 08:55

windowsでも、同じ動画ファイル https://mixkit.co/free-stock-video/portrait-of-a-woman-in-a-pool-1259/ でやってみましたが、macでの結果と同様に、元動画ファイルとopencvで作成したファイルは、ビットレートもファイルサイズもだいたい同じになりました windowsではエラーが出たので「OpenH264」をインストールしましたが、結果はmacと同様だったので、「OpenH264」の性能が劣ってるわけではないようです 私が使った動画ファイルのビットレートが、たまたまopencvが作成する動画ファイルのビットレートと近かったので、ファイルサイズもだいたい同じになった、という気がします
papapai

2022/09/06 08:56

ありがとうございます。ビットレートは考え付きませんでした。 ビデオ データ速度 10093kbps→54420kbps 総ビットレート 10411kbps→54547kbps オーディオ ビットレート 316fps→126kbps に変わっていました。(矢印右側がリサイズ後) 音声の処理はffmpegで以下のようにやりました。 import subprocess import ffmpeg #元ファイルから音声を抽出 #入力 stream = ffmpeg.input(input_filepath) #出力 stream = ffmpeg.output(stream, "temp_audio.mp3") #実行 ffmpeg.run(stream) #音声ファイルとリサイズ後ファイルを結合 command = ["ffmpeg" ,"-i" ,temp_videopath ,"-i" ,"temp_audio.mp3" ,"-c:v" ,"copy" ,"-c:a" ,"aac" ,"-map" ,"0:v:0" ,"-map" ,"1:a:0" ,resize_videopath] subprocess.run(command) commandの内容は、調べている時に見つけたものをそのまま貼り付ける形で使っています。 音声ファイルと結合する前のリサイズ済み無音動画ファイルのサイズも確認しましたが、やはり大きかったです。なので、一番の原因はopencvの段階にあるんじゃないかとは思います。
jbpb0

2022/09/06 10:27 編集

> 音声の処理はffmpegで以下のようにやりました。 そこでffmpegを使うのなら、動画をリサイズしたりフレームレートを変えたりするところも、opencvを使わずにffmpegを使ったらいいと思います https://jbjbgame.com/post-5623/#st-toc-h-3 のオプションで、 ・映像と音声のビットレートと、コーデックは元動画ファイルと同じ ・フレームレートとサイズは、任意の値 とすれば、この質問の意図通りの結果になると思います (ビットレートも変えていいかも)
papapai

2022/09/06 13:15

そうですね、ffmpegで全部やれてしまえるならそっちの方が効率がよさそうですね。
papapai

2022/09/06 13:21

元ファイルのビットレートに応じた演算をするためにffmpeg.probeからビットレートを取得しようとしているのですが、ffmpeg.probe(input_filepath)["streams"][0]["bit_rate"]で得たbit_rateの値が10117031でプロパティから見た値が10093kbpsと微妙に違うのですが、これは2進数からくる誤差と捉えて大丈夫ですかね?
jbpb0

2022/09/07 00:35 編集

> ffmpeg.probe(input_filepath)["streams"][0]["bit_rate"]で得たbit_rateの値が10117031でプロパティから見た値が10093kbpsと微妙に違う 何で違うのか分かりませんが、ffmpegで処理するのだから、ffmpegで取得した値を使えばいいと思いますよ 以下は、参考情報 python経由ではなく、コマンドプロンプトで直接 ffmpeg -i 動画ファイル名 または ffprobe 動画ファイル名 を実行したら、「Duration:」で始まる行と、「Stream」で始まる行の両方にビットレートが表示されますが、下記によると「Stream」で始まる行の数値が動画作成時にエンコーダーに設定された数値らしいので、それを設定したらいいと思います https://stackoverflow.com/questions/54608161/what-is-the-difference-of-duration-bitrate-and-stream-bitrate-in-ffmpeg-ffprobe (ffmpeg実行だとoutputがどうとか言われるけど気にしない) ffprobe -loglevel quiet -show_streams 動画ファイル名 を実行した結果の「bit_rate=数値」は、上記の「Stream」で始まる行の数値をkbpsではなくbps表示(3桁増える)したものです https://www.ninton.co.jp/archives/3081 おそらく、下記と同じ数値だと思います > ffmpeg.probe(input_filepath)["streams"][0]["bit_rate"]で得たbit_rateの値
papapai

2022/09/07 10:25

ビットレート値の微妙な違いがリサイズ後の生成物に大きな影響を与えるというわけではないのなら気にせずやっていこうと思います。 .command = ["ffmpeg" . , "-i", input_filepath . , "-b:v", f"{bit_rate_k}k" . , "-c:v", "h264" . , "-c:a", "copy" . , "-r", f"{fps}" . , "-s", f"{width}x{height}" . , resize_videopath] .subprocess.run(command) でやってみたところ、うまくいきました。同じ縦横、同じfps、同じビットレートでやってみるとほとんど同じ容量のものができました。 command=[]に特に問題が無いようでしたら、ベストアンサーとさせていただきたいので回答をお願いします。
jbpb0

2022/09/07 10:55

opencvではなくffmpegでやる場合は、たしか元動画ファイルに音声がある場合は変換後の動画ファイルにも音声が残ったような記憶があります それが合ってるなら、音声のビットレートも指定しないと、もしかしたら変わってしまうかもしれません 音声は容量的には少ないので、音声のビットレートが変わってもファイルサイズ的にはほとんど効きませんが、音声の音質が変わるのは実用上困るかもしれないので あと、動画のビットレートを変えずに解像度(画素数)を減らすのと、解像度を変えずにビットレートを減らすのと、両方を(控えめに)減らすのと、変換後の画質とファイルサイズのバランス的にどの組み合わせが最良か、で変換のパラメータを決めたらいいと思います
papapai

2022/09/07 11:27

実際にfps,画素数,ビットレートを下げて私が先程書いた通りのcommandで実行してみましたが、音声はちゃんと入ってました。 保険としてビットレート指定を入れておくとかは必要なんでしょうか?
jbpb0

2022/09/07 14:21

右クリック→プロパティ→詳細 で、元動画ファイルと作成した動画ファイルそれぞれの音声(オーディオ)のビットレートを確認して、もしビットレートが著しく増えてたら、意味無いので元ファイルと同じ数値を指定したらいいと思います ビットレートが著しく減ってる場合は、作成したファイルの音声を聞いて音質低下が気になるなら元ファイルと同じ数値を指定し、気にならないならそのままでいいと思います
papapai

2022/09/07 15:38

音を聞いてプロパティを見てっていう手間をかけるなら最初から音声ビットレートを指定した方が無難そうですね...
papapai

2022/09/09 13:21

音声ビットレートなどについては追々やっていきますが、質問の趣旨は達成できたので回答していただいてもよろしいでしょうか。回答していただかないとベストアンサーにできません。
guest

回答1

0

ベストアンサー

リサイズ前よりも後の方がサイズが大きくなってしまうことがある

コーデックやビットレートが違うと、そうなる場合があります
元動画ファイルと作成した動画ファイルで、コーデックが同じか、ビットレートが(だいたい)同じか、を調べてみてください

OpenCVの動画コーデック
の「OpenCVにおけるコーデックの確認方法」

Windows10 動画・音声のビットレートを確認する

投稿2022/09/09 14:32

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papapai

2022/09/09 14:42

長期間質問に付き合っていただきありがとうございました。 ビットレートの増加が問題だと分かったので、追々opencvでもビットレートを小さくするプログラムを作ってみたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問