それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

動画の音声・動画ストリーム情報をJSONで受け取るffprobe json オプション

事の発端:ファイル名変換をミスった

この動画なんだっけ?wmv?avi? mpegts ?

ファイル名の変換をミスった。拡張子がトンだ。もうしにたい。仕方ないのでコーデック情報見ながら各種データの拡張子を探ることに

動画のストリーム情報の解析がめんどくさい。

ffmpeg で動画の情報を見るには ffprobe を使う。

ffprobe -i movie.mov 

まぁこれだけでも見るだけなら 標準エラーにffmpeg と同じ情報が出てきてログ見たらわかるんだけど。もっと手軽にほしいところだけ見たいな的な。

ネット見てたら、ffmpeg/ffprobe のエラーストリームへログをgrep してたりしてたいへんだ。

JSON で取り出す

-print_format json

ffprobe には show_format があってJSONでストリーム情報を取り出せる。

ffprobe -i movie.mov -show_streams -print_format json

これで、ストリーム情報を取り出せる。

うるさいログを黙らせる。

サポートしてるフォーマットとかの情報がうるさいので黙らせる。-loglevel quietで指定する。

ffprobe -i movie.mov -loglevel quiet -show_streams -print_format json

-print_format json jq を組み合わせる。

ここまで来たら後は楽ちん。 jq と組合あせて戦う。

takuya@Desktop$ ffprobe  -loglevel quiet -show_streams -print_format json "$f" | jq '.streams[] | {"index":.index,"codec_type":.codec_type,"codec_name":.codec_name}  '  -r
{
  "index": 0,
  "codec_type": "audio",
  "codec_name": "aac"
}
{
  "index": 1,
  "codec_type": "video",
  "codec_name": "h264"
}
{
  "index": 2,
  "codec_type": "data",
  "codec_name": null
}
{
  "index": 3,
  "codec_type": "data",
  "codec_name": null
}
takuya@Desktop$

動画のコーデック情報を取り出す。

ffprobe  -loglevel quiet -show_streams -print_format json "$i" | jq .streams[0].codec_name  -r

最後にこれを関数にする。

function ffmpeg_show_video_codec()
    f=$1
    ffprobe  -loglevel quiet -show_streams -print_format json "$f" | jq .streams[0].codec_name  -r
}

コレで行けそうですね。

追記1 XML + XPATHの方が簡単かも

json と jq はどうしても煩雑なので、 XML+XPATH のほうが楽だった。

XML で出力する -print_format xml

XML で出力してXPATHの方が // の省略記法があるので圧倒的に楽

ffprobe /Users/takuya/.Desktops/2017-02-10/IMG_4046.MOV-1.mov -loglevel quiet -show_streams -print_format xml | xpath '//stream/@codec_name'

やっぱりJSONめんどくさいんだよ。読みやすいけど、コードが煩雑。廃れてほしい。*1

追記 XML / JSON 以外のフォーマット

などがある

追記 他に見れるもの

formats 以外に見れるものもある。

ffprobe の man を眺めているとアレコレあるみたい

       -show_data
       -show_data_hash algorithm
       -show_error
       -show_format
       -show_format_entry name
       -show_entries section_entries
       -show_packets
       -show_frames
       -show_streams
       -show_programs
       -show_chapters

時間無くて調べきれない。-show_programs 番組のprogram_id などが見れる TS のストリーム情報などはコッチ見た方がいいのかな。

追記

動画の拡張子を wmv / mp4 にわける。

#!/usr/bin/env bash
for i in ./movies/* ; do
  name=$(ffprobe  -loglevel quiet -show_streams -print_format json "$i" | jq .streams[0].codec_name  -r)
  echo $name $i
  case "$name" in
    wmv*)
      :
      echo mv "$i" "${i/.*/.wmv}"
      # mv "$i" "${i/.*/.wmv}"
      ;;
    h264|aac|mpeg4)
      :
      echo mv "$i" "${i/.*/mp4}"
      ;;
  esac

done


覚えにくいので、bash alias や function にしてコマンドにした。

alias ffmpeg_info_json ='$ ffprobe -loglevel quiet -show_streams  -print_format json -i '

*1: 配列とオブジェクトがどちらも入るのがより煩雑さを加速してる感じがある。 XMLの子ノードと属性問題はあるけど、XPATHではあまり区別なく使いやすい。