Twitter はじめました

今さらなのですが、Twitterに少し開発情報をのせるようにしました。

理由は、全然開発情報を発信できてないためです。

現在、Medolyの開発は進めているのですが、状態が中途半端なのでブログに書くほどのものでもなく、かといって全く発信してないと全然開発してないと思われそうなので、Twitter側に簡単な情報を少しずつ載せていこうと思っています。

Twitterアカウントは、「@wa2c_medoly」となります。もしご興味があればフォローいただけると助かります。よろしくお願いします。

Twitter アカウント

Scrobbler for KbMedia Player

Medolyと全然関係無いのですが、Windowsアプリケーションを一つ作りました。

Scrobbler for KbMedia Player

プログラムのダウンロードは以下のURLより。

https://github.com/wa2c/scrobbler-for-kbmedia-player/releases

これは、Kobarin様が開発する「KbMedia Player」というメディアプレイヤーアプリケーションで再生中のメディア情報を、Last.fmに通知(Scrobble)するためのアプリケーションです。起動するとタスクトレイに格納され、Windows起動中に常駐します。

使い方は付属のReadme.mdに色々書いてありますが、大して機能も多くないので、何となく感覚で使えると思います。

KbMedia Playerとの通信にはDDEを使用しています。Unicode文字にも対応しているので、文字化け等はないかと思います。

なお、今回はリポジトリにBitbucketではなく、GitHubを使ってます。理由は、Visual Studioが標準でサポートしてて楽だったのと、何となく使ってみたかったからです。あまり深い意味はありません。

以下余談。

何故このようなアプリケーションを作ったのかと言えば、私が昔からWindows上で音楽を再生する際に、このKbMedia Playerを使っていたためです。Medoly開発において、Last.fmへのScrobble用プログラムを開発していたところ、Windowsでも同様の事が行いたくなりました。しかし、KbMedia Playerではそのような機能は無く、それを実現するためのアプリケーションもありませんでした。無いなら作ってしまえ、というわけで実際に作ってしまった次第です。

ちなみに、Medolyの設計思想はKbMedia Playerにだいぶ影響を受けています。Windowsで散々使い続けてきたプレイヤーなので、その不満点を解消したい(歌詞をもっときちんと表示したい、年やアーティストで検索したい、細かい再生順序を制御したい、等)、という発想で作ってたりします。

あと、できることならKbMedia Player同様にプラグインで再生可能メディアを増やすような機能も作りたいと思ってたのですが、Androidの仕様ではちょっと無理そうなのでその辺は諦めてます。

Medoly LRC Lyrics Plugin 1.0.0

Medoly LRC Lyrics Plugin

2017-02-28に、Medoly LRC Lyrics Pluginというプラグインをリリースしました。

本アプリは、LRCフォーマットの歌詞を取得するためのプラグインです。主な機能としては、LRC歌詞の検索、取得、保存、Medolyから自動的に歌詞を取得する機能等です。本アプリは「ViewLyricsOpenSercher」のソースを参考にして、ViewLyrics.com を検索しています。Minilyricsで使われてるサイトなので、検索結果はMinilyricsと同様となります。

検索画面より歌詞の検索をすることができます。Medoly本体より「歌詞検索」を実行することで、現在選択中の曲のタイトルとアーティストで検索することができます。検索した歌詞は、ファイルへの保存および「キャッシュ」への保存を行うことができます。

「キャッシュ」とは、検索条件に一致する歌詞をアプリ内に保存しておく機能で、Medolyから自動的に取得する際に使用されます。Androidのアプリキャッシュとは無関係です。キャッシュ画面から、現在保持してるキャッシュ内容を確認、ファイル保存、削除することができます。

Medolyから「歌詞取得」を実行すると、歌詞を自動的に取得し、Medoly上に表示します。また、プラグイン側で「実行イベント」を「メディア開始」または「再生開始」にすると、該当するタイミングで歌詞を自動的に取得しに行きます。

