2015-05-29

Medoly Last.fm Scrobbler Plugin リリース

Medolyで再生している音楽情報をLast.fmに送信する「Medoly Last.fm Scrobbler Plugin」を公開しました。

Last.fmは日本ではあまり馴染みが無いかもしれませんが、音楽を主体としたSNSです。 自分の再生している音楽の情報をひたすら上げ続けていくという特徴があり、自分の聞いている音楽を主体としてコミュニケーションを行うサービスです。iTunesやWindows Media Playerといった主要なメディアプレイヤーをはじめとし、多くのアプリケーションでLast.fmに再生中の曲を登録する機能やプラグインが提供されています。Androidサービスに登録されている多くのアプリにも実装されています。
SNSとしての利用では無く、自身の音楽再生履歴を残すために利用している人も多いようです。私も最近、それを目的として使い始めました。
 
このアプリの使い方は、Medoly Twitter Plugin同様簡単で、最初に「アカウント認証」ボタンよりユーザ名とパスワードを入力し、ユーザ認証を行ってください(もちろん、アカウントを持っていくことが前提です)。認証が完了すると、Medolyで再生している音楽情報がLast.fmに送信されます。これはメッセージ編集等は無く、ただ必要な情報のみをLast.fmに送信します。ユーザが行うのは、基本的にこのユーザ認証のみです。
入力されたユーザ名はそのままの状態で、パスワードはハッシュ化して保存されますのでご了承ください。

ちなみにこのアプリを作ったのは、複数のプラグインの同時実行テストがしたかったため、という理由が大きかったりします。とりあえず2つのプラグインが同時に動くことは確認できました。

あと、Google Playへの登録名が30文字までなので、表記が 「Medoly Last.fm ScrobblerPlugin」と、スペースが1文字削られています。今後登録する際は、この文字数上限に気を付けた方が良い、という事は今回分かりました(笑)。

Medoly Twitter Plugin リリース

Medolyで再生している音楽情報をTwitterに送信する「Medoly Twitter Plugin」を公開しました。

使い方は簡単で、アプリを起動した後、「Twitter認証」ボタンを押して、指示に従ってTwitterの認証を完了させてください。(もちろん、Twitterアカウントがある事が前提です。)

認証が完了すると、Medolyで再生している情報が自動的にツイートされるようになります。

送信のタイミングは、デフォルトでは「再生中」イベントのタイミングです。「再生中」イベントのタイミングは、Medoly本体側の設定画面から設定できます。デフォルトは曲の再生を開始して30秒後です。曲を停止すると再生時間はリセットされます。再生を再開した場合、そこから30秒後に再びイベントが発生します。とりあえず、「再生開始」のタイミングでも送信できますが、曲を頻繁に切り替えるザッピング再生みたいな事やってると、その都度ツイートされてしまうためあまりお勧めはしません。

メッセージの内容は「メッセージ編集」 ボタンより変更することができます。Medolyのプロパティとして取得できる情報は全てメッセージに入力できますが、加工されていない生データが送信されてますので、使い物にならないデータが多数含まれています。そこら辺は要望があれば何とかしますが、とりあえず放置です。大体、曲のタイトルとアーティストとアルバムの名前があればいいでしょ?っていうぐらい。プラグインのサンプルモデルみたいな 代物なので、実装は割と適当です。

メッセージ編集で、各データには「優先度」が設定できます。「優先度」とは、140文字の文字数を超過した場合に関係します。140文字を超過した場合、優先度の低い順に文字が削られていきます。「省略可」にチェックが入っている場合、文字数を超過した分だけ、途中で省略します。未チェックの場合、文字数に収まらない場合は全て消去されます。例えばID等の、省略すると意味を為さない項目はデフォルトで省略可のチェックが外れています。

例えばTwitterの文字上限が20文字だったとして、優先度が「タイトル, アルバム名, アーティスト名」の順で、フォーマットが「タイトル - アーティスト名 / アルバム名」のようになっていると、「タイトル - アー... / アルバム名」 のように省略されます。アーティストの省略可チェックが外れていると、「タイトル - / アルバム名」のようになります。ちなみに、フォーマット中に直接書かれた文字は省略されません(それだけで140文字を超過しない限りは)。

文字数上限をオーバーさせないための施策なので考えるのが面倒臭いですが、普通は標準の状態をそのまま使っていただければ良いと思います。

ところでこのアプリ、Ver. 1.0.2で一旦別アプリとして公開し直してます。理由は、Googleに公開停止を食らっているためです。理由を問い合わせたところ、アイコンがマズかったらしいです。Twitterのガイドラインに抵触してたと思われるので、アイコンを再加工して、別アプリとして再公開しています。



 
ちなみに、このようなプラグインを開発したということは、Twitter上のどこかに私のTwitterアカウントが存在するわけですが、その存在についてはあまり気にしないでください…。



