ffmpegでDVD-Video用のmpeg2動画を作成する方法

個人的メモです。所用で必要になったので…

ffmpeg -i 入力動画or画像 -target ntsc-dvd -vcodec mpeg2video -s 720x480 -r 29.97 -aspect 16:9 出力動画名.mpg

・-aspectは4:3でも可
・画像ビットレートは9600kを超えないこと。
・出力ファイルを調整(画質を落とす)する場合は、-vcodecの前に -b 5000k 等を加える(数字が小さいほうが画質が悪い)
・音有りの場合は、 出力動画名.mpg の前に、-acodec aac -ab 192000 -ac 2 等を加える。
・入力が静止画の連番であったり、フレームレートが違う場合等は、-iの前に -r 入力側フレームレートとすること。
・-r が非整数の時、分数表記の方が誤差が出ないため、小数の必要がない場合は分数にする。

DVD Styler を使えば、↑で作った動画を再変換なしに直接DVDに焼ける様子。

TclTk + [Incr Tcl] + [Incr Tk] + [Incr Widgets] + TclVfs + Metakit をVisualC++を使ってソースから導入するメモ 続き

前のエントリの書ききれなかった続き


* 7. Incr Widgetsのインストール
-7.1. VisualStudio2008コマンドプロンプトでwork/iwidgets4.0.1/winにcdで移動
-7.2. nmake -f makefile.vc install INSTALLDIR=..\..\inst

* 8. TclVfsのコンパイルとインストール
-8.1. VisualStudio2008コマンドプロンプトでwork/tclvfs-20080503/winにcdで移動
-8.2. nmake -f makefile.vc TCLDIR=..\..\tcl8.5.10 OPTS=static,threads
-8.3. nmake -f makefile.vc TCLDIR=..\..\tcl8.5.10 OPTS=threads
-8.4. nmake -f makefile.vc install OPTS=static,threads INSTALLDIR=..\..\inst
-8.5. nmake -f makefile.vc install OPTS=threads INSTALLDIR=..\..\inst

* 9. metakitのコンパイルとインストール
metakitのmksrc.slnをVisual C++ 2008で開く
-9.1. プロジェクトファイルの編集
各プロジェクトの
・全般 - 出力ディレクトリ、中間ディレクト
C/C++ - プリコンパイル済ヘッダ
C/C++ - 出力ファイル - ASMリスト、オブジェクトファイル名、プログラムデータベースファイル
(mklib以外)
・リンカ - プログラムデータベースファイルの作成、マップファイル名
(mklibのみ)
・ライブラリアン - 出力ファイル
 でmsvc70と書かれた部分をmsvc90に書き換える。

mktclの追加のインクルードディレクトリと、追加のライブラリディレクトリのC:\tclとなっている場所を、workの場所に書き換える
mktclの追加の依存ファイルのtclstub84.libをtclstub85.libに書き換える(tcl85系を使いたい場合)

-9.2. mkpython以外をコンパイル
-9.3. pkgIndex.tclの作成
tclshかwishを起動して、cdでmetakitのbuildsフォルダまで移動し、pkg_mkIndexコマンドを実施
-9.4. インストール inst\lib\metakit2.4フォルダを作成してmk4tcl.dllとpkgIndex.tclをそのフォルダにコピー

TclTk + [Incr Tcl] + [Incr Tk] + [Incr Widgets] + TclVfs + Metakit をVisualC++を使ってソースから導入するメモ

* 1. ソースのダウンロード
-1.1. TclとTkのソースをダウンロード
-1.2. IncrTclのソースをダウンロード (3.4.1と3.2.1をダウンロード)
-1.3. IncrWidgetsのソースをダウンロード (とりあえず4.0.1でチャレンジ)
-1.4. TclVfsのソースをダウンロード
-1.5. Metakitのソースをダウンロード
* 2. ダウンロードしたアーカイブを展開
作業のベースとなるディレクトリを work、導入先を work / inst とする。
work
/ tcl8.5.10 / winとかunixとか...
/ tk8.5.10 / winとかunixとか...
/ itcl3.2.1 / itclとかitkとか...
/ iwidgets4.0.1 / winとかdocとかconfigureとか...
/ tclvfs-20080503 / winとかmacとか...
/ metakit-2.4.9.7 / winとかunixとか...

itcl3.2.1/itclの中身を消して、itcl3.4.1の内容を書き込む

* 3. Tclのコンパイルとインストール
-3.1. VisualStudio2008コマンドプロンプトを開き、work/tcl8.5.10/winにcdで移動
-3.2. nmake -f makefile.vc OPTS=static,threads
-3.3. nmake -f makefile.vc OPTS=threads
このあたりのオプション設定はお好みに合わせて適宜選択
makefile.vcの中にオプション一覧が書いてあります。
-3.4. nmake -f makefile.vc install OPTS=static,threads INSTALLDIR=..\..\inst
-3.5. nmake -f makefile.vc install OPTS=threads INSTALLDIR=..\..\inst

* 4. Tkのコンパイルとインストール
-4.1. VisualStudio2008コマンドプロンプトでwork/tk8.5.10/winにcdで移動
-4.2. nmake -f makefile.vc TCLDIR=..\..\tcl8.5.10 OPTS=static,threads
-4.3. nmake -f makefile.vc TCLDIR=..\..\tcl8.5.10 OPTS=threads
オプション設定は恐らくtclに合わせる必要あり。
-4.4. nmake -f makefile.vc install OPTS=static,threads INSTALLDIR=..\..\inst
-4.5. nmake -f makefile.vc install OPTS=threads INSTALLDIR=..\..\inst

* 5. IncrTclのコンパイルとインストール
-5.1. VisualStudio2008コマンドプロンプトでwork/itcl3.2.1/itcl/winにcdで移動
-5.2. copy ..\..\tcl8.5.10\win\nmakehlp.exe .
-5.3. IncrTclのmakefile.vcを一部編集
・20行目くらいにある!include "..\..\rule.vc"の次の行に!include "..\..\pkg.vc"を追加
・29行目くらいにあるITCL_DOTVERSIONを設定する処理が書かれている!if から !endifまでのブロック全てをコメントアウト(pkg.vcに書かれている設定を生かす)
・ファイル内の全ての$(_INSTALLDIR) を $(INSTALLDIR)に置換する
・IncrTclのmakefile.vcの
#---------------
# Compile flags
#--------------- の行から!if $(TCL_INCLUDES)の前の行までの内容を消して、同じ場所に
tcl8.5.10のmakefile.vcの
#---------------
# Compile flags
#--------------- の行からTCL_INCLUDES = ... の内容を挿入
・231行目辺りから10行ほど続くechoの行をコメントアウトして、下記の行を加える
!if $(STATIC_BUILD)
echo package ifneeded Itcl $(ITCL_DOTVERSION) [list load [file join $$dir $(ITCLLIBNAME)] Itcl] > \
"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
!endif

-5.4 pkg.vcの3.2を3.4に書き換える
-5.5. nmake -f makefile.vc TCLDIR=..\..\..\tcl8.5.10 OPTS=static,threads
-5.6. nmake -f makefile.vc TCLDIR=..\..\..\tcl8.5.10 OPTS=threads
オプション設定が有効に作用するかどうかは、static以外は検証していません
-5.7. nmake -f makefile.vc install TCLDIR=..\..\..\tcl8.5.10 OPTS=static,threads INSTALLDIR=..\..\..\inst
-5.8. nmake -f makefile.vc install TCLDIR=..\..\..\tcl8.5.10 OPTS=threads INSTALLDIR=..\..\..\inst

* 6. IncrTkのコンパイルとインストール
-6.1. VisualStudio2008コマンドプロンプトでwork/itcl3.2.1/itk/winにcdで移動
-6.2. copy ..\..\tcl8.5.10\win\nmakehlp.exe .
-6.3. makefile.vcを一部編集
・19行辺りの!include "..\..\rule.vc"の前の行にPROJECT = itkとPROJECT_REQUIRES_TK = 1を追加
・22行辺りの!include "..\..\config.vc"をコメントアウト
・30行辺りの!if $(DEBUG)のブロック全部と、その次のTMP_DIRをコメントアウト
・45行辺りと48行目辺りの$(ITK_VERSION)の後ろを$(SUFX)にする(s$(DBGX)や$(DBGX)を$(SUFX)に変える)
・53行辺りの!if $(ISTCLINSTALL)のブロック全て(!endifまで)をコメントアウト
・70行辺りのITCLSTUBLIBのReleaseを$(BUILDDIRTOP)に書き換える
・86行辺りの!if $(STATIC_BUILD) == 0 を !if !$(STATIC_BUILD)に書き換える
・88行辺りのdllResource.objをitk.resに書き換える
・114行辺りの$(USE_TCL_STUBS)を1に書き換える
・120行辺りの
# Compile flags
の行から!if $(ITK_INCLUDES)の前の行までの内容を消して、同じ場所に
tcl8.5.10のmakefile.vcの
# Compile flags
   の行からTCL_INCLUDES = ... の前までを挿入
・163行辺りのITK_EXE_CFLAGSの$(cdebug)の次あたりに$(cflags) $(cwarn)を追加
・166行辺りの!if $(USE_TCL_STUBS)を!if !$(STATIC_BUILD)に書き換える
・185行辺りの@$(vcvars) > nulの行をコメントアウトする
・220行辺りのechoを !if !(STATIC_BUILD) と !endifで囲う
226行辺りの
# Regenerate the stubs files
のブロックをitclのmakefile.vcのものに書き換える
・239行辺りの
# Special case object file targets
の中にあるdllResource.objの行とその次の行をコメントアウトする
・255行辺りと262行辺りにある!if $(_NMAKE_VER) < 162の行のブロック5行のそれぞれ4行目以外をコメントアウト

 !if $(_NMAKE_VER) < 162
{$(WINDIR)}.c{$(TMP_DIR)}.obj :
!else
{$(WINDIR)}.c{$(TMP_DIR)}.obj ::
!endif

 #!if $(_NMAKE_VER) < 162
#{$(WINDIR)}.c{$(TMP_DIR)}.obj :
#!else
{$(WINDIR)}.c{$(TMP_DIR)}.obj ::
#!endif
-6.4. nmake -f makefile.vc TCLDIR=..\..\..\tcl8.5.10 TKDIR=..\..\..\tk8.5.10 OPTS=static,threads
-6.5. nmake -f makefile.vc TCLDIR=..\..\..\tcl8.5.10 TKDIR=..\..\..\tk8.5.10 OPTS=threads
オプション設定が有効に作用するかどうかは、static以外は検証していません。
-6.6. nmake -f makefile.vc install TCLDIR=..\..\..\tcl8.5.10 TKDIR=..\..\..\tk8.5.10 OPTS=static,threads INSTALLDIR=..\..\..\inst
-6.7. nmake -f makefile.vc install TCLDIR=..\..\..\tcl8.5.10 TKDIR=..\..\..\tk8.5.10 OPTS=threads INSTALLDIR=..\..\..\inst

WMFやEMFを上下2分割して2ページに印刷するサンプルプログラム

プレゼン資料を上下2分割して2ページに印刷したい用事があったので、やり方を色々探したんですが、なかなか見つからなかったので、自前でプログラムを作ってみました(1)。このプログラムはWMFやEMFを上下2分割して2ページに印刷することができますので、プレゼン資料を何とかしてWMFやEMFに変換できればOK、ということになります。

WMFやEMFを読み込み、表示して印刷するところまでは、マイクロソフトのサイトにサンプルがありました(2)ので、今回はそれを流用しました。
オリジナルのサンプルプログラムにはライセンスが明記されていませんでしたが、(3)の内容によると、Ms-LPLというライセンスで配布すればよいらしいので、今回はそれに従いました。