歌詞の自動取得は、まず最初にメディアのタイトルおよびアーティストに一致する検索条件で保存されたキャッシュが存在するか確認し、存在すればキャッシュの情報を使用します。もし存在しなければ、ViewLyricsのサイトを検索し、自動的にダウンロードします。この時、設定の「優先言語」(第1~第3)が設定されている場合、優先する言語を探索しに行きます。これにより、日本語歌詞なのにローマ字で書かれている歌詞等、期待する内容以外の歌詞を取得することを避けやすくなります。また、ダウンロードされた歌詞は自動的にキャッシュに保存します。

補足情報ですが、アプリ起動直後における自動取得は少し時間がかかります。これは、言語判定に用いられるプロファイル情報を読込むのに時間がかかるためです。歌詞の取得が早かったり遅かったりするのはそのためです。

本プラグインの主な動作は上記のようになります。なお、これらの動作は設定で変更することができます。 (詳細は割愛)

そんな感じで、このようなプラグインを実験的に作ってみました。ソースコードは公開しています。興味がある方は以下の場所にあるのでご自由に。

wa2c / Medoly LRC Lyrics Plugin — Bitbucket

なお、これは自分が勝手に作ったアプリなので、ある日唐突にサイトにアクセス出来なくなる、公開が停止される等のリスクがありますし、自分はその覚悟で作ってます。なので、その辺りを理解できる方のみご利用いただければと思います。

あと、このアプリはAndroid 4.4以降が必要です。古い端末サポートするのが正直面倒くさいので、動作環境を一気に引き上げてます。出来る事なら5.0以降にしたかったのですが、4.4のユーザがかなり多いので、流石に踏み止まりました。

Medoly Ver. 2.9.5, 2.9.6

2017-02-27 Ver. 2.9.5

– プロパティリスト、再生履歴ダイアログリストの見出しを固定
– プラグインメニューを折り畳みリストに変更
– 行内に複数の時間進行が混在する同期歌詞に対応
– 電話ステータス取得権限を削除
– オーディオフォーカスイベント、ヘッドセットイベント見直し
– 一部ダイアログ修正
– notification一部修正
– スクロール処理一部修正
– LRC読み取り処理修正
– その他いくつかの問題修正

プロパティリスト、再生履歴ダイアログリストの見出しを固定

プロパティタブのリストおよび再生履歴ダイアログの見出しにおいて、区切となる見出しが上部に固定されるようにしました。上部に固定される見出しは現在表示している内容に対する見出しで、下部にスクロールしていくと見出しが切り替わります。これは、 StickyListHeadersListView を用いています。

プラグインメニューを折り畳みリストに変更

プラグインのメニューを折り畳み式に変更しました。これは、メニュー内容増えた際にスクロールするのが煩わしかったからです。今後もいくつかプラグインを追加していきたいので、それに備えたという理由もあります。
このメニューの操作は次の通り。

  • アプリアイコン部をタップすると、プラグインが起動します。
  • チェックボックスの切替えをすると、イベントアクションの有効/無効を切り替えます。
  • アプリ名をタップすると、メニューの開閉をします。
  • どこでもいいので長押しすると、該当アプリに関するダイアログを表示します。

行内に複数の時間進行が混在する同期歌詞に対応

これは実にマニアックな機能です。例えば、タイムタグ歌詞において以下のように、1行の中に先頭から末尾に向かって増えていく時間が途中で逆転している歌詞が存在するとします。

[00:01:00]a[00:02:00]b[00:03:00]c[00:04:00]d[00:02:50]e[00:03:50]f[00:04:50]

従来の場合、「先頭から再生時間以下の最大時間までの範囲」の文字に対して再生中を示す色が塗られていました。そのため、2.5秒の再生地点ではa-eの範囲、3秒の再生地点では、a-cの文字が再生中となるという逆転が起こりました。今回の変更によって、3秒地点ではa-cとeが再生中となり、d(=00:04:00地点)は未再生扱いとなります。
該当する歌詞を見かけることは少ないと思いますが、実際にこういった歌詞は存在しますし、作れます。なお、タイムタグ仕様書では、「タイムタグの逆転はあってはならない」と定義しているので仕様範囲外なのですが、まぁ実装できるし、面白いので。LRCフォーマットでも問題ありません。
余談ですが、この対応には歌詞の読取処理を大きく変える必要がありました。その処理は他に比べて負荷がやや大きくなり、消費電力の増加が懸念されたため、その処理が適用されるのは時間の逆転がある行のみとなっています。他は従来通りです。

電話ステータス取得権限を削除

少し前、GoogleからAndroidアプリ開発者に向けて、「[要対応] Google Play デベロッパー ポリシー違反に関わる警告」というメールが届けられました。この内容は、「ユーザの個人情報を読み取る権限を要求するアプリは、Webとアプリ内にプライバシーポリシーを明記しなさい」といった要請が書かれていました。対応期限は3月15日まで。
本アプリでは以前まで、「android.intent.action.PHONE_STATE」(通話状態の読取)という権限を要求していました。この権限があると、電話の着信や発信の状態に加え、電話番号を読み取ることができるため、これが引っかかっていた模様です。
そもそもこの権限は、着信があった際に再生を停止させるためのものでした。私自身は、他人の電話番号なんかにこれっぽっちも興味はありません。そもそもこのアプリ、(今のところは)ネットワーク接続権限が無いですし。個人的には発信・着信はもっとゆるい権限で対応してほしいのですが…。
この要請への対応は2種類ありました。1つはきちんとプライバシーポリシーを掲げること、もう1つは、該当の権限を削除すること。私は後者を選択しました。理由としては、通話状態の検出は代用手段(オーディオフォーカスの切替)で対応できそうだったこと、こういう個人情報に結びつく権限は後々また面倒臭い対応を迫られると予想されること、プライバシーポリシーはアプリ上で目立つように表示しなくてはいけない(恐らく、起動時のダイアログ等)のが鬱陶しかったこと、等が挙げられます。
まぁついでに、せっかくなのでプライバシーポリシーも作成してみました。多分こんな感じで良いのではないかと思います。

余談ですが、このGoogleの方針に従うなら、3/15以降にほとんど更新されていない怪しいアプリが一気に消失するのではないかと思います。

オーディオフォーカスイベント、ヘッドセットイベント見直し

上記の電話ステータス取得権限にも関わるのですが、端末のイベント処理を少し見直しました。具体的には、オーディオフォーカスの変化、ヘッドセットの接続/切断時の動作です。

  • 通話状態の監視は廃止し、オーディオフォーカスの処理に統合しました。
  • ヘッドセットおよびBluetoothの接続/切断イベントを統合しました。

理由は、通話状態の監視を廃止しなければならなかったことと、設定が多すぎて、普通の人に把握が困難であると思われたためです。恐らく、この2種類があれば通常の用途では問題ないと思います。
ちなみに、これを直している最中に、再生開始時のオーディオフォーカス取得が実行されていなかったバグを見つけました。一体いつから…。

一部ダイアログ修正

ダイアログ周りを一部見直しました。あと、Aboutダイアログの中身を少し整理しました。

Notification一部修正

画面上の通知バーに表示される通知の内容で、Android 7.0でアイコンがずれていたのを直しました。これはとりあえずの応急処置です。次のバージョンで見直します。

スクロール処理一部修正

再生画面のプロパティリストで、スクロールがすぐ戻されてしまう問題等の修正です。

LRC読み取り処理修正

LRCフォーマットファイルにおいて、時間が正しく読み取れない場合がある問題を修正しました。一番最初に作ってからずっと手を加えてないはずなので、多分最初から存在するバグです。ちなみにこれは、HUAWEIのP9 Liteという端末に初期状態で保存されている「Dream_It_Possible」という曲に付属されているLRCファイルへの対応です。具体的に言うと、ミリ秒が無いタイムタグの読み取り処理を直してます。

歌詞の影の設定追加

