Tumblelog by Soup.io
Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

December 30 2011

2011年を振り返る

執筆

今年の目標、というかここ1,2年の目標で「本にモノを書いて自分が得た知見、考えをもとに価値を提供する」みたいなものをずっと考えていました。それがひょんな所からかなって、Web+DB PRESS vol.66で記事を書かせていただきました。

今回の記事の後も技評の稲尾さんとは仲良くさせていただいているので、今後もいろいろ僕なりのものを提供し続けられればな、と思っています。

仕事

仕事については、全体として良くも悪くも個人的にはスカっとできない感じがずっと続いていたと思います。。

一方で、震災の時にやった「限られた食材で工夫」の話だったり、ここ最近のいろいろ責任が増えた中でリリースしたものだったり(割といい数字が出た)を振り返ると、やっぱり自分は追い込まれてる時のほうがいい結果が出やすいのかなぁと感じています。縛りのある中の方がパフォーマンスが出やすいというか。

どんな時でもお前なんとかしろよ、な話ではあるかと思いますが、2012年は縛りをいい感じに自分でうまく設定して、パフォーマンスを上げていきたいですね。

プライベート

gem初めて作ったのはいい経験でした。

同じように、最近YouTube絡みのコードも書きました。

それぞれニッチなとこを狙ったものではありますが、自分も日常的に使うものになってるし、音楽に絡むコードを書く楽しさはこれらのコードを書くことを通じて再確認したので、来年もこんな感じのコードは書き続けたいな、と。

2012年

仕事でもっと圧倒的な結果を出したいですね!!!!1 それを元にして自分の知見だったり考えだったりをもっと外に広げたい、サービス開発エンジニアとしてはこれはやっぱり一番強く思っています。あと、仕事以外では、デバイス絡みでなんか作りたいと思っています。思っているというか構想はあるので、少しづつそれも実現していきたいですね。(最近また復活してきましたが)blogももっと書きますぞ!

と、いうわけで来年もよろしくお願いします!

Tags: diary

December 29 2011

YouTubeの音声をiTunesに転送する

年の瀬になんかちゃっちゃと作りたかったので、単機能musicalみたいなtaifuというスクリプトを書きました。

これは何���

YouTubeでかっこういい動画を見つけたときに、iTunesで音だけでも聴きたい���な時は割とあるかと思いますが、それを実現するスクリプトです。実行権限を追加して

taifu http://www.youtube.com/watch?v=KPWfBfFFrwsx

で、wavデータを標準のエンコーダ設定でエンコードして何事もなかったようにiTunesに追加します。���要VLC.app���

タグ情報はどうなってるの���

「TAIFU_NAME」「TAIFU_ARTIST」「TAIFU_ALBUM」の名前でタグ付けされているので、iTunes上から「TAIFU」で検索したら追加された曲が見つかるはずです。あとは自分の好みのタグ情報に更新ください。オプションで渡すことも考えたけど、iTunes上で編集したほうが楽だったのでやめました。

「あーこれいつでも聴いていたいな〜」なものを見つけたとき、ご利用ください���

Tags: ruby

December 23 2011

WEB+DB PRESS vol.66に寄稿しました

Webエンジニアの教科書的存在であるWEB+DB PRESSですが、本日12/23に発売のvol.66でのクックパッド特集で寄稿させていただきました。

第三章「ユーザを向いたものづくり」が僕の担当です。サービス開発の進め方について余すこと無くクックパッドでのプロセスを全部まとめています。ユーザを徹底的に向いた開発手法について興味のある方は是非一読ください。

僕以外の記事もインフラ、開発基盤、スマートフォン開発、DevOpsと多岐に渡る分野の内容になっていて、かなり面白い内容になっていると思います。

読もう��� WEB+DB PRESS���

Tags: book

November 26 2011

rb-appscriptを利用してwavデータを自動的にiTunesにタグ情報付きでエンコード、ライブラリに追加

musical 0.0.2リリース

musicalの0.0.2をリリースしました。(インストールなんかの細かい話はこちら)

リッピングしたwavデータを自動的にiTunesのエンコード設定(mp3/AAC/Appleロスレス...)に従ってエンコードし、アーティスト名とDVDタイトル名を与えることでタグ情報付きでライブラリに追加します。たとえばDVDをドライブに入れた状態で、次のように実行します。

musical --title "TOUR あいのわ" --artist ハナレグミ

そうすると、

  1. チャプタごとにvobでリッピング
  2. wavに変換
  3. iTunesライブラリにwavを追加
  4. エンコード設定に従ってタグ付きでエンコード

の順に処理がすすみ、最終的にはiTunesのライブラリにこのように取り込まれます。

各チャプタのタイトルは今は自動にタグ付けする仕組みはないので、そこは自前で編集を。ここもうまく自動化したいのですが、DVD自身にはトラック情報を持っていないので、amazonなりから情報をうまく吸い出すなりいい方法を模索してます。

--title, --artistを与えない場合は、それぞれ「LIVE」「ARTIST」の名前でタグ付けされます。また、半角スペースを挟む情報の場合(上の例だと、「TOUR あいのわ」)は、「"」と「"」で囲って渡してあげます。

rubyからiTunesを操作

iTunesを操作する処理については、rb-appscriptを利用しています。rb-appscriptは、AppleEventをブリッジしてrubyから扱えるようにしたライブラリで、AppleScriptに対応したアプリケーションは、全て制御することができます。

一見、すごく便利で万能すぎるように思えるんですけど、ドキュメントが全くないのが辛いとこ。(単純にファイルをライブラリに追加するだけでも相当苦労しました。) 基本的に、method_missingで実装されているので、APIを把握してないと何も開発できません。。最初は、AppleScriptのAPIをdeveloper.apple.comからAPIを探しまくってたのですが、全然見つからなくて途方に暮れてたら意外にも手元にすでに存在してました。

「アプリケーション」「ユーティリティ」から「Appleスクリプトエディタ」を起動し、「ウィンドウ」>「ライブラリ」から「iTunes」を選択すると、AppleScript用のAPIが表示されます。(ちなみに裏技的に、Appleスクリプトエディタのアイコンに、iTunesのアイコンをD&Dしてもこのライブラリウィンドウは起動します。すごい使いづらいですけど。。)

これを元に、上で述べたファイルを追加+エンコードの基本的な操作をまとめるとこんなかんじになります。

見てわかる通り、割と直感的な操作が可能になっていると思います。基本的にはgetで情報を取得、setで更新し、このときにAppleEventが発行されています。(なので、できるだけget/setの数は減らすほうがイベント発行の節約になって、パフォーマンスが上がる)

また、普段irbやpryなんかで簡単な操作をしているときに、APIを確認するまでもなく、ざっとプロパティを確認することくらいはもうちょっと手軽な方法で確認できます。ASDictionaryをインストールしておくと、各オブジェクトに対してhelpメソッドを利用できます。たとえば、現在iTunes上で選択中のトラック、current_trackには次のようなプロパティが存在することを確認できます。

$ pry
[1] pry(main)> require 'appscript'
=> true
[2] pry(main)> include Appscript
=> Object
[3] pry(main)> its = app("iTunes.app")
=> app("/Applications/iTunes.app")
[4] pry(main)> its.current_track
=> app("/Applications/iTunes.app").current_track
[5] pry(main)> its.current_track.help
==============================================================================
Help (-t)

Reference: app("/Applications/iTunes.app").current_track

------------------------------------------------------------------------------
Description of reference

Property: current_track (r/o) : track -- the current targeted track


Terminology for track class

Class: track -- playable audio source
  Plural:
    tracks
  Inherits from:
    item (in iTunes Suite)
  Properties:
    container (r/o) : reference -- the container of the item
    id_ (r/o) : integer -- the id of the item
    index (r/o) : integer -- The index of the item in internal application order.
    name : unicode_text -- the name of the item
    persistent_ID (r/o) : string -- the id of the item as a hexidecimal string. This id does not change over time.
    album : unicode_text -- the album name of the track
    album_artist : unicode_text -- the album artist of the track
    album_rating : integer -- the rating of the album for this track (0 to 100)
    album_rating_kind (r/o) : :user / :computed -- the rating kind of the album rating for this track
    artist : unicode_text -- the artist/source of the track
    bit_rate (r/o) : integer -- the bit rate of the track (in kbps)
    bookmark : short_float -- the bookmark time of the track in seconds
    bookmarkable : boolean -- is the playback position for this track remembered?
    bpm : integer -- the tempo of this track in beats per minute
    category : unicode_text -- the category of the track
    comment : unicode_text -- freeform notes about the track
    compilation : boolean -- is this track from a compilation album?
    composer : unicode_text -- the composer of the track
    database_ID (r/o) : integer -- the common, unique ID for this track. If two tracks in different playlists have the same database ID, they are sharing the same data.
    date_added (r/o) : date -- the date the track was added to the playlist
    description : unicode_text -- the description of the track
    disc_count : integer -- the total number of discs in the source album
    disc_number : integer -- the index of the disc containing this track on the source album
    duration (r/o) : short_float -- the length of the track in seconds
    enabled : boolean -- is this track checked for playback?
    episode_ID : unicode_text -- the episode ID of the track
    episode_number : integer -- the episode number of the track
    EQ : unicode_text -- the name of the EQ preset of the track
    finish : short_float -- the stop time of the track in seconds
    gapless : boolean -- is this track from a gapless album?
    genre : unicode_text -- the music/audio genre (category) of the track
    grouping : unicode_text -- the grouping (piece) of the track. Generally used to denote movements within a classical work.
    kind (r/o) : unicode_text -- a text description of the track
    long_description : unicode_text
    lyrics : unicode_text -- the lyrics of the track
    modification_date (r/o) : date -- the modification date of the content of this track
    played_count : integer -- number of times this track has been played
    played_date : date -- the date and time this track was last played
    podcast (r/o) : boolean -- is this track a podcast episode?
    rating : integer -- the rating of this track (0 to 100)
    rating_kind (r/o) : :user / :computed -- the rating kind of this track
    release_date (r/o) : date -- the release date of this track
    sample_rate (r/o) : integer -- the sample rate of the track (in Hz)
    season_number : integer -- the season number of the track
    shufflable : boolean -- is this track included when shuffling?
    skipped_count : integer -- number of times this track has been skipped
    skipped_date : date -- the date and time this track was last skipped
    show : unicode_text -- the show name of the track
    sort_album : unicode_text -- override string to use for the track when sorting by album
    sort_artist : unicode_text -- override string to use for the track when sorting by artist
    sort_album_artist : unicode_text -- override string to use for the track when sorting by album artist
    sort_name : unicode_text -- override string to use for the track when sorting by name
    sort_composer : unicode_text -- override string to use for the track when sorting by composer
    sort_show : unicode_text -- override string to use for the track when sorting by show name
    size (r/o) : integer -- the size of the track (in bytes)
    start : short_float -- the start time of the track in seconds
    time (r/o) : unicode_text -- the length of the track in MM:SS format
    track_count : integer -- the total number of tracks on the source album
    track_number : integer -- the index of the track on the source album
    unplayed : boolean -- is this track unplayed?
    video_kind : :none / :movie / :music_video / :TV_show -- kind of video track
    volume_adjustment : integer -- relative volume adjustment of the track (-100% to 100%)
    year : integer -- the year the track was recorded/released
  Elements:
    artworks -- by index



==============================================================================
=> app("/Applications/iTunes.app").current_track

実際は、さきほどのAppleスクリプトエディタのヘルプ情報から引っ張ってきて表示しているだけですが、都度手元で確認できるのは便利です。ざっとAPI全体を眺めて把握した上で、手元で動かしながら動作を確認するのが開発を進める方法として良さそうです。

今後の予定

当面、次の内容くらいはどうにかしたいです。

  • iTunesのライブラリに追加したとき、変換前のwavファイルをライブラリ上から削除
  • 副音声の扱いを制御
  • テストを追加
  • トラック名を自動追加

あとrb-appscriptめちゃめちゃ可能性を感じるので、こいつでもうちょっと遊んでみたいですね。API見ているだけでムフムフします。。!

Tags: ruby

November 14 2011

Homebrewでffmpegインストール時の"ERROR: libmp3lame >= 3.98.3 not found"を回避

前のエントリで「libmp3lameあたりでコケる」と言ったのですが、そのときの対応方法のメモ。

ERROR: libmp3lame >= 3.98.3 not found

brew install ffmpegしたときのエラーはlibmp3lameが3.98.3以上のものが見つからないというエラーでした。ところが、

$ lame --version  
LAME 64bits version 3.99.1 (http://lame.sf.net)

Copyright (c) 1999-2011 by The LAME Project
Copyright (c) 1999,2000,2001 by Mark Taylor
Copyright (c) 1998 by Michael Cheng
Copyright (c) 1995,1996,1997 by Michael Hipp: mpglib

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.

と、なっているので、lame本体は3.99.1の最新のものがインストールされているようです。要はこいつが認識されていないよう。

最初は、(他の)ライブラリのインストールが失敗していて、正しく認識されないことを疑ったのですが、どうもそうではなさそう。

そもそもどのバージョンとして認識されているのか

インストールされていないことは無さそうなので、一体どのバージョンがインストールされていると見なされているんだろう、、途方に暮れつつも共有ライブラリのバージョンの確認方法がそもそもよくわかりません。。。とりあえず、libmp3lameのインストールされている場所を確認してみます。

$ locate libmp3lame
/usr/lib/libmp3lame.dylib
/usr/local/Cellar/lame/3.99.1/lib/libmp3lame.0.dylib
/usr/local/Cellar/lame/3.99.1/lib/libmp3lame.a
/usr/local/Cellar/lame/3.99.1/lib/libmp3lame.dylib
/usr/local/lib/libmp3lame.0.dylib
/usr/local/lib/libmp3lame.a
/usr/local/lib/libmp3lame.dylib

なんかいっぱい出てきました。下の/usr/local/lib以下のものは、実際はそれぞれ/usr/local/Cellar/lame/3.99.1/以下のシンボリックリンクになっているようですが、一番上のものが何やら疑わしいです。普通、バージョン情報なんかは文字列として埋め込まれている可能性が高いので、stringsで覗いてみると

$ strings /usr/lib/libmp3lame.dylib | less
l3_side->main_data_begin: %i
, 3DNow!
Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)
xr^3/4
3.97
LAME3.97
http://www.mp3dev.org/
32bits
mpg123: Bogus region length (%d)
mpg123: Can't rewind stream by %d bits!
333333?
...

むむむ。LAME3.97とすごい怪しいバージョン番号ぽいものが見えます。。。! では、他のファイルはどうなのかと思い、/usr/local/lib以下のものを調べてみると

$ strings /usr/local/libmp3lame.dylib | less
Error: can't allocate VbrFrames buffer
strange error flushing buffer ... 
Error: MAX_HEADER_BUF too small in bitstream.c 
Internal buffer inconsistency. flushbits <> ResvSize
bit reservoir error: 
...
This is a fatal error.  It has several possible causes:
90%%  LAME compiled with buggy version of gcc using advanced optimizations
 9%%  Your system is overclocked
 1%%  bug in LAME encoding library
LAME %s version %s (%s)
LAME version %s (%s)
...
INTERNAL ERROR IN VBR NEW CODE (986), please send bug report
INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report
maxbits=%d usedbits=%d
3.99.1
L3.99r
http://lame.sf.net
...

おおお、やはりlameのバージョンである3.99.1という文字列が確認できます。やはりこの/usr/local/lib以下のものよりも優先して/usr/lib以下の低いバージョンの共有ライブラリが参照されているようです。試しに、この低い方のものを削除して、brew install ffmpegしなおしてみると

$ brew install --use-gcc ffmpeg
==> Downloading http://ffmpeg.org/releases/ffmpeg-0.8.6.tar.bz2
File already downloaded in /Users/katsuma/Library/Caches/Homebrew
==> ./configure --prefix=/usr/local/Cellar/ffmpeg/0.8.6 --enable-shared --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --cc=
==> make install
/usr/local/Cellar/ffmpeg/0.8.6: 97 files, 55M, built in 5.7 minutes

ビンゴ!やはり低いバージョンのものが邪魔をしていたようです。。。!どういう経路でこの古いバージョンのlibmp3lameが入ってきたのか謎ですが、何かのアプリケーションをインストールしたときに一緒に入って、アプリケーションのアンインストール時に削除されないまま残ったのかもしれません(謎)

まとめ

ライブラリのバージョン依存でインストールに困ったときは、とりあえず

  • locateで該当対象のファイルパスのリストを洗い出し
  • stringsでバージョン確認

な感じでしょうか。ただ、このstringsで確認するあたりが正当法じゃない感じがする。。のですが、もっといいバージョン確認方法があればぜひ教えていただきたいです。

Tags: osx
katsuma
なお、EMI社に所属していたビートルズの記録的なレコードの売上が、CTスキャナーを含めたEMI社の科学研究資金の供給元だったとも考えられるため、CTスキャナーは「ビートルズによる最も偉大な遺産」とも言われている。
コンピュータ断層撮影 - Wikipedia

November 13 2011

katsuma
katsuma
「頑張らなかった自分にお仕置き」と言う女性は実在するのか
Twitter / @nkoz (via rpm99)
katsuma
「五、六年後「プレステ3」を出すころでしょうね。僕は最大のライバルは携帯電話だと考えています。人間の最大の娯楽はコミュニケーションだからです。そのころは携帯電話の形態もかなり変わっているでしょう。挑戦のしがいがありますよ」

「人間発見」1999/07/26日経新聞夕刊より
【神予言】ソニー久多良木健氏、12年前からもしもしゲーの脅威を予見していた!!  : オレ的ゲーム速報@刃 (via tayouji)
katsuma
6517_17c8

xxmessxx:

KYUKYUUKYUUU..

katsuma
katsuma
katsuma
katsuma
katsuma
katsuma
6562_9cf2_390
katsuma
僕は『大地の汽笛』のときは参加しなかったので
プレイヤーの立場で遊ぶことができたんですが、
ちょっと触っただけで、藤野さんがつくった
ダンジョンはわかるんです。
もう・・・独特のクセがあるものですから(笑)。
社長が訊く『ゼルダの伝説 スカイウォードソード』 (via do-nothing)
katsuma
世界中どこにでも差別はあります。日本人が韓国人を差別するといいますが、韓国人の中国人差別はどうだ、と訊くんです。それほど韓国では中国人を差別する。世界でチャイナタウンがないのは韓国だけです。
差別に打ち勝つ、差別を撥ね返すたったひとつの道は、自分たち自身が教養と見識をもって社会貢献する。これしかないんです。私はね、16のときに日本に来て、産みの親は韓国、育ての親は日本と思っています。
NEWSポストセブン|マルハン会長 「それほど韓国人は中国人を差別する」と語る (via wideangle)
katsuma
6563_c063_390
katsuma
Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.