调用playAudio()30到40次后,Phonegap Sound停止播放

时间:2014-03-29 12:55:52

标签: android cordova media

在我的应用程序中,我在鼠标点击时给出了响应。这就是我的工作方式

我已经调用了这个函数

<center><input id="click_flip" type="button" value="Click Me" class="clickme" onclick="callplay()"></center>

这是函数

<script type="text/javascript" charset="utf-8">

        function callplay()
        {
                                         if(voice=="male")
                                        playAudio('/android_asset/www/Mobile/sound/Male/'+rand1+'.mp3');
                                        else
                                        playAudio('/android_asset/www/Mobile/sound/Female/'+rand1+'.mp3');
        }
        // Audio player
        //

      var my_media = null;

        // Play audio
        //
        function playAudio(src) {




                // Create Media object from src

                my_media = new Media(src, onSuccess, onError);
            // else play current audio
            // Play audio
            my_media.play();



        }





        // onSuccess Callback
        //
        function onSuccess() {
            console.log("playAudio():Audio Success");
        }

        // onError Callback 
        //
        function onError(error) {
         //   alert('code: '    + error.code    + '\n' + 
                  'message: ' + error.message + '\n');
        }


        </script>

但是当我重复按钮时,请点击多次(约30至40次)。声音没有给出任何回应。

之后使用此link我添加了此功能

if(my_media){ 
   my_media.stop();
   my_media.release();
 }

也试过这个

function playAudio(url) {
    try {

        var my_media = new Media(url,
            // success callback
            function () {
                **my_media.release();**
            },
            // error callback
            function (err) {
                **my_media.release();**
            });

        // Play audio
        my_media.play();
    } catch (e) {
        alert(e.message);
    }
}

但没有工作。请建议

2 个答案:

答案 0 :(得分:0)

我有同样的问题,现在我尝试使用这种方式,它似乎有效:

var my_media = null;

function playAudio(src)
{
    if(my_media != null) my_media.release();
    my_media = new Media(src);
    my_media.play();
}

如果你发布硬件你不需要停止,因为发布会自动停止android中的当前媒体。不知何故,如果您尝试在成功或错误回调中发布它并不总是有效。有些时候我尝试播放媒体尚未完成时,这会破坏媒体对象。

答案 1 :(得分:0)

在我的情况下,我有扫描应用程序与手机差距。 当扫描失败时,它会通过我们的API扫描票证震动并发出蜂鸣声。 通过我们的API扫描票,没有振动就有成功的声音。

经过35到40次后,它无法振动或播放声音。

修复前的代码:

在HTML中

    <audio id="successSound" 
      src="/android_asset/www/audio/correct.mp3" 
      type="audio/mpeg">
     </audio>



var my_media = null;
var mediaTimer = null;

function playAudio(id) {
    var audioElement = document.getElementById(id);
    var src = audioElement.getAttribute('src');
    // Create Media object from src
    // alert(src);
    // alert(getPathMedia());
    my_media = new Media(src, onSuccess, onError);

    // Play audio
    my_media.play();

    // Update my_media position every second
    if (mediaTimer == null) {
        mediaTimer = setInterval(function() {
            // get my_media position
            my_media.getCurrentPosition(
                // success callback
                function(position) {
                    if (position > -1) {
                        setAudioPosition((position) + " sec");
                    }
                },
                // error callback
                function(e) {
                    console.log("Error getting pos=" + e);
                    setAudioPosition("Error: " + e);
                }
            );
        }, 1000);
    }
}

// Pause audio
function pauseAudio() {
    if (my_media) {
        my_media.pause();
    }
}

// Stop audio
function stopAudio() {
    if (my_media) {
        my_media.stop();
    }
    clearInterval(mediaTimer);
    mediaTimer = null;
}

// onSuccess Callback
//
function onSuccess() {
    // alert('success');
}