すいません、これ書くの忘れてました。以前のバージョンで歌詞の文字をアウトライン文字に変更しましたが、以前の影表示タイプにも変更できるようにしました。これはユーザ様からの要望です。
メイン画面 – 表示タブ – 表示スタイルにある「外観」タブで切り替えることができます。

その他いくつかの問題修正

その他細かい部分を色々直してます。検索画面のストレージタブを開くとにトップまで戻されてしまう問題とか、プラグインのイベントが動いてなかった問題とか、その他諸々。

2017-03-01 Ver. 2.9.6

– アプリ終了時に状態が保存されない問題修正
– ストレージ書込み権限が取得できない問題修正

アプリ終了時に状態が保存されない問題修正

画面の「アプリ終了」よりアプリを停止すると、状態がリセットされてしまう問題を修正しました。これは、状態が保存がされていなかったのではなく、最後にクリアされた状態が保存されてしまったためです…。
  

ストレージ書込み権限が取得できない問題修正 

Android 7.0でストレージの書込み権限が取得できなくなっていた問題を修正しました。この問題は6.0では起こらなかったような…。

総ダウンロード数が5000を超えました

1/24で、合計ダウンロード数が5000を超えました。

この数値は、総インストール数の合計値なので、複数端末でダウンロードしても同一アカウントの場合は1とカウントされるはずです。公開してから今までだいたい5000人以上がダウンロードしているということです。

この5000という数値は、Google Play上で区切りの数値となります。Google Playのアプリのページでは5000ダウンロードからは以下のように表示されるようになります。

増加率を見ると、驚くほど変化がありません。まぁ徐々に増えているという感じではあります。

ちなみに、開発者向けに公開されているアクティブなユーザ端末数(1ヶ月以内に使用されたインストール端末数)は931台です。この全員が使用しているのかどうかは分かりませんが、アプリをバージョンアップすると800台ぐらいはバージョンアップされていくので、実際にはそれぐらいが利用されているのではないかと思ってます。

そんなこんなで、ぼちぼち開発を続けていきたいと思いますので、今後ともよろしくお願いします。

Medoly Ver. 2.9.0

Ver. 2.9.0

2017-1-21 Ver. 2.9.0
– 表示タブ内のコントロールバー追加
– ストレージアクセス処理変更(Android 7.0対応)
– 編集モードのサムネイルタップで再生/未再生切替え
– 外部ファイルのキュー追加がエラーとなる問題修正
– その他各種修正

表示タブ内のコントロールバー追加

表示タブ内に、コントロールバーを表示するようにしました。可能な操作は、再生コントロールバー(メイン画面最下部のバー)の内容です。

これは、レイアウト設定のチェックボックスをONにした上で、タブ内のボタンを表示状態する必要があります。表示タブのダブルタップまたは、ピンチアウト操作で表示タブを拡大した際、再生コントロールバーが非表示になると、自動的にタブ内に表示します。
これは、画面を最大化した際に再生コントロールボタンが非表示になってしまい、再生操作が行えなかったという問題に対応したものです。
また、コレに合わせて内部のクラス構成を色々弄ってます。もし以前と挙動が変わった部分があれば報告いただけると助かります。

ストレージアクセス処理変更(Android 7.0対応)

ストレージアクセス処理を見直しました。

ユーザストレージ(内蔵ストレージまたは外部ストレージ)のみアクセス可能で、その他にはアクセスできません。これは、最近の端末だとユーザが操作可能なストレージ以外にアクセスすると、エラーとなってファイル操作ができなくなる場合があるためです。
一部端末には、初期状態でユーザストレージ領域外にメディアが配置されているものがありますが(Huawei P9 Liteで、/system/media/Pre-loaded/Music フォルダに「Dream It Possible」という曲が置いてあるのを確認しました。ちなみに、LRCファイル付き。)、今回の変更でストレージからアクセスすることはできなくなります。こうした曲を再生した場合は、タグ情報の検索から取得するようにしてください。

