Saturday, May 31, 2014

ストリームキャッシュ機能をとりあえず実装

今日は一日休みだったのでプログラム充してました。
とりあえず、実用レベルまでキャッシュ機能を実装したので記念上げです。

現時点の実装は以下のとおりです。

・Range指定のストリーミングでない場合に限りキャッシュの作成を行う。
(シークバーなどでバッファを先読みすると、内部でRange指定でHTTPリクエストがくるんだけど、その場合はキャッシュ化はしないよっていう意味)
・キャッシュはキャッシュフォルダに作成され、再生時に利用されます。
ただし、このファイルは起動時に3日前のものを消す仕様になっています。

将来的には、Range指定されてもキャッシュ化し、再生時に最新日付を設定することで消される対象から除外するといった処理をする予定です。
あと今回はRatingを統一する予定なので、Ratingにも比例して消されにくくしたいと思っています。
あと、要望であった、キャッシュフォルダを設定で変更出来るようにするなど

https://bitbucket.org/yokmama/just-player/downloads/JUSTPLAYER3_v1.0_053102.apk

GoogleDriveすごい、、かも

今日の予定である、GoogleDriveAPIからのStreaming処理の部分をDropboxやAmpacheといった他のクラウドデータでも使える用に、Creator、Strategyパターンでリファクタリングしました。
このあとキャッシュ化処理を実装しようかとおもったんだけど、ちょっと疲れたので、GoogleDrive共有フォルダへのアクセスが可能かどうかしらべたところ、できましたね。
これは、すごい。
Dropboxとか他のクラウド・ストレージの場合共有フォルダはいくつか制限があるもんだけど、これはあんのかなぁ?
スピードも早いし快適すぎるよ。

共有フォルダ対応したバージョンをアップロードしておきました。

二段階認証時の処理対応

GoogleDrive対応がやっつけ仕事だったので、二段階認証や認証でなにか問題があってエラーがおきたときに無限ループのような状態になってました。

05-30 19:44:35.425      333-335/? D/dalvikvm﹕ GC_CONCURRENT freed 865K, 11% free 14926K/16647K, paused 1ms+5ms
05-30 19:44:35.441    4161-4172/? I/GLSUser﹕ GLS error: BadAuthentication
05-30 19:44:35.441    4161-4172/? V/GoogleLoginService﹕ Returning error intent with: ComponentInfo{com.google.android.gsf.login/com.google.android.gsf.login.LoginActivity}
05-30 19:44:35.464  17779-17905/? E/MusicStreaming﹕ Received null auth token.
    android.accounts.AuthenticatorException: Received null auth token.
            at com.google.android.music.sync.google.MusicAuthInfo.getAuthToken(MusicAuthInfo.java:42)
            at com.google.android.music.sync.api.SignupClient.checkInviteStatus(SignupClient.java:86)
            at com.google.android.music.tutorial.SignupStatus$SignupCheckService.onHandleIntent(SignupStatus.java:308)
            at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
05-30 19:44:35.464  17779-17905/? I/CheckMusicStoreAvail﹕ No verified accounts found
05-30 19:44:35.496  17779-17905/? I/CheckMusicStoreAvail﹕ Starting account signup check
05-30 19:44:35.558      186-213/? I/ActivityManager﹕ Displayed com.google.android.gms/.auth.login.ShowErrorActivity: +226ms
05-30 19:44:35.574  16430-16430/? D/OpenGLRenderer﹕ Flushing caches (mode 0)
05-30 19:44:35.605  16430-16430/? D/OpenGLRenderer﹕ Flushing caches (mode 0)
05-30 19:44:35.628    4161-4172/? I/GLSUser﹕ GLS error: BadAuthentication
05-30 19:44:35.636    4161-4172/? V/GoogleLoginService﹕ Returning error intent with: ComponentInfo{com.google.android.gsf.login/com.google.android.gsf.login.LoginActivity}

原因は、エラーが起きた時に、理由の含まれたExceptionを渡して再度ログインを試みるのですが、この際別のアプリに連携します。
二段階認証だとこの処理でブラウザアプリに連携しそこで認証コードを入力して戻るという処理なのですが、このとき新たにActivityが生成されるので、また認証処理を実行してしまうというループになっているようでした。
もどってきてもきちんと処理をうけとれるようにAndroidManifest.xmlでandroid:launchMode="singleInstance"にすることでとりあえずの処置をしました。
この認証処理は、OnStartとかで実装するのではなく、ボタンなどのトリガーで呼び出すように実装するのが正しのかとおもいます。

ちなみに、上記ログに関連する情報は下記にもあります。
http://stackoverflow.com/questions/12929569/error-while-trying-trying-to-use-oauth2-accountmanagerfuture-to-authenticate-w

修正したアプリはこちらにアップしました。

https://bitbucket.org/yokmama/just-player/downloads/JUSTPLAYER3_v1.0_053001.apk

いちおうGoogleDriveアプリと連携できたので、今後はStreaming処理に手を入れていく予定です。
今後のマイルストーンは以下のように進めます。

・ストリーミング処理の再構成
・ファイルキャッシュの導入
・画面フロー時の処理を見直し
・GogleDriveファイル選択画面のUIをリファクタリング
・イコライザー設定のバックアップ機能追加
・ブックマーク機能の検討
・その他クラウドへの対応

ちなみに、要望にありましたがBox.netは難しくないのでやりましょう。
SkyDrive(OneDrive)のほうはAndoridからアクセスできるかどうかから調査しないといけないので、できるとはまだ明言できないんだけども。



Wednesday, May 28, 2014

記念上げ

実はこっからが大変なんだけど、ひとまずGoogleDriveの音楽を再生できるようになったので記念上げ。

