2008年8月31日日曜日

UbuntuでCをコンパイルできるようにする[build-essential]

素のUbuntuだとC/C++言語のためのヘッダファイルなどが用意されていない。stdio.hすらない。
なので、apt-getまたはSynapticからbuild-essentialをインストールする。

$ sudo apt-get install build-essential


インストール後に/usr/include/ディレクトリを見ると、各種ヘッダファイルが納められていることが分かる。

参考:https://answers.launchpad.net/ubuntu/+faq/61

2008年8月30日土曜日

メタデータが壊れたMP3ファイルへの対処[ffmpeg]

ネットで自作の曲なんかを配布してるのはよくある話だけども、最近落としたmp3ファイルのメタデータがおかしくて、ちょっと難があった。
エンコーダのいたずらか、はたまたダウンロード時にエラーになっただけなのかはわからないが、実再生時間とメタデータに書かれてる再生時間が違っていて、PC上のプレーヤでは難なく再生できていたのだが、gigabeatに転送したらエラーを吐かれて再生できない、ということがあった。

そこで私が取った行動はコレ
$ ffmpeg -i broken_metadata.mp3 -acodec copy extracted_audio.mp3

メタデータだけがおかしい様だったので、Audioストリームだけを抽出して新たなmp3ファイルを作成。

いやぁffmpeg使えるなぁ。
あとはWMV3のエンコードに対応してくれるとありがたいのだけれども。

2008年8月29日金曜日

自動起動とアプリケーションメニュー[.desktopファイル]

~/.config/autostart/というディレクトリに、アプリケーションのdesktopファイルを置いておくと、ユーザのログイン時にそのアプリケーションが自動起動する。
簡単に言えば、Windowsのスタートアップと同じ様な使い方が出来る。

アプリケーションの自動起動の設定画面(システム>設定>セッション(gnome-session-properties))で、ユーザが設定したものは実はこのディレクトリに反映されている。

具体的には、このディレクトリに次のようなdesktopファイルが作成される。

Pidginの例:
[Desktop Entry]
Type=Application
Encoding=UTF-8
Version=1.0
Name=名前なし
Name[ja_JP]=Pidgin
Exec=/usr/bin/pidgin
X-GNOME-Autostart-enabled=true
Comment[ja_JP]=インスタントメッセンジャー
Comment=インスタントメッセンジャー
X-GNOME-Autostart-enabledのtrue/falseによって自動起動するか否かが設定される。設定画面ではチェックのON/OFFに反映されている。

2008年8月28日木曜日

最近開いたドキュメント(recently-used)

Ubuntuに限らず、GNOME環境を使っているとパネルメニューに「最近開いたドキュメント」というのがあることに気づくと思う。
これはその名の通りの機能を持っていて、最近開いたファイルを一覧でずらっと表示してくれる。

でも、正直この機能って使わない。。。

なので、この機能を解除する/パネルメニューから消す方法が無いか探してみたが、設定エディタ(gconf-editor)にすらそれらしい項目が無かったりするので、機能を解除できるものではないらしい。

ググって出てきた先達の知恵を紹介すると、
とにかく機能しななるようにするなら、ユーザのホームディレクトリ次の2つのコマンドを叩くだけで済む。
$ rm .recently-used.xbel
$ mkdir .recently-used.xbel
要するに、最近開いたドキュメントの一覧を保存しているファイルにアクセスできなくしてしまう訳だ。
環境によってはファイル名が.recently-usedの場合もある。

ファイルを削除した後に、わざわざ同名のディレクトリを作成しているのがミソ。
単に削除しただけでは、自動で新たにファイルが作られるだけだし、試しにパーミッションを変えてファイルに書き込みできないようにしてみたが、今度は勝手にパーミッションが元に戻されてしまった。
そこでディレクトリを作成して、とにかく.recently-used.xbelというパスにアクセス出来ないようにしてしまうのだ。

ただし、この方法でもパネルメニューから「最近開いたドキュメント」の項目を消すことは出来ない(´・ω・`)

<追記>
それと、この方法を使っていると端末からファイルを開こうとする時に、「.recently-usedにアクセス出来ねぇよコンチキショウ」とエラーを吐かれるのでちょっと気になる。

2008年8月27日水曜日

UbuntuでMTPデバイスを扱う[Amarok][mtp-tools][mtpfs]

20081216編集
注意Ubuntu8.10上で同期できるっぽいです。

---------------------

以前のエントリでも書いたように、Ubuntuでもgigabeat(MTPデバイス)を使うことができる。

その時に試したのはRhythmboxでだった。そのエントリ中でも書いたように、IDv2タグをgigabeatが見てくれないという問題があるのだが、実はさらにアルバムアートが同期できないという問題もあった。

後者の問題に対して、他のプレーヤで何とかならないだろうかと思い、Amarokを導入してみた。
$ sudo apt-get install amarok
本体だけでは肝心のmp3など音楽ファイルが再生できないので、Amarokが自動でlibxine1-ffmpegパッケージをインストールしてくれる筈なのだが、私の場合は手動でインストールした。つか、インストールしないと固まる固まる。
("amarok mp3"とかでググると、libxine1-pluginsをインストールする、という記事が見つかるが古い情報なので注意。libxine-pluginsをapt-get installしようとしたら「それ古いからlibxine1-ffmpeg入れてね」とメッセージが出た。)
Amarokの初回起動時には、楽曲コレクションの初期設定などのダイアログが表示されるので、お好みでデータベースを選んだりする。

Amarokにgigabeatを認識させるにはまず、Amarokのメディアデバイスの設定画面で「メディアデバイスを追加」から現れるダイアログで、プラグインにはMTPデバイスを選択、適当な名前を付けて「OK」ボタンを押す。

マウントポイントなどさらに詳細に設定できるようだが、とりあえずこれで下準備は完了。

MTPデバイスを接続した状態で、デバイスブラウザで接続ボタンを押せば自動で認識してくれる筈。(完了まで多少もたつくが我慢我慢)


そして、さっそくファイルを転送してみよう…………出来ない orz
手順は間違っていない筈なのに何故だろう? と思い、さらに他の手段を探すことに。

そこで今度はSynapticsでmtp-toolsというのを見つけて、インストールしてみた。
$ sudo apt-get install mtp-tools
これは端末でMTPデバイスと通信出来るコマンドをいくつも提供してくれる。
mtp-albumart     mtp-files        mtp-newfolder    mtp-thumb
mtp-albums mtp-folders mtp-newplaylist mtp-tracks
mtp-connect mtp-format mtp-playlists mtp-trexist
mtp-delfile mtp-getfile mtp-reset
mtp-detect mtp-getplaylist mtp-sendfile
mtp-emptyfolders mtp-hotplug mtp-sendtr
例えば、mtp-detectを使うと、MTPデバイスの詳細情報を検出してくれる。

しかし、gigabeatをPCに接続して一番最初の接続しかgigabeatが受け付けてくれない、という妙な症状が起こってしまった。
mtp-detectをやった後に他のコマンドでgigabeatと通信しようとしてもエラーが出て、接続できない。これはAmarokも同じ様で、一度接続を解除するとUSBケーブルを一度外してからでないと接続しなおせなかった。

mtp-toolsもAmarokもMTPデバイスとの通信にlibmtpというライブラリを利用しているのだが、libmtpの設定ファイル(/etc/udev/rules.d/45-libmtp7.rules)がおかしいのか、libmtp自体のバグか何かなのかは分からない。Rhythmboxもlibmtpを使っている様なのだが、同じ症状は現れない。。。
Rhythboxで同期した楽曲ファイルが、何故かgigabeatのPicturesフォルダに入るのと関係があるのだろうか?

とりあえず、Ubuntuのリポジトリのバージョンは0.2.6.1なのだが、最新のものは0.3に上がっているので、次の機会にそちらを手動で導入してみようかと思う。

そして、結局アルバムアートは同期できないまま orz

<おまけ>
mtpfsを使うと、mtpデバイスをマウントできる。
$sudo mtpfs /media/gigabeat/ -o allow_other
(/media/gigabeatディレクトリは先に作成しておくこと)

<追記>
文中でパッケージ名を間違えてたのを修正。

ググって来た人、こちらも見た方がいいかも
mtp-sendtrコマンドでgigabeatSに転送してみた[mtp-tools]
http://mstssk.blogspot.com/2008/09/mtp-sendtrgigabeats.html

<追記2>
一番上にも書き加えましたが、2008年12月16日でUbuntuのリポジトリからDL出来る各ソフトウェア(Ubuntu8.10/Amarok/libmtp)の最新バージョンでは同期できる?
http://mstssk.blogspot.com/2008/12/gigabeats-syncs-with-amarok.html

2008年8月26日火曜日

Bloggerでタグクラウド

タグクラウドを付けてみた。
Bloggerでタグクラウドを使う方法はいくつかあるけど、弄くる部分が一番少なくて済むものを見つけてこのブログに付けてみた。(→右のペイン)

ググってたまたま見つけたRaymondさんのブログからコードを拝借。
http://www.compender.com/2007/12/simple-tag-cloud.html

Bloggerの設定で、「レイアウト」の「HTMLの編集」で「ウィジットのテンプレートを展開」にチェックを入れる。
<b:widget...> ... </b:widget>ってのが並んでる部分があるので、その下にでもRaymondさんのコードをコピペ。(他の<b:widget>タグの内にペーストしないように注意。)そして、「テンプレートを保存」。

これでもうタグクラウドが付いてるはず。
表示位置は、「レイアウト」の「ページ要素」で他のWidgetと同じようにグリグリ移動できる。

ただし、私はコードをほんの少し書き換えた。(文字サイズをpt指定にして、line-heightプロパティを付け足しただけ)

ちょっとしたHTMLの知識があれば出来るので、プログラムとか出来ない人もやってみてくださいな。

2008年8月25日月曜日

SongbirdまとめWiki

Songbirdのまとめサイトなんてのがありました。
http://wikiwiki.jp/songbird/

Songbird自体がまだ発展途上なので、そんなに情報は蓄積されてませんけどね。
とりあえず、私はLinux版でのWMA再生の正式サポートを望むだけです……(10GB近いWMAファイル達を変換したくないってのが本音です)

2008年8月24日日曜日

Songbird 0.7 リリース

http://getsongbird.com/

Songbirdの0.7がリリースされていたので、さっそくインストールしてみました。
Ubuntu用のdebファイルもすでにgetdebに上がってました
http://www.getdeb.net/release/3116

以前のバージョンからかなりデザインを刷新してますが、伊達に変わったわけではなく、UIがすっきりしていて以前より扱いやすい印象を受けました。

ですが、今回のバージョンでかなりコードが書き換わったためなのか、wmaファイルが再生出来なくなってしまっていました orz
大人の事情もあり、従来のバージョンでも正式にサポートしている訳ではなかったですが、それでも0.6.1までは直接パスを叩けば再生させることが出来たのですが、、、

Tips:
ちなみに、このスレッドを参考にして少しコードを書き換えるだけでSongbird上からWMAファイルが見えるようにすることもできます。従来バージョンなら有用ですが、0.7では上記のとおり見えたとしても再生はできません。
http://ubuntuforums.org/showthread.php?t=465051

2008年8月23日土曜日

端末でダブルクリック[gnome-open]

nautilusでディレクトリを見ている時はファイルのアイコンをダブルクリックすれば、関連付けられたアプリケーションが勝手に起動してファイルを開いてくれます。
ですが、端末でファイルを開くときは、そのファイルの形式が分かった上でそのファイルを開くのに適切なアプリケーションコマンドを使って開かなければなりません。
ファイル名に拡張子が付いていればまだいいですが、そうでない場合はそれがプレーンテキストなのかバイナリなのかはたまた画像ファイルなのかすら分かりません。そのファイルを開く前にまずfileコマンドあたりでファイルの形式を調べなければなりません。

そこで、gnome-openコマンドの登場です。
$ gnome-open anyfile

GNOMEデスクトップ環境でgnome-openコマンドを使えば、デスクトップ環境でファイルに関連付けられたアプリケーションでファイルを開いてくれます。ダブルクリックした時と同じように動いてくれるわけです。

ちなみに、同じ事をKDEではkfmclient execで出来るそうです。

これで端末での作業が少し楽になりました^^

2008年8月22日金曜日

LaunchPadに登録してみた

昨日のエントリとか書いてて、使えるソフトが日本語化されていないのはもったいないなぁ、と思ったのでとりあえずLaunchPadに登録してみました。(ぃゃ、そんなに英語は得意じゃないんですが)

LaunchPadってのは、フリーソフト開発のためのポータルサイト、って言ったら早いだろうか。それぞれのソフトの翻訳作業なんかも管理されている。

登録の手順の説明はここでは省くとして、翻訳作業を行おうとTranslacionページに行こうとすると、BSDライセンスに従うかどうかの確認ページが現れます。LaunchPadで行った翻訳はBSDライセンスで管理されるそうです。承諾(Confirm)しときましょう。

Emeseneのプロジェクトページを見てみましたが、Emeseneの公式wikiに上がってた日本語poはこっちに上げられていないようです。うーん。
http://emesene.org/trac/ticket/1449に、poを上げた人がLaunchPadにも上げたって書いてるんですけどねぇ。。。

とりあえず、Emeseneの翻訳をほんのちょっとだけやって今日は寝ます。

2008年8月21日木曜日

GUIツールキットの言語パック

昨日のエントリの続き。

EmeseneでDisconnectだけ"接続断"と訳されていた謎が解けました。
EmeseneはPythonでgtkを使って作られていて、Emeseneの言語ファイルがインストールされていなくても、gtkの言語ファイルが適用されていたんです。

ググったらlaunchPadのページが出てきました。"Disconnect"の訳を"接続断"としています。https://translations.launchpad.net/ubuntu/hardy/+source/gtk+2.0/+pots/gtk20/ja/570/+translate
このページの見方が分からないので推測ですが、新たな訳として"切断"が適用されたパッケージがそのうち提供されるのでしょうか。

ちなみに、肝心の言語ファイル自体はlanguage-pack-gnome-ja-baseパッケージで提供されていて、/usr/share/locale-langpack/ja/LC_MESSAGES/gtk20.moにあります。
ソースコード(gtk20.po)を確認したければ、
apt-get source language-pack-gnome-ja-base -d
でパッケージのソースコードをダウンロード出来ます。(-dオプションは--download-onlyで、ソースをDLしたあとコンパイルを行わないようにしています。)

ほかのアプリケーションでも、一部だけが訳されていたりすることがあったのですが、これでその謎も解けました。gtkのようなGUIツールを使って作られているアプリケーションで、GUIツールライブラリの機能をそのまま使っているような場合は、GUIツールの言語ファイルが適用されるんでしょう。
たとえば、GNOME MPlayerはウィンドウメニューの「開く」「終了」「設定」「情報」など、どのアプリケーションでもあるような(=GUIツールキットに標準で入っている)機能のところだけ日本語化されています。(ところで、GNOME MPlayerの言語パックはあるのかしら)

2008年8月20日水曜日

LinuxでWindows Live Messenger[Emesene]


今までメッセンジャーにはPidginを使っていたのですが、様々なメッセンジャープロトコルに対応しているにもかかわらず結局使っているのはMSN(現Windows Live Messenger)のアカウントだけでした。
そしたら、Emeseneというメッセンジャーを発見。WLMに特化したものらしいです。

$ sudo apt-get install emesene
パネルメニューのアプリケーションの追加と削除からもインストール出来ます。

私が一番感動したのは、Pidginで使えなかったWLMの機能「現在再生中の曲の表示」が出来るプラグインが標準で入っていることです。(ただし、デフォルトでは無効になっているので、オプション設定で有効にしましょう)
対応しているプレイヤーもAmarokやRhythmboxなどなど……

ただ、Pidginでもっともネックだったファイル転送の遅さは、Emeseneでも大して変わりませんでした orz

それと、まだ日本語のロケールは入っていないようなので、メニュー表示などは英語のままです。
何故か、Disconnectだけ"接続断"という変な表示になってましたが……
探してみると、Emesene公式の開発者ページに日本語訳をアップしている方がいたので使ってみました。
#1449 (Japanese translation for emesene (based on r1371's)) – emesene – Trac:
http://emesene.org/trac/ticket/1449
このページのAttachment(添付)のemesene.poファイルのリンクをクリックすると、ファイル内容のプレビューページに飛びます。そのページの一番下に、「Download in other formats: Original Format」というリンクがあるので、そこからemesene.poをダウンロード。

poという拡張子のファイルはUNIX系OSのアプリケーションの言語ファイルのソースコードだそうです。このpoファイルを、言語ファイル専用のエディタで.moという拡張子のファイルにコンパイルして使います。
とりあえず、言語ファイルのエディタとしてPoeditを使ってみました。
$ sudo apt-get install poedit


Poeditを起動し、emesene.poを開きます。(Poeditの初回起動時には、新規に言語ファイルを作成する場合に必要な署名を設定するようメッセージが現れます。)
開いたら、そのままファイルの保存をします。すると、emesene.poファイルと同じディレクトリにemesene.moファイルが出来るので、それをロケールファイルを置く適切な場所に置きます。Emeseneの場合は「/usr/share/locale/ja/LC_MESSAGES/emesene.mo」としましょう。

これで、Emeseneを再起動すると日本語表示になっているはずです。

って、"接続断"だけそのままってどういうこと??


<追記>
"接続断"の謎が解けました。
GUIツールキットの言語パック:http://mstssk.blogspot.com/2008/08/gui.html

<追記2>
Emeseneのアバター画像選択ダイアログで、「画像がありません」ボタンがありますが、英語版では「No Picture」となっていて、このボタンを押すと画像が何も設定していない状態に戻るので、訳は「画像なし」とした方が良いですね。
Poeditで読み込む段で訳を弄っとくと良いでしょう。

<追記3>
2008年11月22日現在、Ubuntu8.10 Intrepid Ibexで導入できるEmeseneのパッケージの方には日本語のmoファイルが含まれていますが、実際は空っぽです
http://mstssk.blogspot.com/2008/11/intrepidemesenejapanesetranslation.html

2008年8月19日火曜日

UbuntuでFancontrol出来ない[nx6125]

私のマシン(HP nx6125)でUbuntu起動中は、CPUの温度に応じてファンのON/OFFをやってくれるのはいいんだが、CPU温度が95℃とかクリティカルな状況じゃないとファンが回らないってのはキツイ。
温度表示は80℃台なのにファンが止まるってのは無いだろう。
(流石に変すぎなので、どこか表示が狂っている気がするけど)

それで、Ubutnu上からファンの速度をコントロール出来ないかと思い、調べてみたところ、linuxだとfancontrolを使うとファンの速度を設定ファイルに基づいてコントロール出来るらしい。

作業の流れとしては、
1.sensors(lm-sensorsパッケージ)をインストールし、sensors-detectコマンドでsensorsの基本設定を行い一度再起動。
2.pwmconfigコマンドでfancontrolの設定ファイル/etc/fancontrolを作成。
3.fancontrolを実行すると、/etc/fancontrolに基づきファン速度をコントロールする。

だが、pwmconfigを実行する時点で躓いた。
こんなエラー表示が出て、進まない。
/usr/sbin/pwmconfig: There are no pwm-capable sensor modules installed

これは既知のバグらしいのだが、ググっても古いバージョン(Dapper)のUbuntuでの対処方法しか見つからなかった。Hardyではfixされているはずで、nx6125が対応していないというだけなのかもしれない。

/etc/fancontrolファイルを直接書いてしまう手も無いことは無いかもしれないが、本来pwmconfigでファンコントローラを検出/確認を行ってマシンに適した設定を行うものだと思うので、他の人の設定ファイルを参考にするわけにもいかないだろう。

ちなみに、BIOSでは電源ケーブルを差した状態では常にファンをONにするように設定されているのだが、マシンに電源を入れUbuntuが立ち上がるまではファンは回っているが、そこから上記のような状態になる。

とりあえず、lm-sensorsを入れておけばCPU温度などは確認できるようになる。
さらにsensors-appletパッケージを入れると、パネルに表示できるようにもなる。

とりあえず、今日はここまで。

<追記>
/usr/sbin/pwmconfig: There are no pwm-capable sensor modules installed
もしバグでないのなら、このメッセージが出るという事はM/Bがファン制御に対応していないということらしい。うーん。

2008年8月18日月曜日

UbuntuでgigabeatS


Ubuntu 8.04にデフォで入ってるRhythmboxプレイヤーはMTPデバイスと楽曲の同期が出来るプラグインが入ってる。だが、以前に手持ちのgigabeat S30で試してみた時にはRhythmboxがフリーズしてしまい、結局諦めたのだった。
それで、gigabeatに楽曲を同期するときだけWindows XPを立ち上げるという面倒くさいことをやっていたのだが、昨日ふと思い立って再び試してみたら、、、ありゃイケたよオイ(´・ω・`)

接続時にモタつくのはgigabeatがあくせくしてるわけだからいいとして、曲の転送時にフリーズしたりするのはまぁご愛嬌か。やり直すと大抵うまくいく。転送する時は曲の再生を止めるとかちょっと気をつかわなきゃいけないかもしれない。

ちなみに転送の方法は、上の画像みたいにデバイスのアイコンが表示されるので、自身の楽曲ライブラリのところから転送したい曲をドラッグアンドドロップすればいい。

それよりも躓いたのはタグ情報についてだ。
手持ちのmp3ファイルを試しに転送してみたところ、何故かタグのアルバム情報がgigabeat上では「不明」になっている。
転送時のエラーなんかではなく、曲データ自身に問題がある様。同じようなことがWindowsでWMPから転送した時にも起こったことがあるのを思い出した。

んで、原因としては、Ubuntuのソフト(RhythmboxやEasyTagとか)で見てるタグ情報とgigabeatで見てるタグ情報が違っている、という感じみたい。

解決法としては、やはりEasyTagで、タグをID3v2書き込みのみにしていたのをID3v1でも書き込むように設定を変更し、目的のmp3ファイルを一度読み込んで強制保存する。これで、ファイルにID3v1のタグが追加される。
ID3v1ならgigabeatでもちゃんと読み込んでくれるので、これでおk。

<訂正>やっぱダメだった。

<追記>
ID3v2タグでなくてWMAには別にメタデータがあって、gigabeatなんかはそいつを見てる様。
それと、Rhythmboxで転送したファイルは何故か、gigabeat内のPicturesディレクトリ以下に保存されてしまった。本来はMusicに入るはず。

この記事の続き
UbuntuでMTPデバイスを扱う[Amarok][mtp-tools][mtpfs]
http://mstssk.blogspot.com/2008/08/ubuntumtpamarokmtp-toolsmtpfs.html

2008年8月17日日曜日

Ubuntuで各種圧縮ファイルを扱う

Ubuntuの標準のアーカイバである書庫マネージャ(file-roller) は様々なアーカイブ形式に対応しているが、別途に各種アーカイブそれぞれのアーカイバをインストールしないと対応できないものもある。
例えば、LZH(LHA形式)はデフォルトのままでは解凍できない。lha(またはlha-sjis)パッケージをインストールすると、解凍できるようになる。
(file-roller自身はアーカイバというより、アーカイバのフロントエンドの役割みたい)

Ubuntu 8.04でアーカイバを追加しないと解凍できないもの
形式 - パッケージ名
7ZIP - p7zip-full
LHA(LZH) - lha または lha-sjis(lha-sjis推奨)
RAR - rar 及び unrar
ACE - unace
CAB - lcab 及び cabextract

全部いっきにインストールするなら、端末でこんな感じに一発叩くだけ
$ sudo apt-get install p7zip-full lha-sjis rar unrar unace lcab cabextract


<追記>
lha-sjisは日本語セットアップヘルパでも入れられます。
つか、玄人さんでも日本語セットアップヘルパは一応使っておくべきじゃないかなぁ。忘れがちなpdfビューアの日本語文字化け対策のパッケージ入るし。

2008年8月16日土曜日

デスクトップテーマを変えて……みたかった

Ubuntuのデスクトップテーマを変えてみようとしたんだけども、Ubuntuの標準テーマHuman以外はアプリケーションによって対応がまちまちなので、見た目がちぐはぐになってなんか嫌な感じ……
とりあえず、ダークが色合いが気に入ったので、gnome-themes-extrasパッケージに入っていたDarklooksにしてみた。

だが、Xを再起動したりすると別のテーマに切り替わる。。。何故。
他にも、切り替える度に色の変更が反映されたりされなかったりで変な状態。

結局、Humanに戻しちゃった。

2008年8月15日金曜日

Linuxで色んなディスクイメージをマウントする

iso9660のイメージファイルなら、Linuxではmountコマンドで無問題なんだけど、その他のファイルタイプではiso9660に変換する必要がある。

ちなみに、ディスクイメージの形式はbin,nrg,mdf,b5i,cdi,img,ccd,pdiなどなど。
こいつらをiso9660に変換するのにそれぞれのためにコマンドがちゃんとある。
コマンドは大抵「[filetype]2iso」という形になっている。[filetype]はそれぞれのbinとかcdiとかに置き換えて考えてください。

例えば、binファイルをiso9660に変換するには
$ bin2iso input.bin output.iso

こんな感じ。
それぞれのディストリのリポジトリにちゃんと入ってると思うので、UbuntuとかDebian系なら
# apt-get install bin2iso

とかでインストール。

ただし、bin+cueなイメージなんかはbchunkを使う必要がある。(bin+cueの他にraw+cueとかもあるらしい)
$ bchunk input.bin input.cue output.iso

この時、必ずbinを先に持ってくるように。

ソースなんかはこのページからリンク飛んでsourceforgeから落としてください。
http://wiki.linuxquestions.org/wiki/CD_Image_Conversion

<注意>
音楽CDはiso9660で扱えないそうなので、変換しようとしてもダメらしい。

<訂正>
bin2isoの説明で、出力先がoutput.binになってたのをoutput.isoに修正。

2008年8月14日木曜日

端末で「初音ミクに「Ievan Polkka」を歌わせてみた」を再現してみた のソースコード


先週くらいに作ったこの動画で、ソースが欲しいという米があったので、ここに私の酷いコードを晒します。ソース自体は無駄な長さなので、この記事の最後に置いときました。
あと、端末とは言ってますが実際はLinux上の端末エミュレータってやつですね。スミマセン。

実行した環境はUbuntu 8.10訂正:8.04のgnome-terminal上です。フォントはデフォのまま。

一応、動画作成に至った流れの解説というかなんというか。

コマンドプロンプトの人のを見る→せめてちゃんとしたAAで……俺が作るか!→よしゃ出来た。あれ?なんかもう他にも色々うpされてる→もっとなにか拈りを入れないと→他の顔のバリエーションも作ろう→AAを分解したらもっと短くなるけど、全体コピペして微調整したらAA分解するの面倒くさくなった。描画する関数書き変えるのも面倒→ソースの半分をAAが占めることに→どうせなら、背景のロゴも→どうせなら動画全体を再現……→プログラムの全体構造書き変えるの面倒くせえ。メインループそのままでぶん回しながら時間計ってifで→あ、歌詞入れるタイミングとネギ振りのタイミングが同期するわけじゃないから、ネギ振りに合わせてsleepすると……→まぁ、いいや。

他の方の環境では、フォントが違ったりしてAAがうまく表示され無いかもしれません。
ちなみに、私の環境で端末のウィンドウを横73文字x縦27行になるようにリサイズしたらちょうど512x384ピクセルくらいになりました。

ソースは途中で面倒くさくなって定数を#defineしなくなったりしてます。もうちょっと丁寧に作るべきだったか……。最後の1行分だけ歌詞抜けちゃってるし。
AAは等幅フォント用に作ってますが、私の環境で全角文字が半角幅で表示されるという現象が起こったので、半角スペースを入れて微調整してあります。なので、普通に表示できる環境ではAAの一部がズレてます。

Cursesは、2バイト文字対応のncurseswというライブラリを使いました。ライブラリを導入してから、-lncursesw とオプションを付けてコンパイルしてください。

以下、「動きゃいいんだよ動きゃあ」精神のコード。動画に使った物そのままです。
テキストエディタで特殊文字をエスケープ文字に置換してからコピペしましたが、マズってるかもしれないのでお気を付けて。
#include <stdio.h>
#include <ncurses.h>
#include <locale.h>
#include <time.h>
#include <sys/time.h>

//screen size(row x col)
// 27x73

#define true 1
#define false 0

//for sleep command
#define DELAY 1000

#define UP 0
#define DOWN 1

#define MIKU_SIZE_ROW 17
#define MIKU_SIZE_COL 37

#define REAL_MIKU_SIZE_ROW 26
#define REAL_MIKU_SIZE_COL 47

//Negi ASCII Arts
char *negiUp[] = {
"くヽ l^i ",
" \\l l ",
" \\l ",
" \\ ",
" \\",
" \"
};

char *negiDown[] = {
" <\ ",
" \\ ",
"┌ ーーーーーー",
"└ ーーーーーー"
};


//Miku ASCII Arts
char *normal[] = {
" rへ ___ __ ",
" /: : : : : Y: :ヽ ",
" /: ./l: lヽ::ヽ: :ヽ ",
" //: /ノ l:ト、ヽ: :':: .', ",
" / l: / ○ 丶l ○ l: :ハ : : ',",
" _/: l: l@┌ ー┐ @l:/:l: : .',",
"/:::\ヽl \ │ │ /://l : :.i",
"{:::::::`T7└-ー┴‐< l: : l",
" `rーー┼ーー/l/l//_ヽ l : : :l",
" /: : : | /:/:l: Y:::l l : : :l",
" ,': : :/ /:/: : l:::l. l : : :.l",
" i : : く/レへ : l::::', ! : : : l",
" l : : :\:::::ヽイ::::〉 l : : : l",
" l : : : :ト、:::::>tjtjノ |: : : : l",
" ',: : : :/├ ー┤ |─ '\"| l : : : :l",
" ヽ : :/ l:::|l::::l ',: : ::,'",
" \:/ l:::l|:::l ヽ: : /"
};