// onError Callback
function onError(error) {
    switch(error.code){
        case MediaError.MEDIA_ERR_ABORTED:
        alert('MEDIA_ERR_ABORTED code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_NETWORK:
        alert('MEDIA_ERR_NETWORK code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_DECODE:
        alert('MEDIA_ERR_DECODE code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_NONE_SUPPORTED:
        alert('MEDIA_ERR_NONE_SUPPORTED code: '    + error.code);
        break;
        default:
        {
            alert('Un Known: '    + error.code);
            navigator.notification.vibrate(2000);
            playAudio("errorSound");
        }
    }
}

function setAudioPosition(position) {
    document.getElementById('audio_position').innerHTML = position;
}

修复后的代码:

var failCounter = 0;
var successCounter = 0;

var srcSuccess = "/android_asset/www/audio/correct.mp3";
var srcFail = "/android_asset/www/audio/error_long.mp3";

var my_media_success = null;
var my_media_fail = null;
function playAudioSuccess() {
    // stopAudio(my_media);
    if (my_media_success != null) {
        my_media_success.release();
    }
    successCounter = successCounter + 1;
    // Create Media object from src
    // alert(src);
    // alert(getPathMedia());
    try {
        my_media_success = new Media(srcSuccess, onSuccess, onError);
        // my_media.setVolume('1.0');
        // if (successCounter >= 35) {
        //     alert("success count " + successCounter + " total counting " + ( successCounter + failCounter));
        // }
        // Play audio
        my_media_success.play();

    } catch (err) {
        alert(err);
    }

}

function playAudioFail() {
    try {
        // stopAudio(my_media);
        if (my_media_fail != null) {
            my_media_fail.release();
        }

        failCounter = failCounter + 1;
        // Create Media object from src
        // alert(src);
        // alert(getPathMedia());
        my_media_fail = new Media(srcFail, onSuccess, onError);
        // my_media_fail.setVolume('1.0');
        // if (failCounter >= 35) {
        //     alert("fail count " + failCounter + " total counting " + ( successCounter + failCounter));
        // }

        // Play audio
        my_media_fail.play();
    } catch (err) {
        alert(err);
    }
}

// Pause audio
function pauseAudio() {
    if (my_media) {
        my_media.pause();
    }
}

// Stop audio
function stopAudio(my_media) {
    if (my_media) {
        my_media.stop();
    }
    // clearInterval(mediaTimer);
    // mediaTimer = null;
}

// onSuccess Callback
//
function onSuccess() {
    // alert('success');
}

// onError Callback
function onError(error) {
    switch(error.code){
        case MediaError.MEDIA_ERR_ABORTED:
        alert('MEDIA_ERR_ABORTED code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_NETWORK:
        alert('MEDIA_ERR_NETWORK code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_DECODE:
        alert('MEDIA_ERR_DECODE code: '    + error.code);
        break;
        case MediaError.MEDIA_ERR_NONE_SUPPORTED:
        alert('MEDIA_ERR_NONE_SUPPORTED code: '    + error.code);
        break;
        default:
        {
            alert('Un Known: '    + error.code);
            navigator.notification.vibrate(1000);
            setTimeout(function() {
                playAudioFail();
            }, delayInMilliseconds);
        }
    }
}

function setAudioPosition(position) {
    document.getElementById('audio_position').innerHTML = position;
}

经过大量的尝试和错误,并在此处发出警报!

1)我避免getElementById获取src路径,我将其定义为全局变量。

2)我分离了成功和失败的方法(重构)

3)我尽可能地使变量局部化,以避免任何内存泄漏和重叠,超出堆栈等等。

4)我删除了setAudioPosition方法,因为它没有使用和没有理由调用。

(经验教训)当您从互联网上获取代码时,请注意您真正需要的内容。

5)我注意到当我添加警报时它起作用但是当我删除它时它不起作用,所以我的

主要解决方案在首先调用的vibrate和像这样的关键部分的播放方法之间添加Timeout

navigator.notification.vibrate(1000);
            setTimeout(function() {
                playAudioFail();
            }, delayInMilliseconds);

6)我添加了发布方法,但是

(leasson了解到)请注意放在哪里 所以我把它称之为正确引用相同的变量之前的游戏。

if (my_media_fail != null) {
            my_media_fail.release();
        }

7)最后的建议作为你可以使用的javascript尝试并抓住以防万一))) Try catch W3School