Android 5.0 LollipopからMediaPlayerの再生開始直後にノイズ!?

投稿日:2015年7月1日

皆さんこんにちは!
最近アプリの動画を撮るために新型Nexus7(2013)を購入した伊達あずさです。

ものすごく久しぶりのビジネスカテゴリですね。
しかも、プログラム(JAVA)のお話です!
私のプログラム知識って完全な独学なので、変なことを言っていないか心配ではありますが、同じような問題で悩んでいる方の助けになればと思いまして思い切って書いてみちゃいました。

今回の記事は、今さらな気がする「Android 5.0 Lollipop」に関するものです。
(Android 5.1.1でも一緒です)

私が作ったアプリでBGMを流すために使用している「MediaPlayer」なんですが、なんだかこれの挙動が旧Version時と変わってしまっているようなのです。

例えばこれまでMediaPlayerで音楽を再生する場合ですと

//再生ファイルの設定
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bgm);
//再生ボリュームの設定
mediaPlayer.setVolume(1f, 1f);
//再生開始
mediaPlayer.start();

みたいな感じでコードを書けば特に何事も無く音楽が再生されていました。
(rawフォルダにbgm.ogg(mp3など)を設置している前提)

ですが、Android 5.0 Lollipopの環境で同じ方法を使うと、曲の再生開始直後に謎のノイズが入ってしまうのですよね。
再生、停止、再生を短い間で繰り返した様な感じのノイズなんですよね。
なので、曲の開始直後に十分な無音領域がある曲ならいいのかもしれませんが・・・

もしかして、曲の開始位置の初期値がおかしいのかな~と思って、「mediaPlayer.seekTo(0)」を追記してみるも変わらず・・・
確かに開始直後の1回だけだしと言われればそれまでですが、結構私は気になるんです!こういうの!

という訳で、今回はこの開始直後の謎のノイズを回避するために私が考えたコードをご紹介します!

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bgm);
mediaPlayer.setVolume(0f, 0f);
mediaPlayer.setLooping(false);
mediaPlayer.seekTo(mediaPlayer.getDuration() - 200);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
  public void onCompletion(MediaPlayer mp) {
    mp.setVolume(1f, 1f);
    mp.seekTo(0);
    mp.start();
  }
});
mediaPlayer.start();

こんな感じです!!
なんでこんなことをしてみようかと思ったのかといいますと、曲をループさせた場合の曲の出だしにはノイズが入ってなかったんですよね。
だから1回無音で曲をループさせてから開始させればノイズが入らないんじゃないかな~と思いましてこんなコードを書いてみました。
もちろん、正しく再生されていた旧OSでこのコードが実行されても特に変な挙動は起こしませんのでご安心を!

ちなみに・・・最初に無音で流す際の再生位置なのですが, 曲の最後200ms前から再生してます。
ここをあんまり短くすると呼び出す環境次第ではノイズが入っちゃうんですよね。
音の出始めスピードに特に拘らないなら長めにしておくと良いかもしれません。
「200ms未満の短い曲を流したい!!」なんていう場合は、10秒未満なんですからSoundPoolで再生してくださいっっ

ちなみに曲をループさせたいときはこんな感じで書けば良いです。

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bgm);
mediaPlayer.setVolume(0f, 0f);
mediaPlayer.setLooping(false);
mediaPlayer.seekTo(mediaPlayer.getDuration() - 200);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
  public void onCompletion(MediaPlayer mp) {
    mp.setOnCompletionListener(null);
    mp.setVolume(1f, 1f);
    mp.setLooping(true);
    mp.seekTo(0);
    mp.start();
  }
});
mediaPlayer.start();

onCompletionの中でループ設定をtrueにするわけですが、そのままだとループ時に毎回onCompletionが呼び出されてしまうので、最初の頭出しが終わったらMediaPlayerのonCompletionListenerを解除してしまうと良いです。
でもなんか、MediaPlayerで曲をただ再生したいだけなのになんでこんなことになってしまったのでしょうか・・・

ちなみにMediaPlayerのおかしな挙動はまだ他にもあるのです。
それは、MediaPlayerのループ設定に関するもので、以前のVersionの時と比べると、ループ端に異様な隙間があるのです。
まあ要するに、「今まで綺麗にループしていたはずのBGMのループの境目がはっきりと聞き取れるほどになってしまった」ってことです。
むしろこっちのほうが気になる度合いは酷いです。
次回はこのループ問題について私が考えた対策法についてお話したいと思います。

ビジネス記事一覧へ

Studio POPPOをフォローしませんか?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください