Mac OSX 10.9 に kivy をインストール

以前作った Python2.7 の virtualenv 環境に kivy をインストールしてみる。

cython

普通に pip でインストールに成功するが、後の kivy のインストールでエラーを起こす。

https://groups.google.com/forum/#!topic/kivy-users/WQCDgk9cTRc

の記事に従い、古いバージョンを明示的にインストールする。

pip install -Iv http://cython.org/release/Cython-0.20.2.tar.gz

pygame

pygame / pygame / issues / #82 - homebrew on Leopard fails to install — Bitbucket

の記事に従ってインストール。

brew install sdl sdl_image sdl_mixer sdl_ttf portmidi
pip install hg+http://bitbucket.org/pygame/pygame

kivy

pip install kivy

インストールは成功した。virtualenv 環境の share/kivy-examples フォルダーに

Examples — Kivy 1.9.0-dev documentation

で説明されているサンプルがインストールされているので動作を確認できる。カメラアプリ等、一部のサンプルは動作しなかった。原因は未確認。

Final Cut Pro X でホームビデオ編集

子供の幼稚園イベントで撮ったビデオを編集するときくらいにしか使わない Final Cut Pro X。毎回使い方を微妙に忘れてしまっているので記録しておく。

マルチカム編集

ビデオカメラと一眼カメラ(のビデオ機能)の2台体制で撮った場合、マルチカム編集機能を使うと便利。

マルチカムクリップの作成
  • クリップを複数選択して右クリック→新規マルチカムクリップ

マルチカムクリップができるので、タイムラインに貼り付ける。

アングル選択

マルチカムクリップ内のどのクリップを採用するかはアングルビューアで決定する。アングルビューアが表示されていない場合は

  • ウィンドウ→ビューアの表示→アングルを表示

で表示する。映像と音声を独立して選択できる。編集点を決めた状態で、アングルビューア内の左上のボタン3種(映像と音声、映像のみ、音声)のうちどれかを選び、選択したいクリップをクリックする。

写真の貼りこみ

右側にあるカメラのアイコンから iPhoto にある写真を貼り込める。iPhotoで先に写真を選んでおいてアルバムに入れておく。アルバムに入れた写真を全部貼りこむと楽。動画の最後に写真を連続して貼りこんで曲をつける。曲の長さを調べておいて、貼り込んだ写真の枚数で割って1枚あたりの長さを決める。写真を全部選択して右クリックして「継続時間を変更」をクリック。1枚あたり7.5秒であれば、(1秒は約30フレームなので)715と入力する。 その後、写真ごとに Ken Burns エフェクトをかけるとそれなりの感じになる。プレビュー画面の左下隅にあるポップアップメニューから「クロップ」を選択し、プレビュー画面をクリックすると、下に「トリム」「クロップ」「Ken Burns」が表示される。「Ken Burns」をクリックする。「開始」の枠と「終了」の枠を適当に動かす。

NHK-FM ロジャー・ニコルス特集のプレイリスト

2015年1月2日と3日に NHK-FM で「カーペンターズのヒットを作った男〜ロジャー・ニコルスの軌跡」という濱田高志さんの番組が放送されました。プレイリストを探してみましたが見つからなかったので記録しておきます。

第1夜(1/2)

第2夜(1/3)

  • Show Your Love - Roger Nichols & The Small Circle Of Friends
  • Let Me Be The One - Cathy Carlson
  • Footprints On The Moon - Judy Lynn
  • I Can See Only You - Al Martino
  • I'm Gonna Find Her - Steve Lawrence
  • I Never Had It So Good - Barbra Streisand
  • Someday Man - Georgie Fame
  • The Age Of Astrology Part 2 - Johnny Magnus
  • When Love Is Near - Sands Of Time
  • Roger Nichols Medley - Roger Nichols
    • The Drifter
    • Girl With A Complicated Heart
    • Love So Fine
    • Always You
    • Rainy Days And Mondays
    • I Won't Last A Day Without You
    • We've Only Just Begun
  • Now - Carpenters

と、ここまで書いた後で気づいたのですが NHKネットクラブ 番組表ウオッチ! で、過去の番組のプレイリストが調べられるんですね。せっかくなので下に転記しておきます。 あと、エンディングのバックでかかっていたのは The Drifter - Pisano & Ruff だと思いますが、オープニングの方はわかりませんでした...。

 - 第1夜 -                      
                              
「愛のプレリュード」           (カーペンターズ)
                       (3分07秒)
        <A&M RECORDS D25Y3275>
                              
「ドント・テイク・ユア・タイム」(ロジャー・ニコルス&   
          ザ・スモール・サークル・オブ・フレンズ)
                       (2分30秒)
      <UNIVERSAL UICY-75172-3>
                              
「ラヴ・ソー・ファイン」(ロジャー・ニコルス&       
          ザ・スモール・サークル・オブ・フレンズ)
                       (2分01秒)
      <UNIVERSAL UICY-75172-3>
                              
「オールウェイズ・ユー」         (リンダ・ボール)
                       (2分21秒)
               <JERDEN JD-816>
                              
「イッツ・ハード・トゥ・セイ・グッバイ」          
                 (クロディーヌ・ロンジェ)
                       (3分14秒)
        <A&M RECORDS D25Y3275>
                              
「ザ・ドリフター」         (ハーパース・ビザール)
                       (3分01秒)
     <WARNER BROS. WPCR-27844>
                              
「トーク・イット・オーヴァー・イン・ザ・モーニング」    
                      (アン・マレー)
                       (2分30秒)
             <東芝EMI CP32-9027>
                              
「ビター・ハニー」        (フォー・フレッシュメン)
                       (2分27秒)
             <LIBERTY LP-8852>
                              
「アウト・イン・ザ・カントリー」 (スリー・ドッグ・ナイト)
                       (3分09秒)
               <MCA UICY-1125>
                              
「アイ・ケプト・オン・ラヴィング・ユー」          
    (ロジャー・ニコルス&               
          ザ・スモール・サークル・オブ・フレンズ)
                       (2分27秒)
           <VICTOR VICP-64023>
                              
「モーニン・アイル・ビー・ムーヴィン・オン」        
                   (カレン・ブライアン)
                       (3分07秒)
            <A&M RECORDS 1071>
                              
「ザ・ワン・ワールド・オブ・ユー・アンド・ミー」      
                   (ロジャー・ニコルス)
                       (2分57秒)
       <KING RECORD KICS 1756>
                              
「タイムズ・オブ・ユア・ライフ」   (ジョアンナ・ウォン)
                       (3分17秒)
            <SONY 88697571052>
                              
「ルック・アラウンド」       (クリスティナ・ミニス)
                       (3分50秒)

 - 第2夜 -                      
                              
                              
「ショウ・ユア・ラヴ」(ロジャー・ニコルス&        
          ザ・スモール・サークル・オブ・フレンズ)
                       (3分35秒)
           <VICTOR VICP-75089>
                              
「レット・ミー・ビー・ザ・ワン」  (キャシー・カールソン)
                       (3分14秒)
                  <MGM K14333>
                              
「フットプリンツ・オン・ザ・ムーン」   (ジュディ・リン)
                       (3分33秒)
                 <MGM AMT 149>
                              
「アイ・キャン・シー・オンリー・ユー」(アル・マルティーノ)
                       (2分50秒)
             <CAPITOL ST-2983>
                              
「アイム・ゴナ・ファインド・ハー」(スティーヴ・ローレンス)
                       (2分44秒)
                <RCA VPS-6050>
                              
「アイ・ネヴァー・ハッド・イット・ソー・グッド」      
                (バーブラ・ストライサンド)
                       (3分35秒)
           <COLUMBIA CK 33815>
                              
「サムデイ・マン」          (ジョージ・フェイム)
                       (2分32秒)
                  <CBS S 5131>
                              
「ジ・エイジ・オブ・アストロロジー・パート2」       
                   (ジョニー・マグナス)
                       (2分59秒)
           <WARNER BROS. 7347>
                              
「ホエン・ラヴ・イズ・ニア」    (サンズ・オブ・タイム)
                       (2分59秒)
               <DECCA F 13272>
                              
「ロジャー・ニコルス・メドレー」   (ロジャー・ニコルス)
                       (9分13秒)
                              
「ナウ」                 (カーペンターズ)
                       (3分50秒)
       <A&M RECORDS UICY-3019> 

Python ebooklib のインストール

epub ファイルを編集する Python パッケージ ebooklibOSX 10.9 にインストールした時のメモ。

基本的には

pip install ebooklib

でインストールできるが、依存関係でインストールされる six, lxml パッケージのうち lxml のインストール時にビルドエラーが出た。

fatal error: 'libxml/xmlversion.h' file not found

調べてみたところ、以下のようなページを発見。libxml2 のファイルが置いてあるフォルダーをインクルードパスに追加してやれば良いようだ。

Installing lxml on Mavericks

Compiling or using libxml using C on OSX - Stack Overflow

xml2-config コマンドでインクルードパスを調べた。

xml2-config --cflags
-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2

環境変数にインクルードパスを追加した状態で lxml パッケージを再インストール。

export C_INCLUDE_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2:$C_INCLUDE_PATH
pip install lxml

これでインストールは成功した。

Python virtualenv

OSX 上の Python で(インストール済みパッケージ等の)環境を切り替えられるよう、 virtualenv をインストールする。複数Python バージョンをインストールし、それを切り替えるための pyenv というものもあるようだが、pyenv と virtualenv のそれぞれで切り替えを行うのは面倒だと思ったので pyenv は使用しない。

まず pip をインストールして、pip を使って virtualenv をインストールする。

curl -LO https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
sudo pip install virtualenv
mkdir ~/.virtualenv

Windows では virtualenvwrapper が使用できないようだ。職場の Windows 環境と合わせるため、ここ(OSX)でも virtualenvwrapper なしでやってみる。 OSX Marvericks では python2.5, 2.6, 2.7 が標準でインストールされている。それぞれ仮想環境を作ってみる。 まず Python2.5。

cd ~/.virtualenv
virtualenv --python=/usr/bin/python2.5 py25

"ERROR: this script requires Python 2.6 or greater." というエラーが出た。残念ながらこのバージョンの virtualenv は Python2.5 をサポートしないようだ。

virtualenv --python=/usr/bin/python2.6 py26
virtualenv --python=/usr/bin/python2.7 py27

はそれぞれエラーなく実行できた。py26 環境に切り替えるには

. ~/.virtualenv/py26/bin/activate

を実行する。Python3 の環境も作ってみる。Python3 は homebrew でインストールする。 XCodeApp Store からインストールした後、

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

で、homebrew をインストールした。その後、

brew install python3
virtualenv --python=/usr/local/bin/python3.4 py34

で Python3.4 およびそれ用の仮想環境を作った。

今作った仮想環境に簡単に切り替えられるよう ~/.bashrc に

alias py27='. ~/.virtualenv/py27/bin/activate'
alias py34='. ~/.virtualenv/py34/bin/activate'

と書いておいた。これで

py27         <--- Python2.7 環境に切り替え
deactivate   <--- virtualenv 環境から抜ける
py34         <--- Python3.4 環境に切り替え

できる。virtualenvwrapper があれば deactivate は不要になるようだが、とりあえずこれでやってみる。

Windows リモートデスクトップ 同一アカウントでのデフォルトプリンターの扱い

リモートデスクトップサービスに対して同一のアカウントで同時に2セッションログインした時に、片方のセッションでデフォルトプリンターを切り替えたらどうなるかの実験。 Windows 2012 + xfreerdp では以下のようになった。