char *cool[] = {
" rへ ___ __",
" /: : : : : Y: :ヽ",
" /: ./l: lヽ::ヽ: :ヽ",
" //: /\ l:ト /: :':: .',",
" / l: / ○ 丶l ○ l: :ハ : : ',",
" _/: l: l@ @l:/:l: : .',",
"/:::\ヽl \ /\ /://l : :.i",
"{:::::::`T7ヽ ̄ー-< l: : l",
" `rーー┼ーー/l/l//_ヽ l : : :l",
" /: : : | /:/:l: Y:::l l : : :l",
" ,': : :/ /:/: : l:::l. l : : :.l",
" i : : く/レへ : l::::', ! : : : l",
" l : : :\:::::ヽイ::::〉 l : : : l",
" l : : : :ト、:::::>tjtjノ |: : : : l",
" ',: : : :/├ ー┤ |─ '\"| l : : : :l",
" ヽ : :/ l:::|l::::l ',: : ::,'",
" \:/ l:::l|:::l ヽ: : /"
};

char *tired[] = {
" rへ ___ __ ",
" /: : : : : Y: :ヽ ",
" /: ./l: lヽ::ヽ: :ヽ ",
" //: /ノ l:ト、ヽ: :':: .', ",
" / l: / ○ 丶l ○ l: :ハ : : ',",
" _/: l: l@ @l:/:l: : .',",
"/:::\ヽl \ /\ /://l : :.i",
"{:::::::`T7ヽ ̄ー-< l: : l",
" `rーー┼ーー/l/l//_ヽ l : : :l",
" /: : : | /:/:l: Y:::l l : : :l",
" ,': : :/ /:/: : l:::l. l : : :.l",
" i : : く/レへ : l::::', ! : : : l",
" l : : :\:::::ヽイ::::〉 l : : : l",
" l : : : :ト、:::::>tjtjノ |: : : : l",
" ',: : : :/├ ー┤ |─ '\"| l : : : :l",
" ヽ : :/ l:::|l::::l ',: : ::,'",
" \:/ l:::l|:::l ヽ: : /"
};

char *sleep1[] = {
" rへ ___ __",
" /: : : : : Y: :ヽ",
" /: ./l: lヽ::ヽ: :ヽ",
" //: /ノ l:ト、ヽ: :':: .',",
" / l: / =丶l =l: :ハ : : ',",
" _/: l: l@┌ ー┐ @l:/:l: : .',",
"/:::\ヽl \ │ │ /://l : :.i",
"{:::::::`T7└--u┴‐< l: : l",
" `rーー┼ーー/l/l//_ヽ l : : :l",
" /: : : | /:/:l: Y:::l l : : :l",
" ,': : :/ /:/: : l:::l. l : : :.l",
" i : : く/レへ : l::::', ! : : : l",
" l : : :\:::::ヽイ::::〉 l : : : l",
" l : : : :ト、:::::>tjtjノ |: : : : l",
" ',: : : :/├ ー┤ |─ '\"| l : : : :l",
" ヽ : :/ l:::|l::::l ',: : ::,'",
" \:/ l:::l|:::l ヽ: : /"
};

char *sleep2[] = {
" rへ ___ __",
" /: : : : : Y: :ヽ",
" /: ./l: lヽ::ヽ: :ヽ",
" //: /ノ l:ト、ヽ: :':: .',",
" / l: / =丶l =l: :ハ : : ',",
" _/: l: l@┌ ー┐ @l:/:l: : .',",
"/:::\ヽl\ │ │ /://l : :.i",
"{:::::::`T7└--u┴‐< l: : l",
" `rーー┼ーー/l/l//_ヽ l : : :l",
" /: : : | /:/:l: Y:::l l : : :l",
",': : : / /:/: : l:::l. l : : :.l",
"i : : く/レへ : l::::',! : : : l",
"l : : : \:::::ヽイ::::〉l : : : l",
"l : : : : ト、:::::>tjtjノ |: : : : l",
"',: : : :/ ├ ー┤ |─ '\"| l : : : :l",
" ヽ : :/ l:::|l::::l ',: : ::,'",
" \:/ l:::l|:::l ヽ: : /"
};

char *realMiku[] = {
" ,.-.‐ . へ",
" {少'\" : : : 幻、\",
" /:/:: : : Y::i : :ヽ.",
" /:/N: iヽ: l_:_: :l: ハ",
" ,{:/:Lヾ{ 'Tヽ|::} ハ:: :i",
" /:ヽ:|心 、 ゛ .}'-:'/l: :!",
" /: : :>:ヽ ー;,イiTく l: : l",
" /: : :/ `≧ 令ーツー.、 l: : :l",
" /: : :/ r‐ f^小:::./ }l: : :l",
" /: : :/ j//./::::Y i / l: : :l",
" /: : :/ /:}/./:::::ll. 01! l: : :l",
" /: : :/ /://./:::::::! ̄: | l: : :l",
" /: : :/ /://./:::::::/|;;;;| l: : :l",
" /: : :/ /// ':::::::/ |;;;;| l: : :l",
" /: : :/ /':/ i:::::{ |;;;;| l: : :l",
" /: : ://:::/ i::::::\|;;;;;| l: : :l",
" /: : :/::::〈 i:::::::`!;;:;;;| l: : :l",
" / : ;〈:::::/ヽ/::::::::: |;;;;;;l l: : :l",
" /: :∧ ヽ:::/;;;;\::::::/ |;;;;;;| l: : :l",
" /: :/;;Y ゝ;;;;;:::;\::/;.;ィ|;;;;;;|. l: : :l",
",: : /、;lヽ√`ート::::,;r-Y\"..\"ィ|;;;;;;| |: : l",
"!: :′l>、| `ー- L_ ̄ i 斗 ´ |;;;;;;l.l: : l",
"l: :i ^|` ー - | ̄|_,.- ‐ 1ヽ;;;;;ノ l: : l",
" ',:l |;;;;;;:! l;;;;;;| ヒ!ヘハ! l: ,'",
" ゛:, |;;;;;:i l;;;;;;| } :/",
" ヾ:. |;;;;;:! l;;;:;;| /:/",
" |;;;;;! l;;;;;;| /'"
};

char *mikuLogo[] = {
" _ _",
" ∪ ∪",
" ┌─ ─┐┌ ─ ┐┌ ─ ─┐ ∩ __",
" └─ ./└_┐ |└┐┌┐┌┘│ └ ─ ┐/ |",
" // _||||┌┘└┘└┐└ ─ ─ ┘\/~||",
"//||//||||└ ─ ─┘┌ ─ ─ ┐ /|",
"|/|トゝ|||| ┌ ─ ,└ ─ ─ ┘ //",
" || |||| │ =)┌ ─ ─ ┐//",
" └┘ └┘└┘ └ ─ '└ ─ ┐//",
" HACHUNE MIKU |/",
};

//Lyrics
char *lyric0 = "あらっつぁっつぁ〜やりびだびりんらばりったんりんだんれんだんどぅ";
char *lyric1 = "まばりぱっぱーっぱりぱり ぱりりりびりびりすてんれんだんどぅ〜";
char *lyric2 = "やばりんらんてんだんでんあろ〜 わらば るぶるぶるぶるぶれいえぶ〜";
char *lyric3 = "ばりったんりんだんでんらんろ〜 たた たたたたとぅとぅでんやぶ〜";
char *lyric4 = "りんらんてんだんりんらんてんだん りんらんりんらんりんりんりりり";

//values
int nowNegiType = UP;
int sleepingType = UP;
int mikuRow;
int mikuCol;

void addLogo(int ha, int li, int vo){
int i;

if(ha){
for(i = 0; i < 10; i++){
mvaddstr(LINES - 14 + i, 0, mikuLogo[i]);
}
}

if(li){
for(i = 0; i < COLS; i++){
mvaddstr(LINES - 3, i, "-");
}
}

if(vo){
mvaddstr(LINES - 2, 2, "VOCALOID2");
}
}