2015-05-28

Medoly Ver. 2.0.5, 2.0.6

2015-05-23 Ver. 2.0.5
- 再生キュー登録処理を統一化
- 再生キュー登録オプション設定を追加
- Bluetooth AVRCP 1.3 による曲名表示対応 (Android 4.3以降)
- リモートコントロールを初期状態で有効化
- Lollipopのプライベートロック画面に表示されない問題修正
- その他、各種修正
- BROADCAST_STICKY 権限要求追加


2015-05-26 Ver. 2.0.6
- 再生終了後に落ちる問題修正
- プレイリストの削除時にダイアログが閉じない問題修正


Ver. 2.0.5



再生キュー登録処理を統一化


いくつかある再生キュー登録方法について、登録処理の共通化を行いました。(今までバラバラに実装していたものを統合した感じです)。
登録処理は大まかに分類して、

- 検索画面から登録
- プレイリストを開いて登録
- 再生履歴から登録
- 他アプリから渡された共有メディアを登録

が実装されており、これらを統一した処理で登録されるようにしました。
それに伴い、登録処理の際は全てメッセージが表示されるようになっています(設定でOFFに出来ます)。


再生キュー登録オプション設定を追加


再生キュー登録処理の統一化に伴い、設定画面より各登録処理にオプション設定ができるようにしました。オプションとして登録できるのは

- 追加、更新の選択、または確認表示
- 再生キュー登録済みの内容と重複しているメディアの除外
- 追加されるメディアを対象としたソート(再生キュー登録済みのメディアはソートされません)
- 追加されるメディアを再生(複数追加の場合は、追加されたメディアの先頭が再生)
- メイン画面に戻る(検索画面のみ)

となっています。 また、これらのオプション選択ダイアログを表示させることもできます。ちなみにこのオプション選択、ずいぶん前から検索結果の長押しで表示させる事ができていたのですが、存在が中途半端だったので放置していました。今回改めて実装し直した次第です。

また、検索画面からの登録方法を細かく分類すると、

- 検索メニュー
- 検索結果タップ
- 検索結果長押し

の3種類があり、さらにメニューは3つまで登録できます。 初期状態では、「再生キュー追加」、「再生キュー更新」の2種類で、3つめのメニューは非表示にしてあります。必要に応じて変更・増減させてください。







Bluetooth AVRCP 1.3 による曲名表示対応 (Android 4.3以降)


Bluetoothには、リモート操作を行うためのAVRCPというプロファイルが規定されています。また、このAVRCPにはいくつかバージョンがあり、Ver.1.3よりリモート操作側にメディアの情報を送信できるようになっています。Bluetoothのリモコンに曲名が表示されたりするアレです。
Android 4.3より、このAVRCP1.3による曲名表示に標準対応しています。最近、Bluetoothヘッドセットアダプタ Sony SBH50 を購入したので、正式に対応させてみた次第です。
今までもロック画面の表示設定をONにすると表示されていたと思いますが、きちんと検証したという事で。また、Android 5.0のLollipop以降は実装方法が異なるため、そこは新たに作り直しています。現状、Android 4.3以降であれば表示されるはずです。

ちなみに、Android 4.2以前ではAVRCP 1.3に未対応ですが、端末メーカーが独自に実装している場合があります。自分の所持するXperia UL(Android  4.2.2)で色々試してみたところ、Android標準の音楽プレイヤーや、Walkmanアプリ、Rocket Playerといったいくつかのアプリならリモコン側に曲名が表示されるのは確認しましたが、多くのプレイヤーでは非表示のままでした。自分でもこれを表示させる方法を色々調べてみたのですが、結局よく分かりませんでした。上記で実装した方法はAndroid 4.3以降が対象であるため、Xperiaは何らかの独自実装を行っているものと思われます。
Android標準の音楽プレイヤーのソースコードを弄って確認したのは、MediaPlayerのインスタンスが再生を開始すると曲名が表示されるという事です。それ以外の、外部に曲情報を送信しているものと思しき箇所を片っ端から削除してみましたが、表示に対してはまったく影響を与えませんでした。とにかく、再生を開始した時点で何らかの方法で再生している曲の情報を取得しているものと推測しますが、Medolyで再生している曲を取得させる方法が分かりませんでした。Rokect Playerというアプリで表示できているので、特定のアプリ以外では無理というわけではないと思っているのですが…。

どなたか、これについて情報をお持ちの場合は教えていただけると嬉しいです。また、Xperia以外で、Android 4.3以前にAVRCP 1.3に対応している端末で曲名表示させたいという要望があれば受け付けます。ただし、その実装方法が確実に分かっている場合のみですが。