GoogleDriveのフォルダ内の音楽を再生することしかできません。
ラジオボタンでフォルダ選択、プレイリスト選択は意味ないので注意です。
あとキャッシュ化もしていないです。
これはこっちのほうがいいっていう人がいるかもしれないけど。


https://bitbucket.org/yokmama/just-player/downloads/JUSTPLAYER3_v1.0_052801.apk

クラウド対応始めました

Equalizer処理、Shuffle,Repeat、早送りの対応が終わりだいたい音楽プレイヤーとして形になってきたので、次はクラウドデータの対応をはじめることにした。

クラウド対応といっても、どのクラウドデータに対応するか悩むところです。
最終的には、Dropbox,GoogleDrive,Ampache,OwnCloud,SkyDrive(OneDrive)辺りには対応をしたいなとおもっているのですが、どれからにしようかな。

モチベーションを維持するためにはやったことないところから手をつけていきたい、そういうわけで、GoogleDriveかSkyDriveにしよう。
で、SkyDriveだけどちょっと調べたところ、最近名前がOneDriveになったようですね、OneDriveってUbuntuOneにのってるアレかとおもってました。違った。
SkyDriveは以前オープンソースのライブラリを見つけたのでそれで試したことがあるんだけど、APIが古くなっているのか動作確認がとれなかったです。そういう状況だったのでOneDriveにはとても対応してるとはおもえないし、公式サイトをみてもどうやってアクセスすればいいのかイマイチわからない感じでした。
というわけで、まずは手始めにGoogleDriveから対応することにします。

GoogleDriveは最近GooglePlayServiceからアクセス出来るようになったし、認証処理などもお手軽にできるようになったので、JUST PLAYERのクラウドデータとしては標準で装備してもよいのかなとおもっています。
これが実装できたら、インターフェースを統一して他はプラグインという形で提供できればいいなぁ。



Tuesday, May 27, 2014

Shuffleの実装

Shuffleの実装は意外と難しい。
Equalizerの実装は納得はしてないけど、とりあえずこれ以上掘ってもわからないので一旦ペンディングすることにしてRepeatとShuffleの実装にとりかかることにした。

Repeatはそんなに難しくない、1曲リピートはOnCompleteのときにSeekで0に戻せばいいだけだし、RepeatAllは最終の曲が再生され次の曲がないとき一曲目から再生するようにするだけでよい。
ただ、JUST PLAYER3にはBookmark機能があるのでその分実装が少し複雑になるけども。
まぁ、これはいいとして問題はShuffle。
Shuffleは、ShuffleをOnにしているときに再生順がランダムになるようにする機能だ。
このランダムというのが先読み機能と相性が悪くて、次の曲が何を再生するのかわからないようなShuffleは実装できない。
それに、一度再生された曲が何度もでてくるのもいただけない。
なので、再生済みフラグを設定し、フラグのたっていない曲から次の曲をランダムに選ぶというのが簡単に思いつく実装だとおもう。
前バージョンのJUST PLAYERはこの方法を取り入れていた。
しかし、この方法には欠点があり、プレイリストの数が数千曲もあると、再生後に実行されるシャッフルでもたつきが発生し、折角ギャップレス再生をしていても意味がないものになってしまう。
なので、これをなんとか解決したいと思っていた。
JUST PLAYER3ではそのため、プレイリストの曲順とは別に再生順用の曲順をプレイリストに設定し、シャッフルでそれを一遍に変更することにした。
このシャッフルの設定は曲の登録後に毎回設定することで見かけじょうShuffleされているようにみえるとおもう。
ただ、これでも問題があるとおもう。
Shuffle自体のアルゴリズムだ、既ににあるプレリストに曲を追加した場合、再生中の位置から以降の曲をシャッフルするのが自然だし、まだ一度も再生をしていない状態のプレイリストをShuffleすると一曲目からシャッフルされるべきだし。
数万曲とかのShuffleをしても高速に曲順を設定できるべきだし。
そう考えるとけっこう複雑になってしまう。
実際にShuffleの実装は思った以上に実装ステップ数が多くなってしまったのでバグが潜んでいるのではないかとちょっと心配。

https://bitbucket.org/yokmama/just-player/downloads/JUSTPLAYER3_v1.0_052701.apk






Monday, May 26, 2014

BassBoostとEquqalizerは同時に有効にできない

もしかしたらこれはNexus4が悪いのかもしれない。
もしかしたらこれは、僕のNexus4だけが悪いのかもしれない。

とにかく、BassBoostとEqualizerは両立できないようなので、Equalizerを有効にする場合は一旦BassBoostを無効にするようにした。そして逆も然り
これをするようにしてから、安定して動作をしているようにみえますので、ひとまず開発途中のバージョンをアップロードしました。

現在のところm3uファイルもしくは、cueFile、あとフォルダ指定による音楽の再生しかできません。
AudioEffectは右上の再生ボタンあるいはアルバムアートをクリックすると移動するプレイ画面から、右下のボタンで移動できます。
(添付のスクリーンショットはEqualizer変更画面です。)

 ですが動作確認はNexus4(日本語)でしか実施していません。
他の端末とか、日本語以外の環境ではなにか不都合がおきるかもしれませんが、動作に問題があればご連絡ください。

あぁ、それと、JUST PLAYERのソースコードをPlayStoreにアップロードしている輩がいます。
このアプリに関しては僕は一切関知しておりません。
きちんとバグを修正しているのであればよいのですが、、もしウィルスでも混入しているのでしたら問題です。

下記のアプリは許可なく無断で登録されたものなので、くれぐれもご注意ください。
https://play.google.com/store/apps/details?id=com.illusion.localplayer