前回の記事で紹介したplotbitrate CLIを用いることで、オプション一つで動画や音声ファイルのフレーム毎のサイズデータをCSVファイルで保存出来ますし、動画ファイルにあっては、解析が容易になる様にフレームタイプ種類(I,P,B)がフレーム毎に分類されます。 このplotbitrate で生成されたCSVファイルを使って、ビットレートパターンの拡大・縮小可能なビットレートビューワーをmacOSショートカットで作成してみました。 さらに、ショートカットを Finderからファイル選択が可能な、クイックアクションとして動作するように設定することで 、複数のビットレートビューワー起動が可能となり、エンコーダの違いによるビットレートパターンの比較分析も容易です。
今回は、動画および音声ファイルの両方に対応するビットレートビューワーをmacOSショートカットで作成する手順を解説します。
使用PC環境:M1 MacBook Air:Version (Tahoe 26.3.1 )
macOSショートカットアプリ::Version 7.0
作成する「ビットレートビューワー」の基本仕様
- plotbitrateで生成されたCSVデータの「size」はフレームごとの転送サイズ(Byte)であるため、ビットレート(kbps)に変換する。
- 動画ファイルは、分析しやすくするため、フレームタイプ(I・P・B)ごとのビットレートを色分け(I:brown,P:green,B:blue)した縦棒グラフで表示する。
- 音声ファイルは、フレームタイプの区別がないので ? になる。 縦棒表示では視認性が低くなるので、ビットレートを折れ線グラフで表示する。
- macOSショートカットを Finderからファイル選択が可能な、クイックアクションとして動作するように設定する(複数ファイルの同時表示に対応)。
- plotbitrateで生成されたCSVデータは、後からNumbers(Excel)で再利用できるよう、デスクトップ上の「PlotBitrate-CSV」フォルダに保存する。
- ビューワーによるパターン表示は、拡大・縮小・移動が可能となるよう、インターラクティブに操作できるPythonグラフを使用する。
以上の基本仕様は、次節で説明するmacOSショートカットに必要なアクションを配置してプログラムすることで簡単に達成出来ます。
ビットレートビューワー|macOSショートカットの作成手順
macOSショートカット・アプリを起動して「ファイル」>「新規ショートカット」をクリックすると、まっさらなショートカット編集画面が現れます。 ここに必要なアクション①〜⑤を配置して行きます。 今回のショートカット名は[ PlotBitrate Viewer ]にしました。
アクション配置図
アクションの説明
事前設定:クイックアクションの設定を行います。 配置図の先頭に示す様に『クイックアクションから「ファイル」を受け取る』にします。
①アクション:シェルスクリプトを実行
以下のscriptを① にペーストします。
scriptの処理概要:
クイックアクション(ショートカットの入力)から受取ったファイルを拡張子で識別し、
動画または音声ファイルである場合:plotbitrateを用いてCSVファイルをデスクトップフォルダに保存します。 その後、pythonグラフへ引き渡すために、sizeをビットレート(kbps)に変換し、一時的なTMP.CSVファイルとして保存します。
動画または音声ファイル以外のファイルである場合は:「対象外のファイルです。」というテキストを出力します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# ========================= # ffprobe / plotbitrate の実行パス設定 # Homebrew や Python ユーザーローカルのパスを追加 # ========================= export PATH="/opt/homebrew/bin:$PATH" export PATH="/Users/ユーザー/Library/Python/3.9/bin/:$PATH" # ========================= # 入力ファイルの取得(macOSショートカットから) # ========================= input="ショートカットの入力 (ファイルパス)" #マジック変数プロパティでファイルパスを取得 ext="ショートカットの入力 (ファイル拡張子)" # 拡張子のみ取得 # 拡張子を小文字に統一(大文字混在対策) ext=$(echo "$ext" | tr 'A-Z' 'a-z') # ========================= # ファイル種別判定(動画 / 音声) # plotbitrateの -s オプション用 # ========================= case "$ext" in mp4|mkv|avi|mov|wmv|flv|webm|m4v) type="video" ;; mp3|wav|flac|aac|ogg|m4a|opus) type="audio" ;; *) type="OTHER" esac # 対象外ファイルは処理終了 if [ "$type" = "OTHER" ]; then printf "対象外のファイルです。" # if文アクションへメッセージを渡す else # ========================= # plotbitrate用CSV出力先の準備 # ========================= # 保存フォルダ作成(既にあってもエラーにならない) mkdir -p "/Users/mitsu/Desktop/PlotBitrate-CSV/" # ファイル名生成(例:sample[mp4]-PB.csv) name="${$(basename "$input")%.*}"["$ext"] # 出力CSVパス OUT="/Users/ユーザー/Desktop/PlotBitrate-CSV/"$name"-PB.csv" # ========================= # plotbitrate を実行して、フレーム単位のCSVを生成 # ========================= plotbitrate "$input" -f csv_raw -s "$type" -o "$OUT" # ========================= # size(Byte) → BitRate(kbps) 変換処理 # plotbitrate出力CSVを元に再計算 # ========================= # 一時ファイル(BitRate変換後のCSV) TMP="/tmp/bitrate_temp.csv" # CSV size → bitrate 変換処理 awk -F'[,\t ]+' ' BEGIN{ # 出力はカンマ区切り(CSV形式) OFS="," print "time","BitRate(kbps)","pict_type" } NR==1{next} # ヘッダー行スキップ { # 各列の取得(数値化) time = $1 + 0 size = $2 + 0 # Byte単位 pict = $3 # フレームタイプ(I/P/B/?) if(prev_time != ""){ # フレーム間の時間差(Δt) dt = time - prev_time if(dt > 0){ # ビットレート計算 # Byte → bit(×8)、秒で割る、kbps変換(/1000) bitrate = size * 8 / dt / 1000 # CSV出力(time, bitrate, pict_type) printf "%.6f,%.2f,%s\n", time, bitrate, pict } } # 次ループ用に前回timeを保存 prev_time = time } ' "$OUT" > "$TMP" # ========================= # 補足:TMPファイルはこの後、Pythonグラフ描画へ渡す # ========================= fi # 対象外ファイルの判定if文の終了 |
scriptポイント
5〜6行: ffprobe / plotbitrate の実行パスを設定設定しています。 予めFFmpegとplotbitrateがインストールしておく必要があります。 インストールの方法は、ここをクリックして参照してください。
11〜12行; マジック変数を指定しています。 マジック変数は、ここをクリックして参照してください。
20〜27行: case文で、動画・音声の拡張子から、videoかaudioかを判定し、plotbitrateの-s オプション に渡しています。 それ以外はOTHERになり、30行のif文で、「対象外のファイルです。」として処理終了します。
37〜47行: デスクトップのPlotBitrate-CSVフォルダにplotbitrateで生成されたCSVが保存されます。 CSVのファイル名は、動画又は音声ファイル名に”[拡張子]-PB”を付加しています。
②〜④アクション
①の「シェルスクリプトを実行」の結果(出力)が、②(if文)で、もし「対象外のファイルです。」と出力された場合は、③(アラート)を表示し OK が押されたら、④で、このショートカットを終了させます。 「対象外のファイルです。」で無かったら(つまり動画・音声ファイル)の場合は、継続して次の⑤アクションを続行します。
③(アラート)アクションの表示内容