なお、カスタムOSのCyanogenModをご利用頂いている場合、もしかしたらアーティスト情報の場所にアルバムアーティストが表示されるかもしれません。これは、CyanogenModの挙動なのでご了承ください。アルバムアーティストが存在しない場合は、アーティストが表示されるようにしています。


リモートコントロールを初期状態で有効化


今まで、リモートコントロール設定は初期状態でOFFにしていました。何故ならば、自分は「可能な限り相手の端末に影響を与えたくない」という考え方で作っているからです。
ただ、今回上記のBluetoothリモコンへの曲名表示対応を作っていくにあたり、「やっぱ普通の人には分かりにくいし、めんどいよね」という結論に至り、あっさり宗旨替えです。
というわけで、今回からインストールした時点でロック画面のプレイヤーも占有するし、ヘッドセットのボタンも占有するし、Bluetoothリモコンも占有します(ちなみに、これらの占有処理は一体的な物なので、どれか一つだけOFFにするといった動作は、複雑になりそうなのであまりやりたくないです)。邪魔な人のみOFFにしてください。


Lollipopのプライベートロック画面に表示されない問題修正


Android 5 Lollipop は、ロック画面に通知を表示させることができます。というか、Android 4にあったロック画面専用のコントロールが無くなり、通知によって各種コントロールを行います。
Lollipopはマルチユーザによる利用も想定しています。そのため、ロック画面の通知は非表示にしたり、またはプライベートモードで動作させて、通知がある事だけを表示し、内容は非表示にするといった事ができます。
今まで、Medolyの通知はプライベートモードでの動作となっていました(というか、何も設定しないとそうなります)。音楽再生なんてプライベートモードで動作する必要は全く無いので、パブリックモードで動作させ、ロック画面からコントロールが行えるように修正しました。

 

その他、各種修正

メッセージ文言を修正したり、EclipseからAndrodi Studioに乗換えた際に警告されるようになった箇所の修正等です。



BROADCAST_STICKY 権限要求追加


BROADCAST_STICKYとは、他のアプリにメッセージを送信するための権限です。通常のBROADCASTとは異なり、配信が終了してもメモリ上に残ります。これは、外部のアプリケーションに曲名を通知するために追加しています。
Android の標準音楽アプリは 、再生している曲が変更される度に外部に対して曲名が通知されおり、その際に使用されるのがこの通知方法です。今回、それと同じ通知を外部に対して行うようにしています。比較的多数の音楽プレイヤーが、同様のメッセージを外に投げていると思われます。
世の中には、そのメッセージを受け取って動作するアプリも存在しますので、それが利用できるようになります。未使用の方にとって特にメリットはありませんが、今回ちょっと追加させていただきました。




Ver. 2.0.1


再生終了後に落ちる問題修正


ユーザ様からのエラーレポートから発覚しました。
区間ループを行っている場合、シークバー上のループ区間を示すアイコンの座標計算で0の除算が発生し、再生終了時に落ちる場合があることが分かりましたので、その修正です。
 


プレイリストの削除時にダイアログが閉じない問題修正


プレイリスト操作で、プレイリストの削除を行うっても、ダイアログが閉じなくなっていたので、その修正です。Ver. 2.0.5で行った再生キュー登録処理の統一化の際に、処理が漏れてしまいました。

Medoly Ver. 2.0.0, 2.0.1

2015-05-10 Ver. 2.0.0
- プラグイン機能追加
- 非同期歌詞の自動スクロール機能追加
- 画面タップ時及びスクロール時に歌詞を自動スクロールしないよう変更
- 歌詞の固定オフセット追加
- メディアの対応プロパティ追加
- プロパティタブメニュー項目の変更
- 設定項目の内容を全体的に見直し
- DB登録日時によるソート追加
- 終了ダイアログを表示しないオプション追加
- Bluetoothの接続・切断によるオプション追加
- 画像読込でエラーとなる問題を修正。
- その他、各種修正

開発環境をAndroid Studioに変更しました。

本バージョンより、Bluetooth機器へのアクセス権限を追加しています。


2015-05-13 Ver. 2.0.1
- 再生時にループが終了しない問題修正



Ver. 2.0.0


ついにVer.2.0.0です。 本アプリは2013年12月のVer. 1.0.0から始まり、少しずつバージョンを積み重ねてきました。大体、機能追加で0.0.5、バグ修正で0.0.1上がってく感じでバージョンを変更しています。あまり急激なバージョン番号の上昇はやりたくなかったので、牛歩戦術みたいなバージョンアップを重ねてきましたが、ついに2.0.0まで来てしまいました。思えば遠くに来たもんだ。

せっかくメジャーバージョンが上がるということで、Ver.2.0.0に合せて少し大きめの変更を2件、追加しています。 とは言っても、従来とUIや使い方が変わるわけではありません。使い勝手を買えるのは個人的にあまり好きではないですし、それなりに考え抜いて作ったUIデザインなので、今のUIはずっと続けていきたいと考えています。