xmlファイルの一部だけを編集できるhtaアプリ

イメージ 1

xmlで書かれた設定ファイルの特定のattributeやinnerTextだけを変えたいとき、
その変えたい部分だけを表示・編集できるツールをhtaで作成してみました。

xmlNodeEditor.hta内のxpathesは、xmlファイルの編集対象箇所を表しています。
各行の1つめは編集対象タグのXPath、2つめは編集対象属性名(nullのときは子要素全体が編集対象)です。

下記内容をコピペして拡張子htaで保存して実行すると↑の画面が表示されます。
記事の下側にあるtest.xmlを試しに編集してみて下さい。
* xmlNodeEditor.htaソース
<html>
<head>
<title>xml文書内属性エディタ</title>
<script>
/// 設定
var xpathes = [
// 編集対象タグのXPath attribute名(nullの場合子要素が編集対象)
["/xml/tag", null],
["/xml/text[@attname='hoge']", "attname"],
["/xml/textbox[@id='txt']", null],
["//target", null]
];
</script>
<!--

/// View

-->
<style>
table {
border-collapse: collapse;
};
th,td{
border: 1px solid black;
}
th {
background-color: Silver;
};
</style>
</head>
<body>
対象ファイル:<input id="target_file" value="test.xml" />
<button id="load">読み込み</button>
<button id="save">保存</button>
<div id="contents" />
</body>
<script>

/// Control

// docの内容を表示する。
function model2view() {
var tbl = document.getElementById('contents');
var html = "<table><thead><th>XPath</th><th>タイプ</th><th>名</th><th>値</th></thead><tbody>";
for (var j = 0; j < doc.items.length; ++j) {
var item = doc.items[j];
html += "<tr><td>" + item.xpath + "</td>";
var val = "", type, fc, dom = item.dom;
switch (item.type) {
case 0:
type = "attribute";
val = dom.value;
break;
default:
type = "element";
var nodes = dom.childNodes;
for (var i = 0; i < nodes.length; ++i) val += nodes.item(i).xml;
break;
}
html +=
"<td>" + type + "</td>" +
"<td>" + dom.nodeName + "</td>" +
"<td><input type='text' value='" + val + "'/></td></tr>";
}
html += "</tbody></table>";
tbl["innerHTML"]=html;

}

// input要素配列を取得する。
function query_tableinputtags() {
var ret = ;
var stack =
;
stack.push(document.getElementById('contents').firstChild);
while (stack.length > 0) {
var cur = stack.pop();
if (cur.tagName != null && cur.tagName.toLowerCase() == 'input') ret.push(cur);
while (cur != null) {
var fc = cur.firstChild;
if (fc != null) stack.push(fc);
cur = cur.nextSibling;
}
}
ret.reverse();
return ret;
}

// 表示内容を読み込みdocに書き込む
function view2model() {
var nodes = query_tableinputtags();
var j = 0, len = nodes.length;
for (j = 0; j < len; ++j) {
var item = doc.items[j];
switch (item.type) {
case 0:
item.dom.value = nodes[j].value;
break;
default:
// テキスト内のxmlタグが不正の場合は、上書きしない。
if (partdom.loadXML('<xml>'+nodes[j].value+'</xml>')){
item.dom.text = "";
while(partdom.firstChild.firstChild != null) {
item.dom.appendChild(partdom.firstChild.firstChild);
}
}
break;
}
}
}

var ctr_tf = document.getElementById('target_file');
// 読み込みクリック時の処理
document.getElementById('load').onclick = function () {
read_xml(ctr_tf.value);
model2view();
}
// 保存クリック時の処理
document.getElementById('save').onclick = function () {
view2model();
var fn = ctr_tf.value;
write_xml(fn);
read_xml(fn);
model2view();
}

/// Model

