Coder Social home page Coder Social logo

aoirint / matvtoolpy Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 205 KB

マルチオーディオトラック動画ファイルを取り扱うためのコマンドラインツール / A command line tool to handle a multi audio track video file

License: MIT License

Python 94.14% Dockerfile 5.86%

matvtoolpy's Introduction

matvtoolpy / MultiAudioTrackVideoToolPy

A command line tool to handle a multi audio track video file.

マルチオーディオトラック動画ファイルを取り扱うためのコマンドラインツール

インストール

基本的にFFmpegのラッパーです。別途FFmpegのインストールが必要です。 FFmpeg 4.2(Ubuntu 20.04の標準バージョン)および4.4(Ubuntu 22.04の標準バージョン)をサポートしています。

matvtool本体は、以下からダウンロード・インストールできます。 Pythonパッケージとして導入する場合、Python 3.11をサポートしています。

用途

OBS Studioの録画機能やGeForce Experienceの録画機能などで作成した、マルチオーディオトラック動画ファイルを、 マルチオーディオトラックの状態を保ったまま簡易に編集し、後に高度な動画編集ソフトで使う素材として使いやすい形に整えるためのツール。

用例

slice: クリップの作成

再エンコードしないため、高速ですが時間精度が低いです。 長時間の録画をおおまかに分割する用途を想定しています。 フレーム単位でクリップしたい場合、後段の動画編集ソフトで改めて加工してください。

matvtool slice -ss 00:05:00 -to 00:10:00 -i input.mkv output.mkv

crop_scale: 切り取り・拡大縮小

-vcodec/--video_codecオプションで出力映像コーデックを指定できます(未指定時は既定のエンコーダを使用)。

# 左上1600x900を切り取って、1920x1080に拡大
matvtool crop_scale -i input.mkv --crop w=1600:h=900:x=0:y=0 --scale 1920:1080 output.mkv

# 右下1600x900を切り取って、1920x1080に拡大
matvtool crop_scale -i input.mkv --crop w=1600:h=900:x=iw-ow:y=ih-oh --scale 1920:1080 output.mkv

# 左上1600x900を切り取って、1920x1080に拡大、libx264でエンコード
matvtool crop_scale -i input.mkv --crop w=1600:h=900:x=0:y=0 --scale 1920:1080 -vcodec libx264 output.mkv

# 左上1600x900を切り取って、1920x1080に拡大、nvenc_h264でエンコード
matvtool crop_scale -i input.mkv --crop w=1600:h=900:x=0:y=0 --scale 1920:1080 -vcodec nvenc_h264 output.mkv

# 左上1600x900を切り取って、1920x1080に拡大、nvenc_hevcでエンコード
matvtool crop_scale -i input.mkv --crop w=1600:h=900:x=0:y=0 --scale 1920:1080 -vcodec nvenc_hevc output.mkv

find_image: 画像の出現時間・出現フレームを検索

動画のスナップショットやクロップ画像を使用して、出現時間・出現フレームを検索します。 特定シーンの頭出しやチャプターを作成する用途を想定しています。 確実・正確に検出できるとは限りません。 出力は、VSCodeのマルチカーソル機能やseqコマンドなどを使って手動処理することを想定しています(試合1~試合10までの連番文字列生成:seq -f "試合%g" 1 10)。

sliceと同様のオプションで検索範囲の時間を指定できます。--fpsオプションで比較処理におけるフレームの読み飛ばしができます(コーデックにおけるフレーム間予測の関係で、全フレームのデコードは発生すると思われるため、デコード処理時間が支配的な場合はあまり意味がないと思われます)。 出力は、内部処理における時間・フレームと、入力動画における時間・フレームが併記されます。

-icrop/--input_video_cropオプション、-refcrop/--reference_image_cropオプションで、入力動画や参照画像の一部を使用した検索ができます。値はcrop_scale--cropオプションと同様です。 特定のアイコンが含まれることがわかっているが、フレーム中の他の部分が大きく違うケースの検索に有用です。