また今回に合せて心機一転、開発環境をEclipseからAndroid Studioに変更しています。環境を変えて思ったのは「Eclipseってやっぱ使いにくかったなぁ…」という感想です。もちろん、Android Studioの方がAndroidに特化しているため色々便利な点があるのは当然なのですが、それを差し引いてもEclipseは、重いし、設定が分かりにくいし、環境がよく壊れるしといった色々なアラが目立つので…。Googleもサポートを打ち切っていく方針なので、多分もうEclipseでAndroid開発はしないと思います。
 なお、Android Studioでビルドしてから、ビルド後のAPKのサイズが200kbぐらい縮みました。 これが最適化によるものなのかどうかは知りませんが、サイズ減ったからといって別に機能が削減されたわけではありません(むしろコードの量は増えているはずなのですが)。


プラグイン機能追加


大き目の変更その1。
本バージョンより、プラグイン機能なるものを実装してみました。プラグインとは、Medolyから自動的に実行される外部アプリの事です。この機能は、元々開発を開始した頃から想定していた機能だったので、ようやく実装できたか、という感じです。

プラグイン機能は、再生の開始・終了等のイベントに合せて自動的に機能を実行するという動作を想定しています。例えば、再生中の音楽情報を特定のサイトに送信する機能等です。

現状のイベント種別は、メディアを開く、メディアを閉じる、再生開始、再生終了、再生中の5種類のみです。このイベントのタイミングに合わせて、Medolyからプラグインに対して全てのプロパティ情報が送信されます。なお、送信済みイベントとは、再生開始してから何秒後かに自動的に実行されるイベントです。実行秒数は設定画面より設定します。


現在、以下のプラグインを開発済です。

Medoly Twitter Plugin


現在は、メッセージの投稿機能を持つものしか無いですが、余裕があれば、メディアを開くタイミングで、アルバムアートの取得や歌詞の取得、追加プロパティ情報の取得等ができるような機能を作ってみたいと考えています。(現状はそのような動作は作ってません)。プラグイン機能もそれを前提として実装してあるので、あとは作る気合いと時間の問題です。

なお、元々このプラグインを開発した経緯としては、Medoly単体はあくまでもローカルファイルにアクセスする機能のみを対象とし、外部のネットワークに繋いだりするような機能は、できる限り追加機能として実装 しておき、ユーザが必要に応じて選択できるようにしたかったからです。
わざわざ追加で入れるのは面倒臭いので、ユーザ数が増えない面もあるのは承知しています。しかし、ネットワークに接続するという事は、多少のセキュリティリスクを負うことであり、ユーザにネットワーク接続の権限を要求するという事です。もちろん、意図しない情報を外部に送信するつもりは微塵も無いのですが、少なからず存在するそうしたリスクを、必要の無いユーザにまで負担させたくない、というのが個人的な考え方です。
なので、ユーザが可能な限りリスクを避けて利用できる環境を目指したかったため、このような形としました。
あと個人的感情の問題なのですが、アプリ内に組み込んでしまうと、外部のサービスが終了した場合にアプリ側に動作しない機能が取り残されてしまい、なんとも空しい状態に陥ってしまう可能性があるため、それを避けたかった、という意図もあります。(そんなアプリケーションは、過去にいくつも見てきたので…。)

ちなみに実はこの機能、Ver.1.8.0ぐらいの頃には機能として既に埋め込まれていたのですが、プラグインアプリ側の開発が出来ていなかったので、今まで放置してた経緯があったりします。



非同期歌詞の自動スクロール機能追加


大きめの変更その2。
非同期歌詞(タイムコードが埋め込まれていない歌詞テキスト)について、自動スクロール機能を実装しました。これはユーザ様からの要望だったのですが、元々いつかは実装しようと思っていたところではあったので、丁度良いタイミングだったと思います。
本機能は、非同期歌詞に対してスクロールを行います。
非同期歌詞は再生位置の情報を持っていないため、当然ながらスクロールを完全に合せることができません。そのため、スクロール速度は歌詞の長さに応じて自動的に調整されます。また、設定項目に「イントロ時間」及び「アウトロ時間」の設定を追加し、スクロール速度に対してある程度の補正を加えることができます。
大まかに書くと、再生時間 - (イントロ時間 + アウトロ時間)の時間で、歌詞の縦幅の長さ分スクロールするように速度調整されています。また、再生開始時にイントロ時間分の無スクロール時間が入ります。

なお、非同期歌詞の場合、歌詞を手動でスクロールさせると、スクロール終了位置にスクロール座標が変更されます。スクロール位置がうまく合わない場合に活用してください。

