How can i create a promise for the end of playing sound?

≯℡__Kan透↙ 提交于 2019-11-30 08:05:52

问题


I have a simple JavaScript that loads sounds:

  prefix = 'modules/sounds/';
 _sounds = ['nameOfSound','nameOfSound','nameOfSound'];


 for (var sound in _sounds) {
                if (_sounds.hasOwnProperty(sound)) {
                    var cached = _sounds[sound];
                    cached.audio = new Audio(prefix + cached.src);
                    }
                }
            }

All is being cached here, and then in angular I just have a service that does the following function:

 this.play = function(trackName) {
        _sounds[trackName].audio.play();
    };

What I want is a simple promise for the sound, so when I call it, I will have something like this:

soundService.play('boom').then(function(){
    do something here
});

Is that even possible?


回答1:


You can make a generic object that you can implement to suit your setup:

function play(url) {
     return new Promise(function(resolve, reject) {   // return a promise
         var audio = new Audio();                     // create audio wo/ src
         audio.preload = "auto";                      // intend to play through
         audio.autoplay = true;                       // autoplay when loaded
         audio.onerror = reject;                      // on error, reject
         audio.onended = resolve;                     // when done, resolve

         audio.src = path + url + suffix; // just for example
     });
}

Now you can call:

play("boom").then(function() {

});

There is little point in caching audio elements due their buffering behavior. Indicating preload will tell browser that you will want to play through the audio file. In my opinion this is also nicer to the client and the system.

Example

function play(url) {
  return new Promise(function(resolve, reject) { // return a promise
    var audio = new Audio();                     // create audio wo/ src
    audio.preload = "auto";                      // intend to play through
    audio.autoplay = true;                       // autoplay when loaded
    audio.onerror = reject;                      // on error, reject
    audio.onended = resolve;                     // when done, resolve

    audio.src = url
  });
}