編集モードのサムネイルタップで再生/未再生切替え

再生キューの編集モード時、サムネイルをタップすると、メディアの再生/未再生を切り替えられるようにしました。従来通り、ドラッグ&ドロップによる順序の変更やメディアの削除もできます。

外部ファイルのキュー追加がエラーとなる問題修正

他のアプリからメディアをMedolyに渡した場合、エラーとなる場合があった問題を修正しました。

その他各種修正

その他諸々修正しました。

  • 再生キュー完了時に通知が消せなくなる問題修正。
  • 表示タブのメニューをタップした際にタップ音が2重に鳴る問題修正。
  • 表示タブ内の文字をアウトライン文字に変更。
  • 検索画面でLoading…が表示される条件を、メディア100個以上→500個以上に変更。
  • 検索画面でメディアがない場合のメッセージを追加。
  • ファイル共有の動作一部変更。

Android 7.0におけるストレージアクセス

現在、Android 7.0でMedolyを使用すると、ストレージのフォルダが一部見えなくなる問題があります。これは、Android 7.0においてセキュリティ上の関係か、ストレージのアクセス処理が一部変更になっているためのようです。
また併せて、プロパティから「開く」や「共有」が使用できなくなっている問題も発生しています。これはAndroid 7.0における同様の問題です。

現在対策を練っているところなので、 しばらくお待ち頂ければと思います。正直、Android のストレージアクセス処理はクソ面倒臭いのですが、個人的にもよく利用するため必ず対応します。ただ、一部制限が発生する可能性もありますので、その辺はご了承いただければと思います。

Medoly 課題管理の公開

あけましておめでとうございます。
本年もよろしくお願いします。

唐突ですが、以下のページにMedolyの課題管理ページを公開しました。
ここには、課題、問題点、バグ報告、要望など、何かしら報告があった場合にご書き込んでいただけると助かります。
言語は日本語、英語何れでも構いません。

wa2c / medoly2 / 課題 – Bitbucket
https://bitbucket.org/wa2c/medoly2/issues

現在、ソースコードのリポジトリにBitbucketを利用しているので、そこにあるサービスをそのまま使用しています。bitbucketの利用には、アカウント登録が必要になります (Googleアカウントでもログインできたはず)。

ちなみに、ソースコードは公開されていないのでご了承ください…。

Medoly Ver. 2.8.5


久々の更新となります。難しい更新を行っていたとかそういうわけでもなく、ただ単に他の作業をしていて更新が停滞しているだけです。

Ver. 2.8.5

2016-12-21 Ver. 2.8.5
– 歌詞表示をアウトライン文字に変更
– メディアの長さから再生中アクション実行時間を設定する機能追加
– ウィジットのレイアウト追加・変更
– 言語の変更設定追加
– タブの表示を保持するように変更
– メッセージ一部修正
– ヘッドセット接続時のみ再生を行う設定追加
– シャットダウン時にメディアが破損状態となる問題修正
– 歌詞スクロールが再生位置とずれる問題修正
– 1曲も存在しない場合に検索がエラーとなる問題修正

歌詞表示をアウトライン文字に変更

今まで、歌詞のテキストに影を表示していました。これは、歌詞のテキストが背景に表示されるアルバムアートの内容によって見えにくくならないようにするためのものでした。今回、この影をやめて、アウトライン文字(文字の周囲を線で囲んだ文字、囲い文字、袋文字とも呼ばれる)に変更しました。
変更理由…というか、そもそも3年前の一番最初の開発段階でアウトライン文字にする予定でした。ところが、やり方が分からず断念していたというのが本当のところです。最近、少し落ち着いたところで色々調べていると、MagicTextView というライブラリを見つけ、こちらを参考にしてアウトラインテキストを実装してみた次第です。

変更前

変更後

 

メディアの長さから再生中アクション実行時間を設定する機能追加