なお、スクロール中はバッテリーの消費量が大きくなりますのでご注意ください(それなりにCPU負荷を削減する努力はしてますが、流石に限界があります)。画面を表示しない(または、表示タブ以外のタブを表示させる)と、スクロール処理が停止するので、消費電力は抑えられます。



画面タップ時及びスクロール時に歌詞を自動スクロールしないよう変更

同期歌詞・非同期歌詞共通ですが、歌詞表示状態で表示タブの画面をタップしたり、歌詞がスクロール状態にあると、スクロールを行わなくなります。従来はどんな状態でも強制的に歌詞がスクロールしていました、そんなわけで、今回の変更で歌詞がややスクロールしにくくなっています。
この変更は、非同期歌詞のスクロール処理に合せた変更です。



歌詞の固定オフセット追加


ユーザ様の要望により、設定画面より歌詞の固定オフセット値(表示誤差)を設定できるようにしました。歌詞のスクロールタイミングに対して必ず適用されます。ただし、画面上のオフセット値には表示されないのでご注意ください。

なお、自分はXperia UL(SOL22)という機種を使用しているのですが、この端末は他の機種より取得される再生時間がやや早いようで、歌詞の表示タイミングが少し前倒しになる傾向があるようです。(何故このような差が生じるのかは知りません。)
参考までに、私は今回追加したこの設定に「-100」を設定しています。



メディアの対応プロパティ追加


「プロパティ」タブに表示可能な項目の数を増やしました。とにかく、ライブラリから取得できる項目をできる限り詰め込んでいる感じです…とは言っても、実際に使用される機会はあまり無いと思いますが…。一部項目から、URLを開いたりすることができるようにしています。
プラグイン機能の追加に合せて、取得可能な項目を見直した感じです。 これらのプロパティ情報は全てプラグイン側に送信されます。

 

プロパティタブメニュー項目の変更


「プロパティ 」タブをタップした際に表示されるメニューの内容を見直しました。今までは、検索画面に移動するための項目のみのメニューでしたが、今回から「メディアを検索」「Webを検索」「共有」「開く」の4つのアクションを表示するメニューに変更しました。
通常はプロパティタブより、プロパティ項目選択→アクション選択ですが、メニューからはアクション選択→プロパティ項目選択、が出来る感じです。
このメニューはVer.1.0の頃からずっと変化が無かったので、現状に合せてUIの修正という感じです。


設定項目の内容を全体的に見直し


設定項目を全体的に見直しました。元の設定は大体残してありますが、項目を追加したり、カテゴリを変えたりしています。バージョンアップを繰り返す度に少しずつ設定を変えていったため、設定項目がかなり混沌としていたため、今回で一斉に見直しです。

 

DB登録日時によるソート追加


これはユーザ様からの要望です。ソート項目に「DB登録日時」を追加しています。これにより、音楽ファイルがAndroidのメディアストレージに登録された時間(曲が検索可能になった時間)でソートさせることができます。本当はファイル更新日時にしたかったのですが、ファイル更新日時はDBに登録されていないため、現状ではちょっと無理でした。
いつか独自DBの構築とかやってみたいのですが、しばらくは無理そうです。


終了ダイアログを表示しないオプション追加


これはユーザ様 からの要望です。アクションバーのメニューから「終了」を押すと終了タイマー設定ダイアログが表示されますが、これを表示せずにすぐに終了させるオプションを追加しています。ダイアログ内に非表示にするチェックボックスを設けましたが、設定画面からも変更可能です。(ダイアログで非表示にしても、設定画面から元に戻せます。)

Bluetoothの接続・切断によるオプション追加


Bluetoothでオーディオ再生するためのA2DP接続・切断で再生を開始・停止させるオプションを追加しました。設定画面より変更できます。イヤホンプラグの挿入・抜去、電話の着信・終了イベントと同様の設定を行う事ができます。
また、Bluetoothの状態を検出するため、本バージョンよりBluetoothアクセスの権限要求を追加しています。ご了承ください。

画像読込でエラーとなる問題を修正


ユーザ様からのエラーレポートがあり、画像を読込むタイミングでエラーとなる問題を修正しました。画像読込みの際、既に破棄された画像を再参照してしまう場合があり、その結果エラーが発生するという問題でした。排他ロック処理やリサイクルチェックの見直しを行っています。
…が、こちらでは問題が発生しないため、これによって正しく修正されたか分かりません。問題が正しく修正されたかどうか、再度報告いただけると助かります。


その他、各種修正


上記に挙げた更新以外に、色々な修正が加わっています。イヤホンプラグ挿入時、Bluetooth接続時、通話終了時にもオーディオフォーカスを再取得できるようにしたり、メディア再生エラーの際の処理を設定できるオプションを追加したりしています。
その他、文言変更等の細かい修正も行っています。