play(sample).then(function() {
  alert("Done!");
})
<script>
var sample = "data:audio/wav;base64,UklGRiAOAABXQVZFZm10IBAAAAABAAEA71YAAO9WAAABAAgAZGF0YfsNAACCgoKAgYKCgoKCgoGCgoGBgIB/foCAf35+fn19fX1+foCCgYGAgICAfn5+fnx8fn5/f3+AgICBgYKCg4OCgIB/fn5+gIB/gIGBgoGAf4CAgYB+fn5+fXx8fHx9fn59fX1+foB/f39+gIGAgIGBgIB+f4CAgICAgH+AgoKBgIGCgoKChYWBfHp5eHh5enx/goSGiYqMi4mHhoaEhIOCgH58fHx8fHx+fn5/gICAgYGCgoKDhIODgoCBgYCAgICAf319fn59fn5+fn+Afn6AgYCBgYCAf36AgICAgH5+f4CAgIB+fn59fHx+fn5/gYGBgoOEgoGBgYB+fn59f35+gIB+fn+AgICBgICAfn+AgICCgYCBgYGCgoKCgICBgH+AgICAgIGCgoGAgX9/foCAgICAgIB/gICAgYB+gIGCgoKCgICAf4CCg4KBgYCAfn6AgH99e3x9fXx8fH5/f4CAgICAgIGCgoOEgoKCg4OCgoKCgICAgICAgYKCgoKCgYCBgYKCgoKCgoCAgYF+fn5/gICAgH59foCAgX9+gIB+fX19fn+AgH5/f3+Afn19fX5/gICAf4CAgH59fX6AgH5+gICAf4CAgICAgYKBgoGAfn6AgICAgIKCgICAgICAf35+fn59fX1+fn6AgH9+gIGAf4CAgYCAgICBgYB/fn+Bg4F/foGDgn59gISEgn5+g4aFgX+AhIWEfnyBhoSAfH2Cg396en6Eg357foSGgXx9hIeEfnuAhoZ+en6FhoF7fYSIhH16foSCenl+g4R/eXuChX55eoCCfHd5foJ+enp+hIF6e4KEgXt7goWBe3yChoJ7fISGgXp8g4WAfH6Eh4F6fYSGgHp9hIaAe3+GhoB7gIeGfnyChoN8e4KGg3x6gYaBenyEhn95fISGfnp+h4Z8eH+Ggnl6goiAd3iEiIB4fImKgHh+h4R5cnmGhXdzfoiDd3aAioR4eYaMgnV3hoyCdXmJjoJ2fIqMfnR6jI5/c3uMjn50fo6PfnJ7jY18cnuMjnpteY6Oem14jI56bXmOjnprdo6Se2h0jZJ7Z3GOl4BmbIqZgmZqip2HZGeKn4plZIaklGlggqKWalp4nppxWXKdontZaZOkhFxhi6eTZlyApp5yWHGeq4RYXoqolGNVd6Gfc1ZrmauKXFuHrJtnU3Siq35TX5Cxll5Sfq6rck5ooLaNVliOuaNkTXKnsH1MW5K2m11JdKqxfkxalLiaWkh0rrV5RFaYwJ1VQXe3t3ZDW52+llFGfrq2ckBbnsGWUEaAtq9uQl6evJBORn60sXREXJy+l1NCdrO0dD9VmL6eWD5wsbl8QFGUvaJeQ26tvIRIU5C6pGNEaqa5jVBOhLWvckZfnLuZWkh1rLSCTlWKs6hxTmSXsZReTnKirINUVoSsqHhSYJGwmmhTb5uqjmFWeKKog1hZgKSieVZgiaWacllqkKiacVttk6eWcF1xlKSTcWBykqKRbV5xkqKSbVprkKWWbFRok6yYalFqmbCVYExtnrCQXE9wnrCTYlNznaqPY1Z0mqaOZFZylqKMZlpykp6MbmN0jZeMdWdziJKNem5zhI6LfXN2goqHfXZ3gIeEfnt7foCBgYF+fn1+goSDfXp8goeHfnd4gIiKgnZ1fomKgXZ2foeJgnd0e4SJhn54eoKKjYV4dX6KkYt6cXiGkIx7bXOGkpGAcHKElJOCb26Aj5GGdG55iY+KfXJ0g46QhHNteY2Uindsc4aSjHxvcICOj4FycXuIjId8dHN7iIyGe3N1go+OgXVweImPhnlwdIGLh313dHiEiYR9eHZ7hIeGgnlyeYmPh3tvcIGRjYBybXqMkYZ6cXOBjY6Ee3R2hJCPhndud4yWj31ra3+Wl4RvaXaNmIp3b3SBjo6Cd3V4gYmJhH53dHyKj4p+cG+AlJaFcmt1ipSKdWpteoqMgHVzeICIioJ8e3h8h46KgHd0fpCVjHxxcYGTk4Z4cXaGkIuAeHJ0gY+QhnZrboOXloNvZ3SMmpB6amp6kJaIdm5xe4qOh310bnWHk5CAbmZzjpqQeGZmepWciW5lbYGVmId1bnF+jZKIem5qdYyZkHtoZHWRoZV4Y2J3lqORcmFlfpyjjnJla4CYnYpyZ2p8k5uLc2hse5GajnpsaXaLmpJ4aGp4kJuQeWtreIyak35uaXGGmJeEbmhziZ2dhWxpc4ibm4VuaHSImZqGcGpyg5KWiHNtdH6Jkox7bm93hpOSfm5wfIaNjH91eoGAgYeJg317eXqFi4R7eHh5gYiHgX54cneFi4d+dG90go+Nf3Z0doCLioJ/fXd2fYeMi4FzbHSGlJKDcmhwhZWXiXRqbH6Tl4t7cGtyhpaXi3hoan6Wn5N4ZGN0jJqTfGllcIGTmot1bG96i5eSfnBveIWPkIV4dnuBg4aHhYF+enR3goyLgHJrcYSUkoJzc3uEiomCfX6Af32AiIyIgnp1eIKKjYh+dHJ4hpGRhHZvdYaQjoJ3dnyCgn6AgoODfnh3foSHhoB5dHR9h4uHfXRyd4GMj4R0bnaDjIp+eHqAhIWAenuAg4WEfnd1fIWLioB1cnqEi4yFenZ4foOFgn99fHt8foCBgoKCgXx5fIKEhYJ7d3p+goOCgH5+foCCgYCAgIOAfnx8gIOEhoN/foGFhoN9e36DhoR+en2ChYSAfX2Ag4KBgYKDgoB+gIKCgoGAgYKAfn6ChYR9en2ChoeBenuAhYSAfX6Ag4SAfX2AgoKCgH9+fX2Ag4KBfXp7goaDgH19gIKBfoCBgHt6fIGDgn58fYGCgH59gIKBfXt+gYKCfXl6foKEgXx5e4KGhoF8e4CEhIKAfXt+gYGChISBfXx+hIeFfnp8gYaHhYB9gIKDg4KBgYB+foCEhIB8enyEiod+eHqBiIiCenh+g4SBfnx8fXx7fICAfXp7foSGgXx8foKEgn59foGCgoGBgYKAgICBgoSEgn5+goeKhHx4eYCHiIN7eHqCiod+eHl9goWFgHt7fYCEhYJ7dniAhoWAenh6goeEfnt6fIKGhH15en2DhoJ9e3x+gYOCgH59fICCgYKAfHx9goSCgX17foKEgn56fICCgHx8fX6AgYB+fn5+fn6AgoJ+e3yAg4WEgH5+gYOCgH5+gH9+fn6ChIB6eHuAhoZ+eXp/hIeEfn2Ag4KAgYWGhIGAf4KFhoOBfnx+goSFhIB+fYCEhoSCgH6AgoSDgoCAgIGCg4OBfn1+gYKAfnt8foGBgH98fH+CgoB8enyAgoKAfXt+g4OBfnyAgoJ+fHyAg4N+ent+goOCf319fn+ChIF9e3x/gIGAgIB+fX2AgoWFgHp7foKDgn59fYGDhIOCgYKFhIKCgYCBg4OCgH2AhIaEgHx7foKEhH56e36ChISAfHyAg4WDgoKAfoCCgX99e3h5fICAfnt8f4KBgH9+gYSEgH5/goSFhoJ9fH+DhoV/enp+hIiHg318foGDhIJ/fX2AhoiFf3p4fIOGg3p0dn+GhoB5dnmAhIOAfn59foGEhIJ+fHx8gISFgn57fH6DhIJ+fHx/goSEgH19fYCBgICAgICAfHx+goSCfnx8foGDhIF+fH6BgoSCfnx8gISEgX58fH+CgoB+fH5/f4CAgIB/fH2AgoOAfXx+gIKCgH19foCDhYOAfn6Bg4SDgH5+gYOFgn59foGCg4OAfn5/goKCg4GAgIGChIJ/fH2Ag4WEgHp6foKGhHx4eX2DhIN/enp+goODgH18gIKBgYGAfn59foGBgH59fX5+foCCgn58fX6Bg4F9fH5+fn6CgoB+foCDhIF+foCCgoF+fn+BgoKAf4CBgYB/gIB/gIODhIKAfoCChISBfn1+gYODgn9+foCCgoB+fH5/gIB+fHyAgoOCfn1/gYOEgn5+gIGBgYGAfHx8fYCAfn18fICCgoF/foCBgoJ/fH2BhYaEgX9+gYWGg357fICEhoSBfn2AhIWFgn58fYCDhIF+fn6ChIOAf39+gYSCgH59foGCgH58fn+BgX98fICAgYB+fn5+f39+fn5+fX5+fn1+fn5/gH58fYB/fn18foGDgoCAgYKDg4B+fX2AgYCAgH9+foCBf4CBgICAgICBgICBgX9+fn+AgYGAfn2AgYKBf35+gIOCgYGAgoKCgoF+gYKCgoSAgYGBgoKDgYB+foB/f35/gICBgYCBgYGBgYGCgoKAgICChISCgH6AgoKCgH5/gIGBgYCBgH5/gYKAfn6AgIGAfX1/gYODgH18fICCgn58fHx9foCAfn18foB+foB+fn6AgH5/fn6AgoGAfoCAgIB+fn1+gIGBgH19foKEgn99foCChISDgH6AgYGCgX5+gICAgYF+fX1+gICCgoGAgIKDg4KDgoKDhISBf4CBg4WEgn5+gIKDg4B9fHt8fn6Afnt7foGCgoB+fYCCgoKCgIGBgoGBgIKCgoKCgoKCgYCCg4OEg4F/foCCgYGAgICBgYF+fn19fX1+fX19fYCCgoGBgH5+fn5/fn18foGBgH17e36Cg4F+fH6Ag4KAfX1/gYKCgYCAf4CAgICBgH9+f4CAgoKAfn6BgoKBgICAgIGAfn19fn19fHx9f4B+f39+fn6AgH59fXx9gIB+fn9/gICBgoKCgoGBgYKCgoKBgICAgYGBgICAgICBgYCBgoKBgICAgoKCgoGBgYKCgYGCg4KBgICAgYCBgoGAgIGCgoGAgICBg4KAgICBgoKCgH5+foCAgH5+foCCgYCAgH9/gYGAf358fH6Afn18foAA"
</script>



回答2:


You can write a service using $q.defer().

app.service('service', ['$q', function($q){
    this.play = function play(sound) {
        var deferred = $q.defer();
        sound.play();
        sound.onended = function(e) {
          deferred.resolve(e);
        }
        return deferred.promise;
    }
}]);

You can just call the service and expecting the promise return. service.play(sound).then(function(e){});

Full plunker sample - http://plnkr.co/edit/FJYjj4ehslqZQZmYyL1I?p=preview




回答3:


There is an 'ended' event that is emitted when the audio has finished playing. Source

 this.play = function(trackName) {
    return new Promise(function(resolve, reject) {
        var audio = _sounds[trackName].audio;
        audio.addEventListener('ended', resolve);
        audio.play();
    });
 };


来源:https://stackoverflow.com/questions/30069988/how-can-i-create-a-promise-for-the-end-of-playing-sound

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!