⑤アクション:シェルスクリプトを実行
以下の Python3 scriptを⑤ にペーストします。 ビットレートに変換されたTMPファイル.CSVをPythonグラフで描画します。
scriptの処理概要:
ビットレートに変換された"/tmp/bitrate_temp.csv" を受取り、このCSVデータに基づいてグラフ化します。
CSVデータのpict_typeが、I、P、Bの場合:色分けした縦棒グラフを表示します。
pict_typeが、? の場合:折れ線グラフを表示します。
また、Pythonのmatplotlibライブラリで表示されるグラフウィンドウの左下のボタンを操作することで拡大・縮小・移動が可能です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import pandas as pd import matplotlib.pyplot as plt import matplotlib import os # 日本語フォント設定(macOS用) matplotlib.rcParams['font.family'] = 'Hiragino Maru Gothic Pro' # グラフタイトル用のパス Title_path = "ショートカットの入力 (ファイルパス)" #マジック変数で受取り # BitRateに変換された TMPファイル.CSVのパス csv_path = "/tmp/bitrate_temp.csv" # グラフを描画するCSVを指定 # CSV読み込み(カンマ区切り) カラム例:time, BitRate(kbps), pict_type df = pd.read_csv(csv_path) # ========================= # 基本統計値の算出 最大ビットレート(Peak)と平均ビットレート(Average) # ========================= max_val = df["BitRate(kbps)"].max() avg_val = df["BitRate(kbps)"].mean() # グラフ初期設定(サイズ指定) plt.figure(figsize=(10, 5)) # ========================= # フレームタイプ別に描画 I / P / B フレームは縦線で表示 # ========================= # Iフレーム(赤) df_I = df[df["pict_type"] == "I"] plt.vlines(df_I["time"], 0, df_I["BitRate(kbps)"], linewidth=0.8, color="brown", label="I") # Pフレーム(緑) df_P = df[df["pict_type"] == "P"] plt.vlines(df_P["time"], 0, df_P["BitRate(kbps)"], linewidth=0.8, color="green", label="P") # Bフレーム(青) df_B = df[df["pict_type"] == "B"] plt.vlines(df_B["time"], 0, df_B["BitRate(kbps)"], linewidth=0.8, color="blue", label="B") # ========================= # '?' フレーム(音声など) 折れ線グラフで表示 # ========================= df_B = df[df["pict_type"] == "?"] plt.plot(df_B["time"], df_B["BitRate(kbps)"], linewidth=0.8, color="navy", label="? audio") # 軸ラベル・タイトル・凡例 plt.xlabel("time (sec)") plt.ylabel("BitRate(kbps)") # ファイル名をタイトルに表示 basename = os.path.basename(Title_path) plt.title(f"{basename}\n [Frame Type別 ビットレート kbps]") plt.legend() plt.grid(True) # ========================= # 最大値・平均値ライン表示 # ========================= # 最大値(赤・破線) plt.axhline(max_val, linestyle="--", color="red", linewidth=1) # 平均値(黒・点線) plt.axhline(avg_val, linestyle=":", color="black", linewidth=1) # ラベル表示位置(右端付近) x_pos = df["time"].max() * 0.98 # 最大値ラベル plt.text(x_pos, max_val, f"Max: {int(max_val)} kbps", va="bottom", ha="right", fontsize=10, bbox=dict(facecolor="white", alpha=0.8, edgecolor="white")) # 平均値ラベル plt.text(x_pos, avg_val, f"Avg: {int(avg_val)} kbps", va="bottom", ha="right", fontsize=10, bbox=dict(facecolor="white", alpha=0.8, edgecolor="white")) # Y軸設定(0から開始) plt.ylim(bottom=0) # グラフ描画 plt.show() |
ファイルを選択して右クリックでクイックアクションからPlotBitrate Viewerを選択でビットレートグラフが表示できます❗️
完成したPlotBitrate Viewer の操作デモ(動画)をご覧ください。