Ver. 2.0.1


再生時にループが終了しない問題修正


Ver.2.0.0で追加した非同期歌詞のスクロール処理ですが、画面を非表示にしてもバックグラウンドでスクロール処理が終わらない問題があったため、処理を修正しています。
このバージョンが出るまでの数日間、バッテリーの消耗が早かったとしたら、それはこのアプリの仕業です。すいません。

2015-05-07

Medoly Ver. 1.9.5

Ver. 2 直前で、気になってた部分の修正が多いです。落ち穂拾いみたいな感じです。

2015-03-27 Ver. 1.9.5
- 区間ループ追加 (Android 4.1以降)
- 区間ループの開始・終了初期値にLOOPSTART / LOOPLENGTH の値を設定
- ループカウンタ及びループカウンタによる終了タイマー追加
- ギャップレスループ化 (Android 4.1以降)
- ランダム再生追加
- 再生シーケンスポップアップ内容の見直し
- アプリ個別ボリューム設定追加
- メディアストレージ情報のリンク追加 (メディアスキャン廃止)
- 設定のインポート・エクスポート追加
- 他アプリからのM3Uファイル共有受付サポート
- キーボード操作一部サポート
- タブメニューの表示位置調整
- 共有メディアが再生キューに登録されない場合がある問題修正
- 一部ダイアログ見直し
- 巻き戻し・早送りのボタン非表示でレイアウトが崩れる問題修正


再生シーケンスポップアップ内容の見直し


今回の機能変更に伴い、メイン画面左下にあるボタンのポップアップメニュー(再生シーケンスメニュー)の内容を大きく見直しました。
まず、再生中の曲に対する再生挙動を独立させ、「再生完了時に次の曲を再生」「再生完了時に停止」「ループ」「区間ループ」の4種類から選択できるようにしました。また、再生順の項目にランダム再生項目を追加しました。あと、一部ラベルの内容を見直してます。
 


区間ループ追加 (Android 4.1以降)


今回、ユーザ様からの要望があったため、区間ループ機能を追加しました。
区間ループ(ABループ)とは、局の特定の2地点をループさせる機能です。リスニング学習や耳コピ作業等、リピートさせて同じ所を何度も聞くような用途に用いられたりします。
先述したように、区間ループの追加に伴い、シーケンスメニューの内容を大幅に見直しています。メニューの「区間ループ」を選択すると、ループ位置の設定が表示されます。
「A」がループ開始位置(ミリ秒)、「B」がループ終了位置(ミリ秒)となります。 この時間の間で再生中の曲をループさせます。

「現在」ボタンを押すと、現在の再生時間を設定します。「<」「>」ボタンで、時間を微調整します。「初期値」ボタンを押すと、メディアの初期値の値が入力されます。通常は「A」が0、「B」が曲の再生時間が入りますが、一部特殊なメディアについては初期値が異なります(後述)。
変更された値は「設定」ボタンを押すまで反映されません。未反映の値は数値が黄色く表示されます。
また、シークバー上にループ位置を示す記号が表示されます。

他の区間ループ機能を持つプレイヤーに比べて使いにくいかもしれませんが、まぁオマケ程度の機能なので…。


区間ループの開始・終了初期値にLOOPSTART / LOOPLENGTH の値を設定


先ほど挙げた区間ループ機能ですが、実は同等の機能が1年以上前に既に実装されていました。LOOPSTART / LOOPLENGTH というタグによる2点間のループ機能です。これは、音楽ファイルにあるタグを読みとって、タグに指定された2点間をループさせるもので、これは元々ゲームBGM等で用いられているものです。
今回、この機能を区間ループと統合しており、区間ループ再生を行うとこの機能が使用できるようにしています。具体的には、区間ループの初期値として、LOOPSTART / LOOPLENGTH タグから求められる時間が設定されるようになり、従来と同様にループが行われるようになります。


 

 


ループカウンタ及びループカウンタによる終了タイマー追加


メイン画面の下部に表示されている再生キュー状態の中に、ループ時にカウントアップされるループカウンタを追加しています。これをトリガーとして、ループ回数で再生を終了させることができます。
まぁ、何となくループカウント数を追加してみたので、ついでに付けてみた機能です。大して使い出があるとは私もあまり思っていません(笑)。


ギャップレスループ化 (Android 4.1以降)


ユーザ様の要望により、ループ処理を見直してギャップレス化しています。従来は単純に先頭にシークさせていただけですが、これだと再生終了→再生開始の間に僅かな無再生時間が発生し、音が途切れてしまいます。今回、これをギャップレス化して、再生終了→再生開始の間が途切れないようにしました。
これを作る際、単純にAndroidの再生ループ機能を使えば良いのかとも思ったのですが、それでも途切れる機種があったり、そもそも「再生完了」を検出するイベントが発生しないので色々不都合があったり(実は発生する機種もあるようで、どちらかに決め打ちできない)で、割と難航しました。そんなわけで、ループを真面目に作るならMediaPlayerのsetLoopメソッドは使うべきではないと思います。