void addAA(char *miku[]){
int i;
for(i = 0; i < MIKU_SIZE_ROW; i++){
mvaddstr(mikuRow + i,mikuCol,miku[i]);
}
}

void addLyric(char *lyric){
mvaddstr(LINES - 1, 5, lyric);
}

void addNegi(int type){
int i;
if(type == UP){
for(i = 0; i < 6; i++){
mvaddstr(mikuRow + i + 1, mikuCol - 11, negiUp[i]);
}
}else{ //DOWN
for(i = 0; i < 4; i++){
mvaddstr(mikuRow + i + 4, mikuCol - 14, negiDown[i]);
}
}
}

void mvAddNegi(int row, int col, int type){
int i;
if(type == UP){
for(i = 0; i < 6; i++){
mvaddstr(row + i, col, negiUp[i]);
}
}else{ //DOWN
for(i = 0; i < 4; i++){
mvaddstr(row + i, col, negiDown[i]);
}
}
}

void toggleSleepMiku(){
if(sleepingType == UP){
addAA(sleep1);
sleepingType = DOWN;
}else{
addAA(sleep2);
sleepingType = UP;
}
}

void toggleAddNegi(){
addNegi(nowNegiType);
if(nowNegiType == UP){
nowNegiType = DOWN;
}else{
nowNegiType = UP;
}
}

double getTimeOfDay_sec(){
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

double getPassedTime(double startTime){
return (getTimeOfDay_sec() - startTime);
}

main(){

int i;
double passedTime;
double startTime;
int sleepTime;
int logoHa;
int logoLi;
int logoVo;

setlocale(LC_ALL,"");
initscr();
cbreak();
noecho();

mikuRow = LINES - MIKU_SIZE_ROW - 3;
mikuCol = COLS - MIKU_SIZE_COL - 1;

logoHa = false;
logoLi = false;
logoVo = true;

startTime = getTimeOfDay_sec();

sleepTime = 0;

//ここから動画の描画

//初期状態 VOCALOID2ロゴのみ
addLogo(false, false, true);
move(LINES - 1,COLS - 1);
refresh();
usleep(5500 * DELAY);

//ボーダーライン表示
for(i = 0; i < REAL_MIKU_SIZE_ROW; i++){
mvaddstr(LINES - REAL_MIKU_SIZE_ROW + i,
COLS - REAL_MIKU_SIZE_COL - 1,
realMiku[i]);
}
addLogo(true, false, true);
move(LINES - 1,COLS - 1);
refresh();
usleep(3500 * DELAY);

//初音ミク ロゴ登場
clear();
for(i = 0; i < REAL_MIKU_SIZE_ROW - 3; i++){
mvaddstr(LINES - REAL_MIKU_SIZE_ROW + i,
COLS - REAL_MIKU_SIZE_COL - 1,
realMiku[i]);
}
addLogo(true, true, true);
move(LINES - 1,COLS - 1);
refresh();
usleep(7000 * DELAY);

while(1){
clear();
passedTime = getPassedTime(startTime);
addLogo(true, true, true);

//ミク
if(passedTime <= 16.8){
//登場 休符
sleepTime = 100;
addAA(normal);
addNegi(UP);
}else if(passedTime <= 32.0){
//ネギ振り
sleepTime = 250;
addAA(normal);
toggleAddNegi();
}else if(passedTime <= 33.0){
//休符
sleepTime = 100;
addAA(normal);
addNegi(UP);
}else if(passedTime <= 48.5){
//ネギ振り
sleepTime = 250;
addAA(normal);
toggleAddNegi();
}else if(passedTime <= 49.0){
//休符
sleepTime = 100;
addAA(normal);
addNegi(UP);
}else if(passedTime <= 64.5){
//居眠り
sleepTime = 500;
toggleSleepMiku();
addNegi(UP);
}else if(passedTime <= 65.0){
//YO!!
sleepTime = 500;
mvaddstr(mikuRow - 1, mikuCol + 10, "!!!");
addAA(cool);
addNegi(UP);
addLyric("            YO!!!");
}else if(passedTime <= 80.0){
//激しい振り
sleepTime = 125;
addAA(cool);
toggleAddNegi();
}else if(passedTime <= 81.0){
//疲れ休符
sleepTime = 100;
addAA(tired);
addNegi(UP);
}else if(passedTime <= 96.0){
//疲れ振り
sleepTime = 250;
addAA(tired);
toggleAddNegi();
}else if(passedTime <= 97.0){
//りんらんりんらんりんらんりんらん

sleepTime = 125;
addAA(tired);
toggleAddNegi();

}else if(passedTime <= 113.0){
//ネギ振り
sleepTime = 250;
addAA(normal);
toggleAddNegi();
}else if(passedTime <= 114.0){
//休符
sleepTime = 100;
addAA(normal);
addNegi(UP);
}else if(passedTime <= 129.0){
//ネギ振り
sleepTime = 250;
addAA(normal);
toggleAddNegi();
}else if(passedTime <= 130.0){
//休符
sleepTime = 100;
addAA(normal);
addNegi(UP);
}else if(passedTime <= 145.0){
//居眠り
sleepTime = 500;
toggleSleepMiku();
addNegi(UP);
}else if(passedTime <= 145.1){
//ネギ落下 中段
sleepTime = 50;
addAA(sleep1);
mvAddNegi(mikuRow + 8, mikuCol - 13, DOWN);
}else if(passedTime <= 146.0){
//ネギ落下 中段
sleepTime = 50;
addAA(sleep1);
mvAddNegi(mikuRow + 13, mikuCol - 14, DOWN);
}else{
usleep(5000 * DELAY);
break;
}

//歌詞
if(passedTime <= 17.0){
//前奏
}else if(passedTime <= 20.0){
addLyric(lyric0);
}else if(passedTime <= 24.0){
addLyric(lyric1);
}else if(passedTime <= 29.0){
addLyric(lyric2);
}else if(passedTime <= 32.0){
addLyric(lyric3);
}else if(passedTime <= 37.0){
addLyric(lyric0);
}else if(passedTime <= 40.0){
addLyric(lyric1);
}else if(passedTime <= 45.0){
addLyric(lyric2);
}else if(passedTime <= 48.0){
addLyric(lyric3);
}else if(passedTime <= 81.0){
//間奏
}else if(passedTime <= 85.0){
addLyric(lyric0);
}else if(passedTime <= 89.0){
addLyric(lyric1);
}else if(passedTime <= 93.0){
addLyric(lyric2);
}else if(passedTime <= 97.0){
addLyric(lyric4);
}else if(passedTime <= 101.0){
addLyric(lyric0);
}else if(passedTime <= 105.0){
addLyric(lyric1);
}else if(passedTime <= 109.0){
addLyric(lyric2);
}else if(passedTime <= 113.0){
addLyric(lyric3);
}else if(passedTime <= 117.0){
addLyric(lyric0);
}else if(passedTime <= 121.0){
addLyric(lyric1);
}else if(passedTime <= 125.0){
addLyric(lyric2);
}else{
//do nothing
}

move(LINES - 1,COLS - 1);
refresh();
usleep(sleepTime * DELAY);
}

//終了
endwin();

}

2008年8月13日水曜日

プロンプトを変更する

端末エミュレータで、$とか#とかなってる部分をプロンプトと呼ぶ。
(ちょっと間違ってるかも)
Ubuntuでは、$の前にユーザ名・マシン名・カレントディレクトリのフルパスなどが表示される。
あまりパスが深いディレクトリに行くと、カレントを表示してる部分が長くなりすぎてしまい、作業しづらくなる。
そこで、プロンプトの書式を変える方法。

あくまで、Ubuntuで試した場合なので、他のディストリビューションでは違う部分があると思うけど。

プロンプトはPS1という名前の環境変数として設定されている。

user@machine:~$ echo $PS1
${debian_chroot:+($debian_chroot)}\u@\h:\w\$
user@machine:~$


「${debian_chroot:+($debian_chroot)}」の部分はDebian系ディストリ特有のものだそう。とりあえず、触らないでおく。

で、まぁ\uがユーザ名・\hがマシン名・\wがカンレントディレクトリとそれぞれ置き換わるんだと分かる。
例えば、カレントディレクトリの表示をフルパスでなく、カレントディレクトリ名のみにしたければ、\wでなく\W(大文字)にすればいい。なんなら削除してもいいし。

$ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\W\$'


その他、いろいろ指定できるものがある。
http://pocketstudio.jp/linux/?%A5%D7%A5%ED%A5%F3%A5%D7%A5%C8%A4%CE%B3%CE%C7%A7%A4%E4%C0%DF%C4%EA#content_1_7

でも、フルパスが表示されるのはこれはこれで便利なんだよなぁ

2008年8月12日火曜日

ffmpegでニコニコ動画用のmp4動画を作る

一昨日のエントリで愚痴をこぼしましたが、あとあとmp4で再エンコせずにしっかりアップ出来ました。

参考にしたのはこちら↓

エンコード設定(中画質~高画質) - ニコニコ動画まとめwiki: ffmpegを用いてmp4(H.264、AAC)で2passエンコードする
http://nicowiki.com/%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E8%A8%AD%E5%AE%9A%EF%BC%88%E4%B8%AD%E7%94%BB%E8%B3%AA%EF%BD%9E%E9%AB%98%E7%94%BB%E8%B3%AA%EF%BC%89.html#teeca4db

「まとめWikiじゃねぇか!」と怒らないで orz
わかってます。基本目を通すべきだってのはわかってます。でも、素で見逃してました('A`)

んで、本題。
上記ページに、ffmpegを用いてmp4で2passエンコードする場合のコマンドの例が書かれています。
コーデック指定にlibx264・libfaacと指定していますが、Ubuntu 8.04のaptでインストールできるffmpegのversionでは、そのままh264・aacと指定できます。("$ ffmpeg -formats"の出力結果参照)

<20081222追記>
Ubuntu8.04のリポジトリでなく、正確にはMedibuntuのUbuntu8.04向けリポジトリだったかと

(以降のコマンドラインの例は、私が実際に行ったものとはちょっと違っています。入力動画を切り分けるために-tオプションを使いましたが、一般例としては必要ないので割愛しました。また、ファイル名もわかりやすく変えてあります。)

私はとりあえず普通に1passで試してみました。
$ ffmpeg -i input.mpeg -i input.mp3 -s 512x384 -vcodec h264 -b 300k -r 25.00 -acodec aac -ab 64k -ar 44100 output.mp4
ビットレートが 動画300k + 音声64k = 364k となるかと思いきや、この結果出てきたファイルは570kbpsでした。
どうやら、実際に指定している値より高めになるようです。このために、初め動画のビットレートを500kと指定した時には700kbps台のファイルが出来てしまい、ちょうど良いbpsになるように何度も繰り返す羽目に。(そういうもんなのかな?)

それと2passの場合。
$ ffmpeg -i input.mpeg -vcodec h264 -r 25.00 -b 500k -s 512x384 -pass 1 -passlogfile "./passlog" -an "./1pass.mp4"
$ ffmpeg -i input.mpeg -vcodec h264 -r 25.00 -b 500k -s 512x384 -pass 2 -passlogfile "./passlog" -i input.mp3 -acodec aac -ar 44100 -ab 64k "./2pass.mp4"

こちらの場合は、動画のビットレートが指定したとおりにエンコードされました。

1passも2passもニコニコ動画に再エンコード無しでアップロード出来ました。
ただし、いずれも実際にうpした後のデータをダウンロードしてみると、元のファイルと少しファイルサイズやヘッダが違っているようです。bpsも少しだけ食い違っています。
ですが、大幅に画質が落ちたりしていないので、再エンコードはされていないと判断してます。ニコニコ動画の仕様で、適切なエンコードを行っていたとしても、うpされたデータは必ずエンコード処理に通されます(エンコードしています、とページに表示される)。その時に、実際には再エンコードされていなくても、ヘッダファイルの内容だけ書き変えたりしているのかも。

ちなみに、テストでうpしたその動画は短い上に元の映像も私のデスクトップをキャプチャした少し質の悪いものだったので、1passと2passの差がまったく分かりませんでした orz
再生時間がそれなりに長い動画でなければ違いは出てこないんじゃないかと思うので、よほど質を気にしなければ1passで十分です。

実際にうpした動画のスクリーンショット。

flvでエンコードしたが、再エンコされてしまった場合。


1passのmp4+aacで、再エンコ無しの場合。


やはり、後者の方が圧倒的に綺麗です。文字もくっきり見えて読めます。(当たり前か)


それと最後に注意事項。私と同じ轍を踏む方が一人でもいなくなるように。。。

エンコードする際には必ず、-s -b -r(画面サイズ・映像ビットレート・映像フレームレート)などの値を指定しましょう。オプション指定せずにffmpegのデフォルト値のままでエンコードして40MB以下/600kbps以下になるとしても、ちゃんと指定しないと何故かうpしたときにエンコード処理の時点でエラーで弾かれます。
一昨日あたりに失敗した時は、元の動画を作成する時点(デスクトップのキャプチャ)でサイズが512x384になるようにしていたので、ffmpegによるエンコード時点では-sオプションを使いませんでした。また、フレームレートもデフォルトのままで良いと思い、-rを指定しませんでした。
確証はありませんが、これが失敗した原因だと思います。デフォルト値と同じ値だったとしても、指定した場合としなかった場合では書き出されるヘッダが違っているのではないかと私は思っています。

それと、エンコードした動画を確認するのにTotemは使わない方が良いでしょう。Totemに限らずGstreamerを使っているプレイヤーではAdobeの純正のflash playerに比べ再生時の画質がかなり落ちるようです。
Linux上のブラウザでflashを再生するのにGnashなど使っている方もいると思うのですが、私はAdobe純正のプラグインを使っています。
http://www.adobe.com/go/gntray_dl_getflashplayer_jp
Gnashなど他のプレーヤーのプラグインと比べた訳ではないので、純正が1番と言うつもりはないですが。

兎に角、これで良画質でニコニコ動画にうpできるようになりました^^

<追記>
Ubuntuのバージョン間違えてました。この記事書いた時点では8.10は出てない出てない。

2008年8月11日月曜日

またニコ動にうpしてみた



我ながらひどい内容です。

毎回、映像作成してる時間の方が長いというジレンマ。
Linuxでニコ動用にエンコする方法を体得してないので、やはり再エンコ。

2008年8月10日日曜日

ffmpegはニコ動と相性が悪い?

というか、ニコニコ動画のほうが制限かけすぎな感じがする。
ffmpegで作ったflvファイルは、再エンコされたかと思ったら、ファイルヘッダがおかしいといわれ終了。
再エンコありきで考えて、画質の出来るだけ良い動画をそのままうpするのが手っ取り早いけど、それをやると負けかなと思っている。

やっと作った動画をうpようとしたらこんな風に弾かれて、時間だけ消費して悲しくなった、という記事。

<追記>
解決しました。
ffmpegでニコニコ動画用のmp4動画を作る

2008年8月9日土曜日

Wine1.0入れてみた

UbuntuのSynapticでいつの間にかWineのver1がインストールできるようになってたので入れてみた。

……入れてみたのはいいが、別にWinのアプリケーションで動かしてみたいものなんて無かったので、宝の持ち腐れ。
しかも、従来のWineでの日本語入力を可能にする方法が、ver1は使えない(?)らしい。

Win用のゲームを適当にひっぱってきたが、画面遷移がもたつくことを除けばけっこう動く。

そういえばmixiGraphはやはり動かないみたい。アレのソース公開してくれないかなぁ。

2008年8月8日金曜日

ニコニコ動画にアップしてみた



sm4171553:コマンドプロンプトでネギを振らせてみたを見て作り始めたはいいものの、いろいろ面倒くさかった……

初めはRubyでHachuneMikuクラスでも作ってやろうと思ったんだけど、RubyのCursesで2バイト文字が扱えないらしく、Cでガリガリ書くことに。

この記事の日付が8月8日で、動画は9日の00:24になってますが、キニシナイキニシナイ。

2008年8月7日木曜日

Linuxで"使える"動画編集ソフトが欲しい

"使える"という言葉は、"使うことが出来る"と"役に立つ"という2つの別の意味が解釈できる。この2つの言葉は意味が全然違うので、日本語って難しいなぁと思う。

で、俺は今後者の意味で"使える"動画編集ソフトが欲しいのです。
Kdenliveというのをインストールしてみたが、まだver1にもなってない開発中のソフトなので、不安定でとても使えたものじゃなかった。でも、Kdenliveが提供する機能はかなり充実しているので、早くメジャーヴァージョンをアップしてほしい。

英語版WikipediaでList of video editing softwareという記事を見つけたので、メモ。
http://en.wikipedia.org/wiki/List_of_video_editing_software

2008年8月6日水曜日

C言語のNcursesで日本語を扱う

Ncursesというのは端末をいろいろ操作するライブラリ。昔、同様のCursesというのがあって、Ncurses(New Curesesの意味)はその後継。
端末上でグリグリ操作するようなアプリケーションは、これを使わなければ実現できない。端末上で動作するviやEmacs、nanoなんかのコマンドラインエディタ(テキストエディタ)もこれを使って実装してあるんだろう。

RubyやPythonなどのスクリプト言語などでもNcurses(またはCurses)が使えるようになってたりする。

C言語でNcursesを使う場合、まずinitscr()で初期化し、最後にendwin()で後処理をする。
これで、addstr()などで端末上の好きな場所に文字列を表示したりできる。
Ncursesは標準のライブラリでないので、コンパイル時にgccには-lncursesオプションを付けなければならないので注意。

そして、日本語(2バイト文字)を扱う場合はちょっと1手間必要なので、ここに書いておく。

まず、ダメな例。1秒間「ほげほげ」とだけ表示して終了するプログラム。
#include <ncurses.h>
main(){
initscr();
addstr("ほげほげ");
refresh();
usleep(1000000);
endwin();
}

これだと、「ほげほげ」が文字化けしてしまう。

日本語(2バイト文字)に対応させるには次のようにコードを書き、なおかつgccには-lncursesオプションではなく-lncurseswオプションを付ける。(末尾にwを付加)
#include <ncurses.h>
#include <locale.h>
main(){
setlocale(LC_ALL,"");
initscr();
addstr("ほげほげ");
refresh();
usleep(1000000);
endwin();
}

これだと、日本語(2バイト文字)が扱える。

wはwide charactorの意味。Ncursesを2バイト文字に対応させたもので、Ncurseswという。

NcursesとNcurseswは別のパッケージとして配布されているので、自分の環境を要確認。
UbuntuのSynapticだとNcursesはlibncurses5,libncurses5-devというパッケージ名。Ncurseswはlibncursesw5,libncursesw5-devだった。

ちなみに、RubyではまだNcurseswには対応していないらしい。そのせいでRubyで書こうと思っていたプログラムを、今Cで書いているのです。。。


<追記>
コードの < と > をエスケープし忘れてたのを直しました。

2008年8月5日火曜日

Rubyについて

最近Rubyをごにょごにょやっているのだけど、はてなのRubyに関する記述がかなり充実していて驚いた。
http://d.hatena.ne.jp/keyword/Ruby

こまった時は取り合えずここ見りゃいいな。うん。

2008年8月4日月曜日

Ubuntuでリポジトリの最適なダウンロードサーバを見つける

なんだか、ダウンロードサーバが不調なのかわからないが、一部のパッケージがアップデート出来なくなっていた。

ちょうどu-bonさんのblogで解決方法が紹介されていたので実践してみた。
http://viva-ubuntu.net/?p=808

簡単に言えば、サーバは複数あるのでダメなら他のサーバを選んでやればいいってこと。基本的には、ntpのサーバみたいにネットワーク的に近いところを選ぶべきなんだろうけど、次の方法で自動で最適なサーバを見つけてくれるので、アップデートエラーになったりしたときには試してみるべき。

まず、パネルメニューから システム > システム管理 > ソフトウェアソースを開く。(software-properties-gtkが開く)
そして、ダウンロード元サーバを選ぶリストボックスで「その他」を選択。


国別のサーバ一覧ウィンドウが出てくるので、ウィンドウ右上の「最適なサーバを探す」ボタンをクリック。


最適なサーバを検索中。。。


検索が終了すると、最適なサーバが選択された状態になっているので、右下の「サーバの選択」ボタンをクリックして終了。


これを行った後に、アップデートを実行するとすんなり完了した。

だが、試しにサーバを「メインサーバ」に戻して再度アップデートを実行すると別のパッケージの更新が落ちてきた。サーバによって最新のパッケージが同期されるまで時間差があるのか、たまたまタイミング良くパッケージが更新されたのか。。。

2008年8月3日日曜日

端末でネギを振らせる


ニコ動でこんな動画を見つけて、簡単過ぎるだろ。。。と思い、なんとなくRubyで書き直してみた。


#/usr/bin/env ruby
loop do
print "\r・.・ y"
$stdout.flush
sleep 0.25
print "\r・.・_"
$stdout.flush
sleep 0.25
end


だが、sleepを使おうとすると何故かprintで何も表示されないままになってしまう。Google先生に聞いてみると、同様の症状があるらしく、標準出力の内容がバッファに溜まりつづけてるらしい。というわけで、$stdout.flushで強制的に出力させている。
これって、Rubyの仕様なのかしら? "にわか"なのでよく分からない orz

2008年8月2日土曜日

カウンタ設置してみた

ブログ開設からいつの間にやらひと月経ったので、記念(?)にカウンタを設置してみた。
まぁ、ほとんど回らないだろうけど。。。

べっ、別にネタが無かった訳じゃないんだからねっ!

2008年8月1日金曜日

Pidginを起動時に実行

インスタントメッセンジャーをPC起動時に実行させる人は多いと思う。
Windowsで言うスタートアップみたいなことを、Ubuntuではgnome-session-propertiesで出来る。

パネルメニューからは、システム > 設定 > セッションで開くことが出来る。これで、PCの起動時(厳密には違うけど)に実行するプログラムを指定できる。

ここで、追加ボタンを押して新たに、起動するプログラムを設定すればいい。


ここで注意なのが、指定するコマンドとしてpidginではなく、フルパスで/usr/bin/pidginとするべきだということ。
なぜかpidginと指定しただけでは、実行こそしてくれるがpidginで日本語入力が出来ない状態になってしまった。
しばらくこれでハマっていたのだが、ググってみて他のユーザが/usr/bin/pidginとしているのを見て試してみたらドンピシャだった。


<追記>
この方法でもやっぱり、IMEがダメになる場合があった。この記事書いたときに上手くいったのはたまたまだったのかなぁ。。。