web-dev-qa-db-ja.com

非標準のアスペクト比のビデオファイルをDVDに書き込む

ビデオファイルをDVDに書き込むための標準的なUnixコマンドラインアプローチは次のとおりです(仮定)

# 1. First use ffmpeg to convert to an mpg file.

ffmpeg -i input.m4v -target ntsc-dvd output.mpg

# 2. now do the authoring

dvdauthor --title -o dvd -f output.mpg
dvdauthor -o dvd -T

注意: --titleDVDのタイトルを設定します。-T目次を設定します。上記の両方のコマンドで、-oスイッチは実際のDVDではなくディレクトリを参照しています。

# 3. roll the .mpg file into an ISO file
genisoimage -dvd-video -o dvdimage.iso dvd

最後に、結果のISOファイルをDVDブランクに書き込みます。信頼性の高いブラセロを使用しています。

ただし、この方法は、非標準のアスペクト比ではうまく機能しません。 DVD形式は、受け入れるアスペクト比の指定に関して非常に厳格です。 dvdauthorが次のようなことを言った場合、この問題があるかどうかがわかります

WARN: unknown mpeg2 aspect ratio 1

非標準のアスペクト比を処理するようにこのメソッドを変更する良い方法は何ですか?

更新:Anthonyfoの非常に徹底的で明確な答えに感謝します。これが、この厄介な問題の答えを見つけようとしている人々に役立つことを願っています。ネット上でこれについて他に明確な説明はありません。

7
Faheem Mitha

基本的なアプローチは、ビデオに黒い境界線を追加して、DVDで許可されているアスペクト比の1つに収まるようにすることです。

TLDR:までスキップして結論を​​出します。

いくつかの定義

ただし、最初に、いくつかの異なることを定義する必要があります。

  • アスペクト比は、単に何かの幅を高さで割ったもので、通常は分数で表されます。多くの場合、従来のスラッシュはコロンに置き換えられます。代わりに4:3と記述します。 43。これらは10進数(1.333…)で表される場合があります。これらはすべて等しいので、8:6、12:9、16:12などと呼ぶこともできます。または1.333:1(十分な3を書くことができれば等しい)。
  • Adisplayアスペクト比(DAR)は、実際のディスプレイ(TVなど)のアスペクト比です。 )。一般的なディスプレイは、名目上4:3または16:9です。
  • Astorageアスペクト比(SAR)は、幅と高さの比率(ピクセル単位)です。保存された画像またはビデオ。たとえば、NTSC DVDビデオの最大値は720x 480( "Full D1")で、SARは1.5:1です。
  • ピクセルアスペクト比は、保存された画像内の1つのピクセルのアスペクト比です。ビデオでは、ピクセルは常に正方形ではありません。非正方形の場合、通常、高さよりも幅が狭くなります。

上記の3つの間に単純な数学的関係があります:SAR×PAR = DAR。例として、720:480 * 8:9 = 4:3。これは、フル解像度でDVDに収められた4:3ディスプレイのビデオになります。

別の複雑さ

アナログテレビにはピクセルがありません。代わりに、それは連続的に変化する信号を持っています。その信号の特定の部分がディスプレイの各行に投影されることになっている場合、たとえば次の行に移動できるようにするための非アクティブな時間があります。ただし、テレビが異なれば、各回線の表示量もわずかに異なります。これは、テレビの寿命全体にわたって、またはテレビがウォームアップしたときにも変化する可能性があります。

DVDには、左端と右端の8ピクセルを使用しないように記載されています。したがって、720のうち、704が使用されることになっています。両側の8ピクセルは黒で塗りつぶされているはずです。指定されたPARはこの10:11です。

もちろん、デジタル機器に慣れている人はこれをばかげていると思います(礼儀正しい会社にふさわしい言葉を使うため)。また、多くの商用DVDリリースでは、実際には720ピクセルすべてが使用されており、10:11 PARを期待しているものもあれば、8:9を期待しているものもあります。 [または16:9DARの場合も同様]。ほとんどのハードウェアDVDプレーヤーは10:11を使用しますが、もちろんTVの設定にも依存します。

概要

すべてのピクセルを表示したいビデオから始める場合は、8pxの黒いバーを使用して704x480(SAR 22:15)に合わせるとよいでしょう。切り取られた側面に問題がない場合は、720x480全体を使用できます。いずれにせよ、10:11(4:3のDAR)または40:33(16:9のDAR)のいずれかのPARを取得するために必要に応じてビデオを拡大縮小し、720x480フレーム全体よりも小さい場合は黒を追加する必要があります。バー。

実際にやってる

ありがたいことに、ffmpegはこれを行うことができます。非公式のffmpegサポートフォーラムで、 ks_kalvanはffmpegビデオフィルターチェーンを提供しています 16:9 DARをターゲットにしています:

_-filter:v "scale='w=min(720,trunc((480*33/40*dar)/2+0.5)*2):h=min(480,trunc((720*40/33/dar)/2+0.5)*2)',pad='w=720:h=480:x=(ow-iw)/2:y=(oh-ih)/2',setsar='r=40/33'"
_

それはどのように機能しますか‽

そこには、scalepad、およびsetsarの3つのフィルターがあることに注意してください。最後のものが最も単純なので、最後から順番にそれぞれを取り上げます。

最後のフィルターは、ドキュメント( `man ffmpeg-filter)をチェックして、この罵倒的な削除行を見つけるまで混乱します:" "setsar"フィルターはサンプル(別名ピクセル)アスペクトを設定しますフィルタ出力ビデオの比率。」つまり、実際にはPARを40:33に設定しています。これは、上記で使用したいと言った値です。

padフィルターは黒い境界線を追加します。ドキュメントによると、owは出力幅(つまり、_w=720_部分からの720)、oh出力の高さ(つまり、_h=480_部分からの480)。 iwihは、それぞれ入力の幅と高さです。 ow-iwは、幅に追加するピクセル数です(同様に oh-ih高さ); 2で割ると、その半分が画像の両側に配置されます。言い換えれば、私たちは絵の中心にいます。

scaleフィルターはビデオのサイズを変更します。 _w=_オプションは新しい/出力幅を指定し、_h=_オプションは高さを指定します。繰り返しますが、これは表現ですが、より複雑です。幅と高さの式は同じですが、高さと幅が入れ替わっています。幅(_w=_)の式を調べてみましょう。

  • 関数と演算子は_man ffmpeg-util_に記載されています。正の数の場合、trunc(x+0.5)は、ffmpegにはない整数に丸めるトリックです。

  • そのtrunc(x+0.5)トリックに基づいて、trunc(x/2+0.5)*2があります。もちろん、x/2は半分のxを与えます。次に、切り捨てはそれを最も近い整数に丸めます。それを2倍にすると、最も近い偶数が得られます。

  • "W"を使用します。実際のコマンドは720を使用します。これがピクセル単位の最終出力幅です。同様に、480(最終出力高さ)の代わりに"H"。 40/33の代わりに、"PAR"がターゲットピクセルのアスペクト比です。また、PAR⁻¹はPARの逆数、つまり33/40です。

  • darはffmpeg変数です。入力動画のDARです。

  • これを理解するための重要なことは、真ん中の計算です。ここでは、"H"×dar÷"PAR"の計算があります。 darは元のビデオのw/hの表示であることを忘れないでください。したがって、ターゲットの幅(ピクセル単位)にdarを掛けると、ターゲットの高さ"H"と正方形のピクセルも含むようにビデオをスケーリングした場合の幅がわかります。 PARで除算すると、実際に使用している非正方形ピクセルの幅に変換されます。

_min(«W»,               # take the minimum [lesser of] target width and...
  trunc(               # the truncation of (round to integer towards 0)
    («H»*«PAR⁻¹»*dar)  # calculate the wanted output width, see note above
    / 2 + 0.5) * 2     # and get the nearest even number to that
))
_

例:ディスプレイのアスペクト比が16:9の1280 x720ピクセルのビデオを撮影するとします。真ん中から:

  1. "h"*"PAR⁻¹"* dar = 480 * 33/40 * 16/9 = 704。
  2. 704/2 = 352。
  3. trunc(352 + 0.5)= 352
  4. 352 * 2 = 704
  5. min(720、704)= 704

これは、16:9ディスプレイでの16:9ビデオに期待されるように、使用可能な全幅(つまり、8pxの使用不可能な領域を除く)です。

そして、高さでそれを行うと、490が得られます。これは、min()のおかげで480に保持されます。しかし、実際には、720ではなく704(使用可能な幅)を使用したかったことを示しています。 480.したがって、そこには小さなバグがあり、小さな(そしておそらく知覚できない)歪みを引き起こしているように見えます。それは以下で修正されていると私は信じています。

結論として

_ffmpeg -i YOUR-FILE-HERE \
  -filter:v "scale='w=min(720,trunc((480*33/40*dar)/2+0.5)*2):h=min(480,trunc((704*40/33/dar)/2+0.5)*2)',pad='w=720:h=480:x=(ow-iw)/2:y=(oh-ih)/2',setsar='r=40/33'" \
  -target ntsc-dvd YOUR-OUTPUT-HERE.mpg
_

注:古いffmpegには_-filter:v_がありません。代わりに(未テスト)_-vf_を試すか、 ffmpeg.org から新しい静的ビルドをダウンロードすることをお勧めします。

6
derobert