今回は、従来のギャップレス再生と同様の方法でギャップレスループを実現させています。そんなわけで、ループさせる毎に再生するメディアプレイヤーのオブジェクトが入れ替わってたりします。従来と全く異なる方法でループさせているので、何か問題があったら報告いただけると助かります。
 

ランダム再生追加


ランダム再生機能は以前から気になっていたので、今回実装してみました。これは再生キュー上にある曲から、ランダムに選曲していく機能です。「シャッフル再生」というよく似た機能がありますが、それとは若干異なります。
「シャッフル再生」は、再生キューの順番を入れ替えて再生する機能です。そのため、再生済みの曲は再生されませんし、再生キューの全ての曲の再生が終わると再生キューの完了と判定されます。一方今回の「ランダム再生」は、全ての再生キューの中からランダムに選曲していきます。現在再生されている曲が次にまた流れる可能性もありますし、逆に全く流れない曲も出てくる可能性があります。とにかく、順序や再生済等の情報は一切無視します。再生キューが完了するという概念もありません。
実装はしてみたものの、使い所は難しいかもしれません。私としても、今回の変更でポップアップメニューに余白が出来ていたし、以前から気になってたので追加してみるかぁ、ぐらいの感覚です。
なお、使ってて気になるのは、ランダムに再生しているつもりでも、再生曲が妙に偏るような感じがします。アプリのバグかもしれませんが…。余談ですが、一部のサービスでは、シャッフル再生させる場合、アーティスト等の情報をなるべくばらけさせるようにして、「人間がよりランダムらしく感じられる」ように意図を持って並べ替えることもあるようです。



アプリ個別ボリューム設定追加


今まで、ボリューム調整はAndroid標準の音量設定に任せきりだったのですが、本バージョンよりアプリ固有の音量設定を持たせるようにしました。
画面右上のメニューより、音量スライダーのポップアップを表示させることができます。スライダーの移動でボリュームの変更を行うことができます。左側のボタンはトグルスイッチとなっていて、音量ボタンを押した際にAndroid標準の音量調整ではなく、アプリ固有の音量調整を行うことができます(現状ではアプリを表示させた状態でのみ機能します)。右側のボタンは、Android標準の音量設定を呼び出すためのボタンです。

余談ですが、今回アプリ固有のボリュームを追加したのは、他のアプリとの音量バランスの調整を行うためです。以前、音楽を聞きながらカーナビアプリを起動していたのですが、音楽とカーナビ音声の音量バランス調整がどうしても上手くいかず、カーナビの音量が音楽の音量に対して小さくて聞き取りにくいという問題がありました。そんなわけで、アプリ固有ボリュームの必要性を認識した次第です。



メディアストレージ情報のリンク追加 (メディアスキャン廃止)


以前から気になっていたのですが、今回で設定にあった「メディアスキャン」という項目は廃止しました。というのも、これは全く機能していなかったためです。
そもそも、Androidがどのように端末に保存されたメディアファイルをスキャンしているかというと、バックグラウンドでメディアファイルの変更を監視し、端末のメディアデータベースを更新するアプリが動作しています。このアプリがどのようなタイミングでスキャンを行っているかがよく分からないのですが、確実なのは「ストレージがマウントされたタイミング」で行われるということです。つまり、SDカードを抜き差ししたり、Androidの設定からSDカードのマウント解除→再マウントといった作業を行うとスキャンが開始されます。あるいは、端末の再起動を行うことでも実行されます。
以前はこのストレージをマウントさせるイベントを手動で実行する方法があったのですが(実際、初期の頃はこれで実装してました)、最近のAndroidではこれを行うとエラーとなります。理由としては恐らく、ユーザがSDカードのマウントイベントを自由に実行できるのはおかしいから、という事だと思います。その代替手段としてあちこちのサイトで紹介されている手法があり、とりあえずそれを実行するようにしていたのですが、正直な話、自分でもこれでまともにスキャンできた試しがありません。
たまにスキャンについての問い合わせを頂くのですが、自分でもどうしたら良いか分からず困っていたところだったので、とりあえずバッサリ切り捨てることにしました。
その代わりとして、メディアストレージ情報へのリンクを置いておくことにしました。これが端末に保存されているメディア情報を保持している共通データベースになり、Android端末であれば確実に持っているはずです。メディアの数に応じてサイズが増減し、9500曲ほど入っている自分の端末では124MB程度のサイズになっています。これに対して「データを削除」を行うと、全ての保存されたメディア情報が全て消去されます。ただ、次にストレージが再マウント(再起動)されるともう一度スキャンが開始され、データベースが再構築されます。データベースの情報がおかしい場合は、これで一端データベースを再構築すると調子が良くなる可能性があります。なお、Android共通のプレイリストを利用している場合、メディアストレージ情報を削除すると一緒に消去されますのでご注意ください。プレイリストをM3Uファイルで保存されていた場合、再スキャン時に自動的にプレイリストに登録されます。