-it/--output_intervalオプションで、連続出現時の出力を抑制できます。手動処理を減らすためのオプションです。 例えば、-it 10を指定すると、前回出現してから10秒間のフレームで再び出現を検出しても、ログ出力しません(YouTubeのチャプター機能では、最小チャプター間隔は10秒)。

-p, --progress_typeオプションで、処理の進捗状況の出力方法を変更できます。 値は、tqdm 標準エラー出力・インタラクティブシェル用(デフォルト)、plain 標準エラー出力・逐次出力、none 出力なし、が利用できます。

処理に時間のかかる長い動画を入力するときは、teeコマンドなどで出力を永続化したり、tmuxコマンドなどでバックグラウンド処理したりすると便利です。うまく出力が表示されないときは、一時的に環境変数PYTHONUNBUFFERED=1を設定すると改善するかもしれません。

# reference.pngに一致するフレームを検索
matvtool find_image -i input.mkv -ref reference.png

# 10 FPSでreference.pngに一致するフレームを検索(フレームの読み飛ばしによる高速化を意図)
matvtool find_image -i input.mkv -ref reference.png --fps 10

# 左上1600x900を使用してreference.pngに一致するフレームを検索
matvtool find_image -i input.mkv -icrop w=1600:h=900:x=0:y=0 -ref reference.png -refcrop w=1600:h=900:x=0:y=0

# 最小10秒間隔で同上、10 FPS、出力永続化
PYTHONUNBUFFERED=1 matvtool find_image -i input.mkv -icrop w=1600:h=900:x=0:y=0 -ref reference.png -refcrop w=1600:h=900:x=0:y=0 --fps 10 -it 10 | tee chapters.txt

audio: オーディオトラック一覧の確認

matvtool audio -i input.mkv

select_audio: オーディオトラックを選択して新規動画ファイルとして出力

matvtool select_audio -i input.mkv --audio_index 2 3 -- output.mkv

開発

Python 3.11を使って開発しています。

依存関係

依存関係の管理にPoetryを使っています。

# Pythonパッケージを追加
poetry add pydantic
poetry add --group dev pytest

matvtoolpy's People

Contributors

aoirint avatar dependabot[bot] avatar

Stargazers

 avatar

Watchers

 avatar

matvtoolpy's Issues

開発環境のPythonバージョンをPython 3.11に固定する

Pythonバージョン対応のメンテナンスコストを下げるため、開発環境およびPythonパッケージとして導入する場合に、Python 3.11以上を要求するようにしたいです。

最低動作バージョンは、メンテナンスを続ける限り、適宜更新する予定です。

GeForce Experienceの録画機能が出力するmp4ファイルのオーディオトラック名が取得できない

GeForce Experienceの録画機能が出力するmp4ファイルは、

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'hoge.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2022-08-22T08:33:04.000000Z
    date            : 2022
  Duration: 00:00:27.53, start: 0.000000, bitrate: 14036 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, smpte170m), 1920x1080 [SAR 1:1 DAR 16:9], 13655 kb/s, 51.14 fps, 60 tbr, 90k tbn, 120 tbc (default)
    Metadata:
      creation_time   : 2022-08-22T08:33:04.000000Z
      handler_name    : VideoHandle
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 195 kb/s (default)
    Metadata:
      creation_time   : 2022-08-22T08:33:04.000000Z
      handler_name    : SoundHandle
    Stream #0:2(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 174 kb/s (default)
    Metadata:
      creation_time   : 2022-08-22T08:33:04.000000Z
      handler_name    : SoundHandle

のように、Metadataにtitleが含まれていない。
他の場所に記録されているか・読みだせるかを調べて対応したい。

ValueError: could not convert string to float: '0.007000side_data,H.26[45] User Data Unregistered SEI message'

$ ffprobe -version
ffprobe version 4.4.2-0ubuntu0.22.04.1

以下のようなエラーが起きる動画ファイルがある。

Traceback (most recent call last):
  File "{PYTHON_VENV_DIR}/bin/matvtool", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "{PYTHON_VENV_DIR}/lib/python3.11/site-packages/aoirint_matvtool/scripts/cli.py", line 439, in main
    args.handler(args)
  File "{PYTHON_VENV_DIR}/lib/python3.11/site-packages/aoirint_matvtool/scripts/cli.py", line 168, in command_find_image
    start_timedelta = get_real_start_timedelta_by_ss(video_path=input_video_path, ss=ss)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "{PYTHON_VENV_DIR}/lib/python3.11/site-packages/aoirint_matvtool/util.py", line 113, in get_real_start_timedelta_by_ss
    for output in ffmpeg_key_frames(
  File "{PYTHON_VENV_DIR}/lib/python3.11/site-packages/aoirint_matvtool/key_frames.py", line 47, in ffmpeg_key_frames
    seconds = float(match.group(1).strip())
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: could not convert string to float: '0.007000side_data,H.26[45] User Data Unregistered SEI message'

FFprobeの出力が以下のように壊れていることが原因。

$ ffprobe -hide_banner -skip_frame nokey -select_streams v -show_frames -show_entries frame=pkt_pts_time -of csv video.mp4
frame,0.007000side_data,H.26[45] User Data Unregistered SEI message

本来は、以下のように出力されるのが正しいはず。

$ ffprobe -hide_banner -skip_frame nokey -select_streams v -show_frames -show_entries frame=pkt_pts_time -of csv video.mp4
frame,0.007000,side_data,H.26[45] User Data Unregistered SEI message

この不具合は、FFmpeg側(FFprobe側)ですでに修正されているが、Ubuntu 22.04の標準パッケージのFFmpegには、少なくともまだポートされていない。

こういった動画ファイルでも動作するようにしたい。

FFmpeg 4.4でStream行のパースに失敗する

  • Ubuntu 20.04: FFmpeg 4.2
  • Ubuntu 22.04: FFmpeg 4.4

FFmpeg 4.4になって、標準エラー出力のフォーマットが一部変わっている。

find_imageサブコマンドにおいて、以下のようなエラーが発生する。

Traceback (most recent call last):
  File "/home/user/.pyenv/versions/3.11.3/bin/matvtool", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/user/.pyenv/versions/3.11.3/lib/python3.11/site-packages/aoirint_matvtool/scripts/cli.py", line 361, in main
    args.handler(args)
  File "/home/user/.pyenv/versions/3.11.3/lib/python3.11/site-packages/aoirint_matvtool/scripts/cli.py", line 147, in command_find_image
    input_video_fps = ffmpeg_fps(input_path=input_video_path).fps
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.pyenv/versions/3.11.3/lib/python3.11/site-packages/aoirint_matvtool/fps.py", line 14, in ffmpeg_fps
    input_video = ffmpeg_get_input(input_path=input_path)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.pyenv/versions/3.11.3/lib/python3.11/site-packages/aoirint_matvtool/inputs.py", line 119, in ffmpeg_get_input
    input_metadata_lines = input_lines[0:stream_line_indexes[0]]
                                         ~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

これは、次のようなFFmpegの標準エラー出力の行(Stream行)のインデント数が、4から2に変更されているためと思われる。

Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 60 fps, 60 tbr, 1k tbn, 120 tbc
$ ffmpeg -version
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)

(略)

$ ffmpeg -hide_banner -i 2023-07-23_22-06-42.mkv
Input #0, matroska,webm, from '2023-07-23_22-06-42.mkv':
  Metadata:
    ENCODER         : Lavf60.3.100
  Duration: 02:16:25.62, start: 0.000000, bitrate: 5459 kb/s
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 60 fps, 60 tbr, 1k tbn, 120 tbc
    Metadata:
      DURATION        : 02:16:25.617000000
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp
    Metadata:
      title           : Mixed Audio
      DURATION        : 02:16:25.557000000

(略)
  • 対応方針1. FFmpeg 4.2のサポートをやめ、インデント数を2に固定、FFmpeg 4.4のみ対応とする
  • 対応方針2. インデント数を2または4とし、FFmpeg 4.2および4.4対応とする

linter/formatterを導入する

linter/formatter(flake8/black)を導入して、コードを均一化し、メンテナンスコストを下げたいです。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.