// doc.items : 変更対象項目が書かれた配列
// doc.items[*] : 変更対象項目
// doc.items[*].type : 0 : 属性, 1 : 子ノード
// doc.items[*].dom : 変更対象項目のdomオブジェクト type=0のときDomAttribute、type=1のときDOMElement
// doc.items[*].xpath: selectNodeで検索したときのxpath文字列
// doc.dom : xmlファイルのdomオブジェクト
var doc = { dom: new ActiveXObject('MSXML.DOMDocument'), items: };
doc.dom.async = false;
var partdom = new ActiveXObject('MSXML.DOMDocument');
partdom.async = false;

// doc.domの指定されたxpathのノードからattnameで指定した属性を探し出し、doc.itemsに追加する。
function add_attributeitems(xpath, attname) {
var nodes = doc.dom.documentElement.selectNodes(xpath);
for (var i = 0; i < nodes.length; ++i) {
var attr = nodes.item(i).attributes.getNamedItem(attname);
if (attr != null) doc.items.push({ type: 0, dom: attr, xpath: xpath });
}
}

// doc.domの指定されたxpathのノードを探し出し、doc.itemsに追加する。
function add_elementitems(xpath) {
var items = ;
var nodes = doc.dom.documentElement.selectNodes(xpath);
for (var i = 0; i < nodes.length; ++i) doc.items.push({ type: 1, dom: nodes.item(i), xpath: xpath });
}

// ファイルを読み込み、対象の属性やノードを抽出する。
function read_xml(fn) {
doc.dom.load(fn);
doc.items = [];
for (var i = 0; i < xpathes.length; ++i) {
if (xpathes[i][1] == null) add_elementitems(xpathes[i][0]);
else add_attributeitems(xpathes[i][0], xpathes[i][1]);
}
}

// 読み込まれているxmlデータをファイルに書き込む。
function write_xml(fn) {
doc.dom.save(fn);
}
</script>
</html>

*test.xml
<xml>
<tag>Hello</tag>
<tag>World</tag>
<tag><Nest/></tag>
<hoge>This is xml file.</hoge>
<text attname="hoge">attribute.</text>
<text>no attribute.</text>
<n1><n2>
<target>deep</target>
</n2></n1>
<textbox id="txt">innerText</textbox>
</xml>

dlib C++ ライブラリ バージョンアップ (ver 17.6)

Davis E. King氏が作成・配布している、dlib C++ ライブラリのバージョンが17.6になりました。
今回のバージョンアップで、下記機能が本家ライブラリに組み込まれました。

GUIウィジェットUnicode
・text_fieldウィジェットで、IME/XIMによる日本語入力

いつもと同様に、+α(OpenGL機能と日本語入力ウィンドウの位置をtext_fieldウィジェットの位
置に近づける機能)の追加をしたものを下記URLで配布します。
http://www.tok2.com/home/mocchi2008/libs/dlib/dlib.htm




イメージ 1
図1. Windows環境の実行例(MS-IME)


イメージ 2
図2. X11環境の実行例(KDE, SCIM)



もっちーの小部屋 自作のソフトを公開してます。
http://www.geocities.jp/mocchi_2003/index.html

もっちー書庫 改造ライブラリやプログラムサンプルを公開しています。
http://www.tok2.com/home/mocchi2008/index.htm

dlib C++ ライブラリ 本家アップデート(Ver.17.1)

イメージ 1

dlib C++ ライブラリの追跡の書き込みがここのところご無沙汰になってました。

Davis E. King氏が作成・配布している、dlib C++ ライブラリのバージョンが17.1になりました。
最近の更新はGUIに関するものが多いようです。

そのGUI機能で追加されたうち、気になったものは、下記2点です。
・メニューバー
ツールチップ

バージョン17.1にマルチバイト対応とOpenGL機能を実装したソースを
http://www.tok2.com/home/mocchi2008/libs/dlib/dlib.htm
に置いておきます。




もっちーの小部屋 自作のソフトを公開してます。
http://www.geocities.jp/mocchi_2003/index.html

もっちー書庫 改造ライブラリやプログラムサンプルを公開しています。
http://www.tok2.com/home/mocchi2008/index.htm