実験結果

2セッションともプリンターのリダイレクトを行っていない場合

他のセッションのデフォルトプリンターも切り替わった。

2セッションともプリンターのリダイレクトを行っている場合

他のセッションのデフォルトプリンターは切り替わらなかった。

片方のセッションだけプリンターのリダイレクトを行っている場合

リダイレクトをしている側のセッションのデフォルトプリンターを切り替えると、他方のセッションのデフォルトプリンターも切り替わった。リダイレクトしているプリンターをデフォルトプリンターにすると、他方のセッションのデフォルトプリンターは(そのプリンターは見えていないので)無しになった。 逆に、リダイレクトしていない側のセッションのデフォルトプリンターを切り替えても他方のセッションのデフォルトプリンターは切り替わらなかった。

結論

プリンターのリダイレクトを行っていないセッションは、同一アカウントの他セッションのデフォルトプリンターの影響を受けて自セッションのデフォルトプリンターも切り替わってしまう。

Delphi7 リモートデスクトップ環境でのデフォルトプリンターの取得に関する問題

今日はニッチな話。

過去記事の FreeRDP によるシンクライアントの運用を行う中で、以下の謎の現象に悩まされていた。

  • リモートデスクトップ環境の中で Delphi アプリケーション(Delphi7 でビルド)からデフォルトプリンターに印刷すると、デフォルトではないプリンターに印刷されてしまう。
  • この時、Excel 等のアプリケーションで印刷すると、問題なくデフォルトプリンターから印刷される
  • この現象は必ず起こるわけではないが、一度発生すると何度印刷しても同じ

色々調べたところ、以下のことがわかった。

  • Delphi で、デフォルトプリンターを得るコード(Printers.pas: SetToDefaultPrinter()の中にある)は以下の通り。

    • EnumPrinters() の第1引数に PRINTER_ENUM_DEFAULT を渡してデフォルトプリンターを得る
    • これに失敗した場合は、GetProfileString() でデフォルトプリンターを得る
  • どの Windows のバージョンからかはわからないが、少なくとも Windows 2012 Server では EnumPrinters() でデフォルトプリンターを得ることはできなくなっているようだ(EnumPrinters function (Windows) には PRINTER_ENUM_DEFAULT 引数について触れられていない)

  • そのため、GetProfileString() でデフォルトプリンターを得ることになるが、これは非常に古い API であるため、おそらくリモートデスクトップのようなマルチユーザー環境のことは考えられていないと思われる
  • つまり、GetProfileString() では、後からリモートデスクトップ環境にログインしたユーザーのデフォルトプリンター名が返されてしまう

解決方法

Windows 2000 以降では、GetDefaultPrinter() という API が用意されているのでこれを利用するように Printers.pas を改変する。

interface 部に以下を追加

function GetDefaultPrinterA(pszBuffer: PChar; var pcchBuffer: DWORD): BOOL; stdcall; external 'winspool.drv' name 'GetDefaultPrinterA';

SetToDefaultPrinter() に以下の変数を追加

LBuffer: String;
LSize: DWORD;

同じく

EnumPrinters(PRINTER_ENUM_DEFAULT, nil, 5, PrinterInfo, ByteCnt, ByteCnt, StructCnt);
if StructCnt > 0 then
  Device := PrinterInfo.pPrinterName
else begin
  GetProfileString('windows', 'device', '', DefaultPrinter, SizeOf(DefaultPrinter) - 1);
  Cur := DefaultPrinter;
  Device := FetchStr(Cur);
end;

コメントアウトし、代わりに以下を追加。

SetLength(LBuffer, 255);
LSize := Length(LBuffer);
GetDefaultPrinterA(PChar(LBuffer), LSize);
Device := PAnsiChar(LBuffer);

とりあえずこれで正しく動作するようになった。Windows95/98 をサポートするには少し変更する必要があるが、さすがにもう良いような気がする...。