余談ですが、Google Play上には再スキャンを行うことができるアプリがいくつか登録されていますが、それらのアプリは自分でメディアをスキャンして、自分でメディアストレージのデータベースに登録する処理を行っているようです。(それ以外に、メディアファイルを移動させるとデータベース上の登録情報を更新してくれるファイラ等もあるようです。)一部使用してみましたが、データベースの整合性がうまくとれなくなるアプリを見かけたりしました。どなたか、上手く動作するスキャンアプリ(もしくは、その実装方法)がありましたら教えてください…。
そもそも、Androidがメディアスキャン機能をもっとしっかり作れという話ではあるのですが。



設定のインポート・エクスポート追加



設定をインポート・エクスポートする機能を追加しました。設定の「その他」より使用できます。エクスポートは保存先のファイルパスを指定することで、現状の設定情報をファイルに書き出します。インポートは読み込み元の設定ファイルパスを指定し、設定内容を現在のアプリに反映させます。あんまりきちんとテストしてないので、何か問題が起きるかもしれませんが、何か問題がありましたら情報ください。
この機能は以前、ユーザ様から要望があったと思うのですが、どこから要望を受けたか覚えていないという酷い有様だったりします。
設定ファイルの中身はJSON形式で出力されているため、テキストファイルで開くと中身が見えます。設定のキーの名前についてはあまり突っ込まないであげてください…。大文字と小文字が入り乱れているのは作ってる課程で色々あった末に統一されなかった経緯がありますので、何となくお察しください。
なお、設定を適当に弄って読み込ませてエラーとなっても、当方は関知しません。弄る方が悪い。

余談ですが、Googleにはこうした設定情報をGoogle Drive等に保存して、各端末で設定を共有できるような簡単なAPIを作ってほしいなぁ、と常々思ってます。もっと設定情報を簡単にバックアップしたり、共有できるようにしてほしい。
今回も本当は、出来ることならユーザーに端末のディレクトリ構造を意識させるような作りにはしたくなかったのですが、設定がどこに保存されるのか(どうやって復帰させるか)を、ユーザがきちんと認識できるように作らないと意味が無いと思ったので、「よく分からない場所に勝手に保存するよりは、ユーザ自身に決めさせた方がまだマシ」という判断でこういう作りになりました。
この辺について何か良い案があれば、どなたか教えて下さい…。



他アプリからのM3Uファイル共有受付サポート



他のアプリからM3Uファイルを本アプリに「共有」させると、再生キューにM3Uファイルの内容が展開されるようにしました。(事前にメディアストレージにプレイリストとして登録されている必要があります。)
ファイル書き出しはできるのに、読み込みができないのは何だかなぁ、と思っていたので処理を追加しました。
とりあえず今回は再生キューの更新ではなく追加のみとします。



キーボード操作一部サポート


キーボード操作に対応しました。「一部」というのは、まだ途中だからです。全部作ると大変なので…。他のプレイヤーとできるだけ似通ったキー操作にしたいのですが、イマイチ共通性が見出せないので、とりあえず「VLC」と「Kodi (旧XBMC)」辺りのキーアサインを参考にしてます。

現状ではまだ中途半端な状態(というか、色々大変)なので、とりあえず保留とさせてください。そのうち、きちんと整えてキーアサイン一覧も表示させるようにします。



タブメニューの表示位置調整



タブを押した際に表示されるメニューがタブ幅より小さい場合、タブの中央にメニューが表示されるように座標修正しました。
修正前は、メニューが端に寄っていたので、ちょっと使いにくかったためです。



共有メディアが再生キューに登録されない場合がある問題修正


メディアファイルをMedolyに「共有」とした場合、再生キューに登録される機能がありますが、場合によっては上手く登録されない問題がありました。これは、単純に自分の知識不足の問題です。
これは、以前は「onStart」イベントのみで送られたファイルを受け取っていたのですが、その場合はアプリのスリープ状態から受け取ることができませんでした。この場合、「onNewIntent」というイベントを使用するのが正解でした。



一部ダイアログ見直し


ダイアログの表示内容を一部見直しています。動作的な変更はありません。




巻き戻し・早送りのボタン非表示でレイアウトが崩れる問題修正



設定で巻き戻し・早送りボタンを非表示かすると、レイアウトが潰れてしまう問題があったため、修正しました。