Skip to content

Instantly share code, notes, and snippets.

@hcmiya
Created August 30, 2017 16:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hcmiya/350edea7113dea2d9b3ac0d372422560 to your computer and use it in GitHub Desktop.
Save hcmiya/350edea7113dea2d9b3ac0d372422560 to your computer and use it in GitHub Desktop.
opuscommentのmanの生成元DocBook文書(リポジトリで管理する気は無い)
<!doctype reference public "-//OASIS//DTD DocBook V4.5//EN" [
<!-- 短い繰り返し -->
<!entity vcref "<citerefentry><refentrytitle>vorbiscomment<manvolnum>1</citerefentry>">
<!entity tagfile "<replaceable/tagfile/">
<!entity srcfile "<replaceable/srcfile/">
<!entity ocrev "2017-08-30">
<!entity ocver.Mm "1.4">
<!entity ocver.Mmp "&ocver.Mm;.2">
<!entity manfoot.rev "<refentryinfo><date/&ocrev;/</>">
<!entity manfoot.ver "<refmiscinfo>&ocver.Mmp;</>">
<!-- 長い繰り返し -->
<!entity gainopts "
<varlistentry>
<term><option>-g <replaceable/gain/</>
<listitem><para>出力ゲインをdBで指定する
<varlistentry>
<term><option>-s <replaceable/scale/</>
<listitem><para>出力ゲインをPCMサンプルの倍率で指定する。1で等倍。0.5で半分(コマンド内でdBに変換)
<varlistentry>
<term><option>-0</>
<listitem><para>出力ゲインを0にする
<varlistentry>
<term><option>-r</>
<listitem><para>出力ゲインの指定を内部の設定に対する相対値とする
<varlistentry>
<term><option>-1</>
<listitem><para>出力ゲインが内部形式にした時に0になる場合は±1/256dBを設定する
<varlistentry>
<term><option>-Q</>
<listitem><para>出力ゲイン値にQ7.8形式を使う
">
]>
<!-- DTD終わり。ここから本文 -->
<reference>
<referenceinfo>
<date/&ocrev;/
</>
<title/opuscomment &ocver.Mm;マニュアル/
<refentry>
&manfoot.rev;
<refmeta><refentrytitle>opuscomment<manvolnum>1
&manfoot.ver;</refmeta>
<refnamediv>
<refname>opuscomment
<refpurpose>Ogg Opusファイルの出力ゲインとタグを編集する
<refsynopsisdiv>
<cmdsynopsis>
<command/opuscomment/
<arg>-l</>
<arg>-i <replaceable/idx/</>
<arg>-DepQRUv</>
<arg choice=req>&srcfile;</>
</cmdsynopsis>
<cmdsynopsis>
<command/opuscomment/
<group choice=req><arg/-a/<arg/-w/</group>
<arg>-i <replaceable/idx/</arg>
<group><arg>-g <replaceable/gain/</><arg>-s <replaceable/scale/</><arg>-0</></>
<arg>-c &tagfile;</arg>
<arg rep=repeat>-t <replaceable/NAME=VALUE/</arg>
<arg rep=repeat>-d <replaceable>NAME<optional/=VALUE/</></>
<arg>-1DeQprRUv</>
<arg choice=req>&srcfile;</>
<arg><replaceable/output/</>
</cmdsynopsis>
<refsect1><title/説明/
<para>1つめの書式はタグ出力モードであり、OpusファイルのVorbis comment形式のタグを標準出力に出力する。
<para>2つ目の書式はタグ上書き・追記モードであり、標準入力から読み取ったVorbis comment形式のタグをOpusファイルに書き込む。オプションの後のファイルが1つの場合、元のファイルは編集結果によって置き換えられる。2つの場合は編集結果が別ファイルに出力され、元のファイルはそのまま残る。タグファイル指定のオプションがあれば標準入力を使わずそのファイルからタグを読み込む。タグを直接指定するオプションがあればそれを入力として扱う。ゲイン編集のオプションがあればタグ編集と同時にそれも行われる。
<para>いずれの書式でもゲイン出力のオプションの指定があればOpusファイルが持つ出力ゲインを標準エラー出力に出力する。
<refsect1><title/オプション/
<variablelist>
<varlistentry>
<term><option>-l</>
<listitem><para>タグ出力モード
<varlistentry>
<term><option>-a</>
<listitem><para>タグ追記モード
<varlistentry>
<term><option>-w</>
<listitem><para>タグ書き込みモード
<varlistentry>
<term><option>-i <replaceable/idx/</>
<listitem><para>多重化されたOggストリーム中の編集対象のOpusストリームを、Opus以外のものを除いた1起点の順番で指定する。動画ファイルが吹き替えや副音声などで複数の音声ストリームを持つという状況を想定している
<varlistentry>
<term><option>-R</>
<listitem><para>タグ入出力にUTF-8を使う。このオプションがない場合はロケールによる文字符号化との変換が行われる(&vcref;互換)
<varlistentry>
<term><option>-e</>
<listitem><para>バックスラッシュ、改行、復帰、ヌルにそれぞれ\\, \n, \r, \0のエスケープを使用する(&vcref;互換)
<varlistentry>
<term><option>-t <replaceable/NAME=VALUE/</>
<listitem><para>引数をタグとして追加する
<varlistentry>
<term><option>-c &tagfile;</>
<listitem><para>出力モード時、タグを&tagfile;に書き出す。書き込み・追記モード時、&tagfile;からタグを読み出す
<varlistentry>
<term><option>-d <replaceable>NAME<optional/=VALUE/</></>
<listitem><para>引数に一致するOpusファイル内のタグを削除する。<replaceable/VALUE/が省略された場合、<replaceable/NAME/が一致する全てのタグが削除される。<option/-U/が暗黙的に指定される
<varlistentry>
<term><option>-p</>
<listitem><para>METADATA_BLOCK_PICTUREの出力または削除をしない
<varlistentry>
<term><option>-U</>
<listitem><para>Opusファイル内のタグの項目名に小文字が含まれていた場合、大文字に変換する。他のソフトウェアで編集されたファイルのために用意されているオプションであり、opuscommentは編集入力のタグの項目名を常に大文字に変換する
<varlistentry>
<term><option>-V</>
<listitem><para>出力モード時、Opusファイル内のタグに対して書式の正当性を検証する
<varlistentry>
<term><option>-T</>
<listitem><para>編集入力が改行で終わっているか確認する
<varlistentry>
<term><option>-D</>
<listitem><para>出力モード時、Opusファイル内のタグを全て読み終わるまで出力しない。また<option/-V/を暗黙的に指定する。書き込みモード時、空の編集入力をエラーとする。また<option/-T/を暗黙的に指定する
&gainopts;
<varlistentry>
<term><option>-v</>
<listitem><para>出力ゲインの値を標準エラー出力に出力する
<!--
<varlistentry>
<term><option></>
<listitem><para>
-->
</variablelist>
<refsect1><title/環境変数/
<variablelist>
<varlistentry>
<term><varname/LANG/
<listitem><para>タグ内部形式のUTF-8とロケールの文字符号化方式との変換に影響を受ける
<varlistentry>
<term><varname/LC_NUMERIC/
<listitem><para>出力ゲイン編集に使う浮動小数点数の書式に影響を受ける
<varlistentry>
<term><varname/LC_MESSAGES/
<term><varname/NLSPATH/
<listitem><para>メッセージカタログの処理に関わる
<!--
<varlistentry>
<term><varname//
<listitem><para>
-->
</variablelist>
<refsect1><title/終了ステータス/
<para>Opusファイルの編集に成功した場合は<errorcode/0/、オプションや編集タグ入力の文法に誤りがあった場合は<errorcode/1/、Opusファイルのフォーマットに誤りがあった場合は<errorcode/2/、ファイル入出力などシステム起因のエラーが発生した場合は<errorcode/3/を返す。
<refsect1><title/文法/
<para>opuscommentで扱うタグ入出力の文法について、個々のレコードはvorbis commentの内部形式と同じで<parameter/NAME=VALUE/のようにキー名と値が<token/=/で繋がれていて、レコード同士は改行で区切られている。例えば
<informalexample>
<screen><computeroutput>TITLE=インターネット
ARTIST=荒川智則</></>
</>
<para>但し、<parameter/VALUE/はそれ自体に改行を含む可能性があり、opuscommentは2つの方法で改行をエスケープする。</>
<variablelist>
<varlistentry><term>1. opuscommentが定義する方法
<listitem><para>改行の次にタブが続いた場合、改行後の行は先頭のタブを除き前の行の値の続きとして扱う
<varlistentry><term>2. <option/-e/を用いた時のvorbiscommentとの互換のある方法
<listitem><para>バックスラッシュを使ったエスケープシーケンスで改行を表す
</variablelist>
<para>opuscommentではこのいずれかの改行のエスケープが常に適用されており、適切なオプション指定と編集があれば改行が欠落することはない。具体的に、次の内容を持つレコード:
<informalexample>
<variablelist>
<varlistentry><term>項目名
<listitem><simpara>COMMENT</>
<varlistentry><term>内容
<listitem><literallayout>荒川智則のライブ
2017-08-12録音</>
</variablelist>
</informalexample>
<para>これは1つ目のopuscommentの方法だと
<informalexample>
<screen><computeroutput>COMMENT=荒川智則のライブ<token/&lt;newline&gt;/
<token/&lt;tab&gt;/2017-08-12録音</></>
</>
<para>2つ目のvorbiscomment互換形式だと
<informalexample>
<screen><computeroutput>COMMENT=荒川智則のライブ\n2017-08-12録音</></>
</>
<para>となる。
<refsect1><title/例/
<example><title/基本/
<para>opuscommentをOpusファイル1つだけを引数に指定して起動すると、そのファイル内のタグを標準出力に出力する。
<screen>opuscomment some.opus</>
<para>Opusファイル内のタグを編集したい場合、その出力を好みのエディタで編集した後にopuscommentを書き込みモードで起動して標準入力に渡せば良い。この編集様式は&vcref;に倣っている。
<screen>opuscomment some.opus &gt;tags.txt
ed tags.txt
opuscomment -w some.opus &lt;tags.txt</>
<para>Ogg Opusには出力ゲインというヘッダ項目があり、それを変更することでエンコード後でも自在に音量を変更することが出来るという機能がコーデックの標準として付いている。opuscommentはその出力ゲインの編集に対応している。
<screen>
# 音量が大きいOpusファイルを-5.0dB分音を小さくさせる
opuscomment -g -5.0 loud.opus
# 出力ゲインが変更されたことをopusinfo(1)のPlayback gainという項目で確認できる
opusinfo loud.opus</>
</example>
<example><title/Ogg Vorbisからの移行/
<para>Ogg VorbisとOgg Opusはタグの内部形式が同じで、またopuscommentはvorbiscommentと互換のあるインターフェイスを実装しているため、次のコマンドを使えば容易にタグを移植できる。
<screen>vorbiscomment -Re music-01.oga |opuscomment -wRe music-01.opus</>
</example>
<example><title/Opusファイルの同時編集/
<para>シェルスクリプトの一般論として、1つのファイルをパイプを繋いで同時に編集しようとすると書き込みのタイミングにより内容が消えてしまうため、結果を一度別ファイルにリダイレクトしてリネームするという処理をするのが定石である。
<screen>sed 's/dog/cat/g' &lt;animal.txt &gt;animal.txt.1
mv -f animal.txt.1 animal.txt</>
<para>しかし、opuscommentはタグの読み込みが終わるまでOpusファイルを書き込み用として開かないため、フィルタの前後で同じファイルを開いていても同時に編集されることはなく内容が失われる事は無い。
<screen>
# 一時ファイルを作らなくてもsome.opusからDISCTOTALとDISCNUMBERタグを消す編集が意図通り適用される。
opuscomment -e some.opus |grep -vE '^DISC(TOTAL|NUMBER)=' |opuscomment -we some.opus</>
</example>
<refsect1><title/注意/
<refsect2><title/opuscomment方式のエスケープで編集する場合/
<para>エンコードのやり直しのために同じタグを別のOpusファイルにコピーするという状況を考える。この時、opuscomment同士を直接パイプで繋いでタグの受け渡しを行うことは安全である。
<informalexample>
<screen># 安全な例
opuscomment old.opus |opuscomment -w re-encoded.opus</>
</>
<para>しかし、行の削除を含む編集をするフィルタを挟むことは安全ではなくなる可能性がある。なぜなら、もし削除したいレコードが複数行からなっていた場合、その項目名を含む行だけ削除をすると残りの行が1つ前のレコードの続きと見做されてしまうからである。
<informalexample>
<screen># 安全ではない例
opuscomment old.opus |sed '/^COMMENT=/d' |opuscomment -w re-encoded.opus</>
</>
<para>これを防ぐためには、レコードが複数行に跨ることを考慮してフィルタを設計する必要がある。
<informalexample>
<screen># 複数行のレコードを考慮した削除の例1
opuscomment old.opus |sed '/^COMMENT=/{:loop; N; s/.*\n<token>&lt;tab&gt;</>//; t loop; D;}' |
opuscomment -w re-encoded.opus</>
</>
<para>より単純には、<option/-e/オプションのエスケープを使用することである。
<informalexample>
<screen># 複数行のレコードを考慮した削除の例2
opuscomment -e old.opus |sed '/^COMMENT=/d' |opuscomment -we re-encoded.opus</>
</>
<refsect2><title><token/NUL/の扱い</>
<para>opuscommentは文字「<token/NUL/」が入力された場合は一切エラーとする。もしOpus内のタグが<token/NUL/を含んでいた場合、出力モードで文字が途切れるだろう。これはvorbis commentがあくまでUTF-8テキストを格納するものなのでバイナリファイルが入力された時にテキストファイルが壊れてしまうという動作を意図的に発現させているためである。しかし必要ならば<option/-R/か<option/-e/いずれかのオプションを指定することで回避できる。
<refsect2><title>出力ゲインと<property/R128_TRACK_GAIN/、<property/R128_ALBUM_GAIN/の編集</>
<para>Opus仕様を定めた<citetitle pubwork=webpage/RFC 7845/によれば、出力ゲインを編集した場合、併せて<property/R128_TRACK_GAIN/、<property/R128_ALBUM_GAIN/の更新ないし削除をしなければならない(MUST)、とある。しかし、opuscommentはこの仕様に基く処理を実装しない。opuscommentの利用者はこの仕様を念頭に置いてゲイン調整の編集をスクリプトに組み込む必要がある。
<refsect1><title/関連項目/
<simplelist type=inline>
<member><citerefentry><refentrytitle>opusenc<manvolnum>1</citerefentry>
<member><citerefentry><refentrytitle>opusinfo<manvolnum>1</citerefentry>
<member><citerefentry><refentrytitle>opuschgain<manvolnum>1</citerefentry>
<member><citerefentry><refentrytitle>vorbiscomment<manvolnum>1</citerefentry>
<member><citerefentry><refentrytitle>metaflac<manvolnum>1</citerefentry>
<member><citerefentry><refentrytitle>op_set_gain_offset<manvolnum>3</citerefentry>
</simplelist>
<refentry>
&manfoot.rev;
<refmeta><refentrytitle>opuschgain<manvolnum>1
&manfoot.ver;</refmeta>
<refnamediv>
<refname>opuschgain
<refpurpose>Ogg Opusファイルの出力ゲインとR128ゲインタグを更新
<refsynopsisdiv>
<cmdsynopsis>
<command/opuschgain/
<arg>-i <replaceable/idx/</arg>
<group choice=req><arg>-g <replaceable/gain/</><arg>-s <replaceable/scale/</><arg>-0</></>
<arg>-1Qr</>
<arg choice=req>&srcfile;</>
<arg><replaceable/output/</>
</cmdsynopsis>
<refsect1><title/説明/
<para>opuschgainは、Ogg Opusファイルの出力ゲインの編集をする。もし&srcfile;が<property/R128_TRACK_GAIN/・<property/R128_ALBUM_GAIN/タグを持つ場合、それを併せて更新する。この2つのタグの情報については<citetitle pubwork=webpage/RFC 7845 §5.2.1./を参照。
<refsect1><title/オプション/
<variablelist>
&gainopts;
<varlistentry>
<term><option>-i <replaceable/idx/</>
<listitem><para>多重化されたOggストリーム中の編集対象のOpusストリームを、Opus以外のものを除いた1起点の順番で指定する。動画ファイルが吹き替えや副音声などで複数の音声ストリームを持つという状況を想定している
</variablelist>
<refsect1><title/関連項目/
<simplelist type=inline>
<member><citerefentry><refentrytitle>opuscomment<manvolnum>1</citerefentry>
</simplelist>
<para>opuschgainはopuscommentがR128関連タグを修正しない動作を補完するためにopuscommentと同時に配布されるラッパースクリプトである。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment