2014-11-25

Medoly Ver. 1.7.5, 1.7.6

2014-11-02 Ver. 1.7.5
- MP3 内蔵歌詞 Lyrics3 v1, Lyrics3 v2 形式対応
- 以下の外部字幕ファイル対応
 * SRT (SubRip) フォーマット [.srt]
 * STL (Spruce subtitle) フォーマット [.stl]
 * SCC (Scenarist Closed Caption) フォーマット [.scc]
 * SSA/ASS (SubStation Alpha) フォーマット [.ssa/.ass]
 * TTML (Timed Text Markup Language) フォーマット [.xml]
- プロパティ情報のファイルパスをフォルダとファイルに分割
- フォルダの共有を追加

MP3 内蔵歌詞 Lyrics3 v1, Lyrics3 v2 形式対応


MP3は規格的に古い事もあり、長い歴史の中でいくつものタグ種別があります。
歌詞の内蔵方法にもいくつかの種類があり、主に以下のようなものがあります
・ID3v2 USLT
・ID3v2 SYLT
・Lyrics3 (Version1, Version2)

USLTは非同期歌詞を保存するタグです。単純なテキストが格納され、MP3で「内蔵非同期歌詞」と呼ばれるのはこれです。この歌詞タイプの場合、比較的多くのプレイヤーで読み取りができると思います。
SYLTは同期歌詞を保存するタグです。歌詞は単純なテキストではなく、テキストとタイムコードが交互に登場するような形となっています(参考: id3v2.3.0 - ID3.org )。この内容を独自に解析しているので、表示結果が怪しいところがあるかもしれません。Windows Media Playerのバージョンによっては、これが読み取れる場合があるようです。
Lyrics3は、ID3v1、ID3v2とも独立したタグです。名前の通り歌詞が保存されますが、タイトルやアーティスト情報も保存できるようです。Version1とVersion2がありますが、Version1は古い規格なので、Version2さえ使っておけば良いかと思います。歌詞はテキストで作られますが、その内容はLRCファイルと同一のフォーマットとなるようです。というか、LRCファイルがLyrics3の内容を外出ししているのでしょうか(その辺の経緯はイマイチ分かってません)。Medoly内部でも、Lyrics3の内容をLRCファイルの解析処理にそのまま流して処理しています。いくつかの同期歌詞対応ソフトは、この歌詞を利用しています。

これらは以前からずっと対応しようと思ってましたが、ようやく対応させることができました。これで、大体の内蔵歌詞は読み取れるようになったと思います。読み取り結果に怪しい部分があるかもしれませんが、その際は連絡頂けると幸いです。

なお、これを作っていて分かったのですが、海外のアプリは概ね「文字コード?何それ美味しいの?」レベルの対応しかしていないようです。そんなわけで、Shift_JISで歌詞を保存した場合、まともに表示できるアプリは非常に限られてくると思います。歌詞やタグをMP3に保存する場合は、Unicodeを用いるようにしましょう。Medolyはなにぶん日本人が作ってますので、Shift_JISでも何とかなるかと思いますが。

余談ですが、カラオケタグについて調べてるうちに、ルビの規格について考えてる記述を見つけました。余力があれば、この辺も何とかしてみたいところ。

タイムタグ規格ルビ拡張規格 [翔星 Be ランド| BeOS 特集]



以下の外部字幕ファイル対応


世の中には歌詞ファイル以外に、動画の字幕データを歌詞として用いる文化があるようです。私はほとんど見たこと無いですが。とりあえず「Mediaplayer for lyrics」に名前負けしないよう対応させてみました。対応に当たり、以下のライブラリを利用しています。

JDaren/subtitleConverter · GitHub

一応こういう事をやってる方もいるようです。

春日 - カラオケ字幕制作ソフト プロジェクト日本語トップページ - SourceForge.JP

これも余談ですが、対応させたフォーマットのうち、TTMLフォーマットというXMLファイルがあります。w3cで策定された、由緒正しいフォーマットです。

Timed Text Markup Language 1 (TTML1) (Second Edition)

これは字幕等の時間に合わてテキストを表示させたりするためのものですが、歌詞データにも利用できるようです。今は文字読み取りぐらいしかできませんが、文字修飾等も定義しやすいため、時間があればこの辺を色々弄り回して色々表示できるようにしてみたいところ。


プロパティ情報のファイルパスをフォルダとファイルに分割


プロパティリストで「ファイルパス」となっていた所を、「フォルダパス」と「ファイル名」に分割しました。理由は、そちらの方が利用しやすいからです。
主な利用は、次の項目を参照。

フォルダの共有を追加


上記で追加したフォルダパスについて「共有」アクションを行うことができます。対応するアプリに共有すると、該当のフォルダパスを閲覧することができます。現在対応を確認しているアプリは、「ES ファイルエクスプローラー 」と、「Solid Explorer File Manager 」です。
フォルダを共有する際、MIME Typeに「resource/folder」を設定しています。上記以外にこのMIME Typeに対応したアプリであれば、共有を受け取る事ができるはずです。

余談ですが RFC2425 によると、フォルダ(ディレクトリ)のMIME Typeは「text/directory」らしいのですが、これを設定しても上記のアプリは受け取ってくれませんでした。Linuxだと「inode/directory」の模様。Androidだと、特定の機能ディレクトリを開くために「vnd.android.cursor.dir/*」というMIME Typeを利用するようですが、ストレージフォルダを開くための使い方がよく分かりません。

上記のように、正しいディレクトリのMIME Typeが特定できなかったため、設定からMIME Typeの変更ができるようにしています。

2014-11-20 Ver. 1.7.6

- プレイリストのダイアログ修正 (一部機種で開けない問題に恐らく対応)
- スリープ復帰時にダイアログのボタンを押すとエラーとなる問題の対応追加
- 再生キューのドラッグ&ドロップ処理修正
- SDカード未認識時のエラー処理修正


プレイリストのダイアログ修正 (一部機種で開けない問題に恐らく対応)


これは、アプリのエラーレポートにあがっていました。
プレイリストを開こうとすると落ちるとのこと。エラー内容を見ると、どうもプレイリストの一覧を開く時にエラーが発生しているような様子なのですが、私の端末では発生しないため、どうも特定の機種で発生する事象のような感じです。調べてみると、同様の事象がヒット。

技なれど波高し 【解決】android ListViewのonTouchにてNullPointerException

要するに、きちんとリストを実装しなさい…と。確かに、ここについては標準のリストをそのまま使っており、特別な実装を何もしていなかった。そんなわけで、ここもきちんと実装を行うように修正。

ただ、この問題についてはこちらで修正されたかどうかの確認ができないため、このエラー報告をあげて頂いた SoftBank 201M (MOTOROLA RAZR M) を利用されている方、 もしエラーが直ったという場合は御一報いただけると幸いです。もし、まだ直っていない場合は再度エラーレポートをあげていただけると助かります。


追記

報告された方から連絡があり、プレイリストはきちんと開けたきちんと読み込めたそうです。
というわけで、リストはAndroidのデフォルトのやり方( android.R.layout.simple_list_item_1 等を使うやり方 )でやると危険なようです。アダプタのgetViewをオーバーライドして、自分で処理を書くようにした方が無難かと思います。


スリープ復帰時にダイアログのボタンを押すとエラーとなる問題の対応追加


これはAndroidの仕様なのですが、ダイアログを開きっぱなしの状態でスリープに入って、復帰した際に、ダイアログ上に保持していた情報が欠落してしまいます。その状態で処理を続けると、NullPointerException等のエラーが発生します。
正攻法としては、そうならないようにダイアログを作るのが筋なのですが、正直物凄く面倒臭いので、「情報が欠落したらその時はメッセージ出すから再操作してくれ」というスタンスで作ってます。その処理に漏れがあったため、エラーが発生していました。


再生キューのドラッグ&ドロップ処理修正


再生キューを「編集モード」にした際、順番を入れ替える事ができますが、ここの描画更新処理がおかしかったので修正しました。単純に、ライブラリの使い方を間違ってました。

SDカード未認識時のエラー処理修正


SDカードがアンマウントされた状態でエラーが発生すると、エラーを繰り返してしまい、物凄い勢いでバッテリーが消費されていくという最悪のバグがあったので、修正しました。…多分。
以前直したはずなのですが、ギャップレス再生対応した際に復活してしまった模様です。

Medoly Ver. 1.7.0, 1.7.1

2014-10-17 Ver. 1.7.0

- 歌詞の表示スタイル設定追加
- 設定画面を画面分割化
- 表示タブのメニュー一部修正
- 表示タブのボタン配置一部修
- 再生・停止ボタン連続押しの挙動変更
- スリープ時にCPUに負荷がかかる問題修正
- 停止時のオフセット調整時に歌詞が追従しない問題修正
- メディアエラー時の処理修正
- 未選択状態の曲送りボタン押下時動作修正
- 設定の文言修正

歌詞の表示スタイル設定追加


歌詞の表示について、以下の項目を設定できるようにしました。これらは設定画面から変更できます。
  • 背景色
  • 歌詞テキストの影色
  • 未再生歌詞のテキスト色
  • 再生済歌詞のテキスト色
  • 再生中歌詞のテキスト色
  • 再生中歌詞の背景色
  • 再生中歌詞のボーダー色
  • アルバムアートの透明度
  • フォント種別(Sans-serif, Serif, Monospace)
  • フォントスタイル(太字、斜体)
  • 表示位置(左寄せ、中央寄せ、右寄せ)
また、スタイルのプリセットを選択することで、初期表示に戻すことができます。
なお、フォント種別、フォントスタイルについては、使用するフォントが対応していない場合は変化しません。特に日本語フォントについては、対応していない場合が多いと思います。というか、太字以外に変化してるのを見たことないです。恐らく、ほとんどの人がそうだと思います。そんなわけで、実質英語歌詞向けの設定になってます。

この設定、本当は各自でプリセットを保存できるようにして、メイン画面のタブメニューからプリセットを一発で切り替えられるような機能を持たせたかったのですが、作るのが大変だったので今のところはこの辺で妥協。そのうち作るんじゃないかと思います。

なお、これに伴い以下のライブラリを追加しています。

attenzione/android-ColorPickerPreference · GitHub

設定画面を画面分割化


歌詞スタイル関連の設定が増えすぎたので、流石に1画面で表示させるのは辛くなってきました。そんなわけで、従来の1画面から種別ごとに画面分割するようにしました。


表示タブのメニュー一部修正


表示タブをタップした時に表示されるメニューのうち、歌詞文字サイズの変更と歌詞同期オフセットの変更について、メニューを修正しています。


表示タブのボタン配置一部修


表示タブをタップした時に表示されるボタンのうち、文字サイズのアイコンの左右を入れ替えてま
す。
今まで、 左側がサイズ拡大、右側がサイズ縮小だったのですが、これが逆転しています。理由は、通常は右側が+方向、左側が-方向に値が増減する方が一般的であると考えられるため、それに倣うようにしました。
表示タブのメニューを修正した際に色々ボタン配置を見直した結果を反映しています。


再生・停止ボタン連続押しの挙動変更


再生・停止ボタン(再生と停止を兼ねる単一のボタン)を押した際、ヘッドセットのボタンと同じ動作をさせていたのですが、これを切り分けるようにしました。理由は、再生・停止ボタンの連続押しで曲送り・曲戻し動作が発生してしまうためです。
ロック画面の再生・停止ボタンで曲送り・曲戻し動作が発生してしまう事象への対策です。


スリープ時にCPUに負荷がかかる問題修正


これは昔から存在していた問題。何も弄ってない夜中に突然CPU使用率が跳ね上がり、ずっとCPUリソースを消費し続けるという問題がありました。これは毎日起こるわけではなく、たまに発生する上に、どのタイミングで起こるか分からない、充電中しか発生せずバッテリー稼働の際は起こらないといった症状があり、原因がよく掴めてませんでした。


これについて完全に把握したわけではないのですが、この事象はアクティビティのonResumeイベントにあった、歌詞更新ループ開始処理をはじめとした各種処理を、onStartイベントに持ってきたところ、(恐らく)発生しなくなりました。
恐らく、意図しないタイミングで歌詞更新のループ処理が走っていたものと思います。また、ループ処理も一部見直して、起動してない場合は確実に停止させるようにしました。
とりあえず、onResumeイベントを使うのは最小限に抑えた方が良さそう、という事は分かりました…。


停止時のオフセット調整時に歌詞が追従しない問題修正


以前の修正で、歌詞の更新処理を見直していたのですが、オフセット調整時に歌詞スクロール位置が反映されなくなっていたので修正しました。

メディアエラー時の処理修正


メディアエラーが発生した際の処理を修正しました。これは、ギャップレス再生を追加したことに伴う修正漏れです。


未選択状態の曲送りボタン押下時動作修正


曲が未選択状態で曲送りボタンを押した場合、本来は先頭の曲が選択されるのですが、ギャップレス再生処理を追加した際にその動作が消えてしまい、メディアが存在しないと判定されていました。



設定の文言修正


設定画面を画面分割化に伴い、メニュー項目や分類を一部変更しています。
ちなみに、表には出てこないので利用者には全く関係無い話ですが、今まで設定項目の見出しや説明文の文字列を設定XMLに直接書いていたのですが、これだと 日本語・英語で同じXMLを2つ用意しないといけないという問題があり、設定項目の食い違いに気付きにくいという問題があったため、文字列は全部別の XMLに外だしするように変更しました。これが結構な大仕事でしたが、あくまでもユーザーには全く関係無い部分。




2014-10-26 Ver. 1.7.1

- メイン画面に再生キューの合計曲数、合計時間、再生済み曲数、再生済み合計時間の表示を追加

メイン画面に再生キューの合計曲数、合計時間、再生済み曲数、再生済み合計時間の表示を追加


タブの下側に、現在の再生曲No、再生済曲数、再生キュー曲数、再生済合計時間、再生キュー合計時間を表示するようにしました。ふと思いついて、適当に実装してみました。これに伴い、コントロール部分のレイアウトを多少詰めています。



曲数、再生時間の表示




2014-11-24

Medoly Ver. 1.6.8

久々に変更内容の詳細でも…。

2014-10-01 Ver. 1.6.8

- 音声フォーカス取得時にエラーとなる場合がある問題修正
- アプリ再開時に歌詞再生位置が先頭に戻される問題修正


音声フォーカス取得時にエラーとなる場合がある問題修正

Ver.1.6.5でオーディオフォーカスの処理を変更しましたが、その際にnullチェックが漏れていたため、NullPointerExceptionが発生してました。
メディアがセットされていない状態でオーディオフォーカスの変更が発生した場合、存在しないメディアプレイヤーオブジェクトにアクセスしようとしていたためです。

 

アプリ再開時に歌詞再生位置が先頭に戻される問題修正

再生を中断した状態からアプリを再開した時に歌詞のスクロール位置が先頭に戻されてしまい、シークバー上は再生途中になっていても歌詞が先頭位置になるという状態が発生していたため、その修正です。