プラグインのイベントアクション(自動的に実行されるアクション)に「再生中」イベントというものがあります。これは、メディアをある程度の時間再生し続けると「再生中」であると判断し、イベントを実行します。これは、ザッピング再生や頭出し再生で逐一実行されてほしくないアクションを実行するためのものです。例えば、再生時にTwitterに自動投稿したり、Last.fmに再生中を通知をする、といった使い方を想定しています。
この「再生中」イベントを実行するための時間は、今まで固定時間でした。初期値は30秒です。ところが、これでは30秒未満の曲では実行されません。そこで、今回の変更で全体の再生時間の割合からイベントの実行時間を設定できるようにしました。例えば、4分の曲で50%に設定すると、2分間続けて再生した時点で「再生中」イベントを実行します。(なお、途中で停止した場合はリセットされます。)
加えて、再生終了時点でイベント未実行だった場合は強制的に実行するオプションを追加しています。

ウィジットのレイアウト追加・変更

ウィジェットのレイアウトを追加・変更しています。具体的に言うと、レイアウト構成を1つ追加(4番目)し、従来の1番目のレイアウトと3番目のレイアウトを交換しています。現在のレイアウトは以下の4種類です。全てサイズは可変(最小サイズ:2×1)のため、サイズを変更してご利用ください。

追加したレイアウトは、以下のようなテキストのみのウィジェット表示を想定した物です。(画面のサイズによってはこの通りの表示にならない可能性があります。)

レイアウトの交換については、(旧)3番目のレイアウトは他3つとは少し毛色の異なるレイアウトなので、特別扱いで先頭に持ってきています。

言語の変更設定追加

設定画面に[その他] > [言語]
設定を追加し、言語の変更が行えるようにしました。従来、言語設定はシステム環境の言語設定に応じて変更していましたが、手動で切り替えられるようにしました。
まぁ、今のところは日本語と英語しかありませんが。英語に関しては内容が非常にダメな感じですが…。
 

タブの表示を保持するように変更

アプリをバックグラウンドから再表示した際に、タブの表示(再生キュー、表示、プロパティ)を保持するようにしました。これはどちらかと言えば、保持する方法(起動時に切り替える方法)が分かった、と言った方が良いかもしれません。

メッセージ一部修正

メッセージ内容を一部修正しています。文言の見直しです。

ヘッドセット接続時のみ再生を行う設定追加

設定画面の[操作] > [操作]
に「ヘッドセットのみ再生」を追加しています。これは、イヤホンやBluetoothが接続されていない場合、再生を開始させないようにするための設定です(メッセージが表示されます)。スピーカーから音を鳴らしたくない場合に使用します。

シャットダウン時にメディアが破損状態となる問題修正

従来、端末をシャットダウンした際に、選択中のメディアが破損状態になっていました。これは、シャットダウンの際に、何故か標準のメディアプレイヤーライブラリからエラーが返ってくるためです。何故このような挙動をするのかは知りません。
この対策として、シャットダウン時にシステムからブロードキャストされるシャットダウンメッセージを受信すると、アプリを強制終了する処理を加えました。

歌詞スクロールが再生位置とずれる問題修正

非同期歌詞メディアを再生して、表示タブでスクロール位置を強制的に変更した後、同期歌詞を再生した際に前回の非同期歌詞のスクロール位置がリセットされずに保持されてしまう問題がありました。
長らく謎だったこの原因を究明したところ、メディアが切り替わり、歌詞が切り替わる間に僅かなタイムラグが生じており、その間にスクロールが割り込むと、とリセットされたスクロール位置が現在のスクロール位置で上書きされてしまうために問題が発生していました。
処理の関係上これを変更することが難しかったので、現在選択中のメディア情報を歌詞側に保持しておき、相違があった場合にスクロール位置の設定を無効にするという処理を加えています。

1曲も存在しない場合に検索がエラーとなる問題修正

これは、メディアが1件も存在しない場合に検索画面でエラーが発生するという問題があったため、ちょっと修正しました。まぁ、メディアが1つも存在しない人間がこのアプリを使うか、という話ではあるのですが…。