PythonistaでNowPlayingする時のアートワーク周りで詰まった

お久しぶりです、ちゅん(@Ushigome)です。

最近バイトを始めてニートを脱したのでTwitterスクリーンネームをN_EE_Tから変更しました。

アートワークをpng形式の画像ファイルにする方法がどこにも記されていなかったのでメモ。

 

PythonistaでNowPlayingしたいと思った経緯

iDeviceを使用しているPythonistaはご存知のiOSPythonが出来る「Pythonista 3」の話です。

私は音楽をよく聴くほうの人間なのですが、TwitterでNowPlayingをしたくなるときがあります。

いつも使っているTweetbot4にはNowPlayingをツイートする機能は無く、TheWorldやHel2umを使用しなければなりません。ちょっと不便…

とりあえず検索

Pythonista 3で簡単にNowPlayingがツイートできないかなぁと検索するわけですよ、見つかります。

Pythonista for iOS で Nowplaying する | aoshiman.org

こちらの記事が見つかります。

Now Playing via Pythonista for iOS · GitHub

記事中のGistに上げられているプログラムを使用したいと思います。

動作しない箇所を修正

  1. iOS 11からsocial.frameworkが廃止になったのでPythonista 3に実装されている「twitter」モジュールを「tweepy」に変更
  2. 「iPodMusicPlayer」が廃止されているので「systemMusicPlayer」に変更(参照)
  3. iOS 11のバグかわからないが曲を再生しても「再生なし」と出たり曲変更しても前の曲のデータが取得される場合があるので取得ボタンとツイートボタンの2種類を実装したかったので「ui」モジュールを使ってウィジェットにした(かった)→後述
  4. (本題)アートワークも一緒にツイートしたかったのでゴニョゴニョ→次章

※Todayの所にウィジェットを表示するのが最終目標だったが、外部モジュールをimportしようとするとエラーが発生するので諦めた。アプリ内で実行すると動作するのでそっちで妥協した。

アートワークをpng形式で取得したかった

.valueForProperty_("artwork")で曲名、アーティスト名、アルバム名のようにそのまま画像データが取れると思っていたが型はMPMediaArtworkだった。

.imageWithSize_(CGSize(1000, 1000))でUIImage型に変換。しかしui.Image型とは別物なので「objc_util」モジュールのuiimage_to_png関数でpng形式のbytes型を取得し、「PIL」モジュールを使い保存。

CGSizeの引数1000はとりあえず設定した値なので変更しても問題ありません。

アートワークの画像サイズが1000x1000を下回っていた場合は最大サイズで保存され、上回っていた場合は設定した値のサイズで保存されます。

f:id:chun37:20180622040246j:image

完成

f:id:chun37:20180622040722j:image

実行するとこんな感じ

Getして確認してTweetを押すとツイートされます。

ツイートするとこんな感じです。

作成したプログラムはGistに上げました。

tweetメソッドのtext変数でツイートするテキストのフォーマットを編集してください。

TwitterAPIのKey類はご自分でやってください。

私はiPhone6sを使っているので解像度の違う端末をご利用の方は最後の方のframeあたりの数値を弄ってください。

3DTouch搭載端末をご利用であれば3DTouchのショートカットに設定するとファイルを探して実行する手間が省けるので楽になります。

f:id:chun37:20180622040158j:image

objc_utilは難しい

「objc_util」モジュールは非常に難しいと感じた。

Objective-Cを全く理解していない状況だったがAppleのドキュメントを見て少し理解を進めた。

Pythonista 3の作者様が「objc_util」モジュールを用意してくれたのはありがたいがPythoniOS周りを触るものではないと感じた。

あとがき

これであなたもTwitterにたくさんNowPlayingしましょう。

1ヶ月以上悩んだ末に完成したので私のように悩んで時間を無駄にする人が減ればいいなと思いました。

Todayの所で外部モジュールが使えないのは不便だなあと感じました。