Friday, October 17, 2014

CrossFadeができる端末とできない端末がある

ユーザの要望でクロスフェード機能を実装してみたのですが、この機能のためいくつか犠牲になっているものがあります。
そのまえにクロスフェードとはどういう機能なのかというと、曲の終わりをフェードアウトし、次の曲のはじまりをフェードインすることを同時に行う機能です。
JUST PLAYERはクロスフェードの設定を有効にすると、曲の終了6秒前にフェードアウト処理にはいり、同時に次の曲をフェードインします。
いまのところ6秒固定になっています。
この数値を変更出来るようすることは可能ですが、いまのところ変更するUIを実装していません。マニアックな機能なので特に必要だとはおもっていませんが、もし要望があれば検討したいです。

実際の実装方法は、2つのMediaPlayerを準備し、片方の時間をチェックし、6秒前にはいったら、次の曲を再生するという単純な方法なのですが、これをつかうことで、一時的ではあってもMediaPlayerのインスタンスを2つ準備しなければなりません。
これは、ギャップレス再生でも必要な処理なのでこれ自体は問題ではないのですが、ギャップレス再生とは異なり、違うボリュームをそれぞれに適用する必要があるためAudioSessionIDを共通化することができなくなります。
つまり、AudioEffectも別々になるというわけです。
この問題は、これまで何度MediaPlayerを作りなおしてもAudioSessionIDを共通化しておけば、AudioEffectは共通でつかえていたものが使えなくなったことになります。
そのおかげで、Equqlizerの処理、Visualizerの処理といったAudioSessionIDをもとにインスタンスを生成していた処理の扱いが面倒になってしまいました。
いろいろ、苦労はあったものの今のところなんとか、うまく動いている状態までもってこれました。(手元の最新版において)

しかし、完璧というわけではなく一部の端末では、MP3ファイルを同時に再生するとStartが実行されない問題がおきています。
具体的にいうと、Nexus5さん。

これは個体差があるのかもしれませんが、2台の端末で同じ現象を確認しています。
簡単なサンプルプログラムを作ってもやはり同じ現象がおきるので、MediaPlayer自体に問題があるのではないかと思っています。






Friday, October 10, 2014

beta update version 2142000047

リリースまでもうすぐ、、のはず。
長いよー長いよー早くリリースしてゆっくりしたい。
こちらのIssueが全部解決されたらリリースする予定です。
https://bitbucket.org/yokmama/just-player3/issues?status=new&status=open

あと、1,2週間ぐらい。

今回のバージョンは色々修正しています。
UIでは、選択方式を全面的に見直しました。
Visualizerに関しては処理を高速化し省電力化しました。
Equalizerに関しては画像を綺麗にしました。
Playに関しては、おかしな動きがある不具合などを修正しました。
アプリ内課金は、とりあえず実装しました。今のところ課金しなくても全機能が使えます。

こちらの端末では安定して動くようになっています。
UIをきちんと作ったイコライザ、結構苦労しました。


Wednesday, October 8, 2014

Ampache SelectView renewal

Ampacheの選択画面を再実装しました。

Ampacheにかぎらずファイル選択画面は全部変更しました。
基本的にCheckboxの廃止です。
タップで曲選択、再生が基本となり、ロングプレスから複数選択、置き換え等ができます。

Tuesday, October 7, 2014

GC_EXPLICITが出ないように対策

JUST PLAYERのログをずっとみていると、次のようなログが頻繁にでていました。
 
GC_EXPLICIT freed 5773K, 34% free 27728K/41588K, paused 17ms+20ms, total 267ms
GC_EXPLICIT freed 41K, 75% free 2829K/11252K, paused 2ms+2ms, total 27ms

発生するタイミングを調べるとどうやら、ContentProviderでQueryをするタイミングだということがわかりました。


該当するクエリ処理をみてみると、どうやらsetNotificationUriが怪しい

cursor.setNotificationUri(getContext().getContentResolver(), uri);

試しに上記のコードの部分をコメントアウトすると、GC_EXPLICITがでなくなりました。
setNotificationUriは、registerContentObserverで登録されたコールバックに通知が届くようにするための設定処理なのでコメントアウトするわけにはいきません。 しかし、必要のないQueryに対しても常に設定するのは勿体ないです。 なので、ここは、必要なクエリとそうでないクエリを判別できるようにし、必要なクエリだけ設定するように変更しました。下記は自作のContentProviderのQuery処理です。

        boolean needSetNotify = false;
        if(uri.getQueryParameter("notify") != null){
            needSetNotify = true;
        }

        //クエリ処理

           Cursor cursor = queryBuilder.query(
                getSQLiteOpenHelper().getReadableDatabase(), projection, selection,
                selectionArgs, groupBy, having, sortOrder);
        
        if(needSetNotify) {
            cursor.setNotificationUri(getContext().getContentResolver(), uri);
        }


こんな感じで、自作のContentProviderに仕込んでおく。
そして、ContentObserver.onChangedのイベントが必要なクエリ結果の場合だけ、下記のようなクエリのためのUriを発行する。
 
        Uri uri = PlayOrderContentProvider.PLAYORDER_CONTENT_URI
                .buildUpon()
                .appendQueryParameter("notify", Boolean.toString(true))
                .build();

これをいれておくことで、通知が届くCursorを取得することができます。
GC_EXPLICITを回避しパフォーマンスが向上しました。
次のバージョンでFIXされます。


Wednesday, October 1, 2014

イコライザを引っ込めました

画面の仕様を変更しました。
いままでは、

・プレイリスト
・アルバムアート
・イコライザ

となっていましたが、イコライザを設定と同じ場所に移動し、かわりに

・プレイリスト
・アルバムアート
・メディアリスト

に変更しました。

メディアリストには、すでに再生したことがある、あるいはメディアスキャンによって登録された曲から、アルバム表示、アーティスト表示を選択することができます。
右上のアイコンで表示を変更できます。


Indexを設定しアーティスト順で分かりやすくしています。