LoginSignup
2
1

More than 5 years have passed since last update.

PhoneGapで音を鳴らす(Android対応版)

Last updated at Posted at 2015-02-15

PhoneGapはHTML5アプリをモバイルアプリに変換してくれる。
つまり、HTML5アプリを作れば、iOSアプリもAndroidアプリもそのまま作れちゃう。

ところが、HTML5の以下の様な音の再生ができない。

var audio = new Audio("./hoge.ogg");
audio.play();

代わりに、PhoneGapのPluginのmediaを使う必要がある。
Androidの場合は、soundファイルへのアクセスの仕方に癖があるのでメモ。

公式サイト

オーソドックスなやり方

例えば、次のサイトが参考になる。

Mediaの第2引数は成功時のfunction、第3引数は失敗時のfunctionを入れる。

var src = 'sample.mp3';
media = new Media (getPath() + src , onSuccess, onError);

//Androidではプロジェクト中にあるmp3ファイルを読み込ませるために絶対パスを指定します。そのための関数です。
function getPath() {
    var str = location.pathname;
    var i = str.lastIndexOf('/');
    return str.substring(0,i+1);
}

これでいいのだけれど、PhoneGap Builderのデバッガーでは動作しない。
(インストールすると動く)
これはとても不便。

別のやり方(正しいのかはわからない)

以下のように、location.pathnamelocation.hrefにすると、PhoneGap Builderのデバッガーでも動作する。

var src = 'sample.mp3';
media = new Media (getPath() + src , onSuccess, onError);

//Androidではプロジェクト中にあるmp3ファイルを読み込ませるために絶対パスを指定します。そのための関数です。
function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0,i+1);
}

参考

結局、こんな感じにしました。

var src = 'sounds/alarm.mp3';
audio = getAudio(src);
audio.play();

function getAudio(src){
    // Phonegap media
    if (device.platform.toLowerCase() === 'android'){
        // Android needs the search path explicitly specified
        src = getPath() + src;
    }
    return new Media(src, null, function(error){ alert(src + ':' + JSON.stringify(error)); });
}

function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0, i + 1);
}

ブラウザアプリとmobileアプリで同じコードに

ブラウザアプリのときとmobileアプリのときで書き直すとかは最悪。
ということで、こんな風にしてみました。

要はHTML5のAudioが使えるかどうか。
ところが、mobileのときでも一応Audioは関数として取得できている。
苦肉の策でAudio関数を文字列にしてHTMLAudioElementが含まれているかで判断。

ちなみに、止め方をAudioとMediaで分けているのは、次の記述が気になるため。

Releases the underlying operating system's audio resources. This is particularly important for Android, since there are a finite amount of OpenCore instances for media playback. Applications should call the release function for any Media resource that is no longer needed.

var is_html5_audio, audio;
var src = 'sounds/alarm.mp3';

$(function() {
    is_html5_audio = (String(Audio).indexOf('HTMLAudioElement') > 0);

    $('#start').click(function() {
       audio = getAudio(src);
        audio.play();
    });

    $('#stop').click(function(){
        if(is_html5_audio){
            audio.pause();
        } else{
            audio.stop();
            audio.release();
        }
    });

});

function getAudio(src){
    // HTML5
    if(is_html5_audio){
        return new Audio(src);
    }
    // Phonegap media
    if (device.platform.toLowerCase() === 'android'){
        // Android needs the search path explicitly specified
        src = getPath() + src;
    }
    return new Media(src, null, function(error){ alert(src + ':' + JSON.stringify(error)); });
}

function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0, i + 1);
}

ただ、ブラウザアプリのとき、index.htmlの<script type="text/javascript" src="cordova.js"></script>の読み込みエラーはでてしまう。。。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1