Now many mobile terminals require that audio play must be triggered by the user's event, otherwise it will be hijacked. In practical applications, JS network requests often decide what audio to play through the returned results, which is not allowed in the mobile end.
When the mobile needs to play the audio through the network request callback, it needs to do some preparatory work. The specific code is as follows:
Load preparation processing
/** * Cycle processing * @param {Object} data * @param {Function} callback * @returns {undefined} */ function each(data, callback) { if (typeof data === 'object') { if (data.length) { for (var key = 0; key < data.length; key++) { if (callback(key, data[key]) === false) { break; } } } else { for (var key in data) { if (callback(key, data[key]) === false) { break; } } } } } /** * Play audio * @param {String} name * @returns {undefined} */ function audioPaly(name) { each(name.split(/\s+/), function (_, name) { if (audioPaly.lists[name]) { audioPaly.lists[name].play(); } }); } audioPaly.lists = {}; /** * Ready audio processing * @returns {undefined} */ function audioReady() { var audio; while ((audio = audioReady.lists.pop())) { audio.play(); audio.pause(); //Pause directly and play again quickly } } audioReady.lists = []; /** * Loading audio * @param {String} path * @param {Function} callback * @returns {undefined} */ function loadAudio(path, callback) { var audio = create('audio', {preload: 'load'}); each({'ogg': 'ogg', 'mp3': 'mpeg', 'wav': 'wav'}, function (name, type) { audio.appendChild(create('source', {src: '/audio/' + path + '.' + name, type: 'audio/' + type})); }); addEvent(audio, 'loadedmetadata', function () { audioPaly.lists[path] = { play: function () {//play audio.currentTime = 0; //This is not very useful, compatible processing if (!audio.ended) { audio.load(); //Reload, compatible processing, but also can quickly start playing } audio.play(); } }; audioReady.lists.push(audio); callback && callback(); }); loadAudio.frame.appendChild(audio); } /** * Create elements * @param {String} elem * @param {Object} addAttr * @returns {Element} */ function create(elem, addAttr){ var Elem = document.createElement(elem); for(var key in addAttr){ Elem.setAttribute(key, addAttr[key]); } return Elem; } //Loading audio loadAudio('test');
User event trigger processing
//Bind user triggered element click event element.addEventListener('click', function(){ audioReady();//Audio trigger ready processing for callback playback //Network request code .... //Network callback function (){ audioPaly('test');//Playback processing } .... });
Prepared audio files (why not prepare more than one, see the specific terminal supporting audio format)
/audio/test.mp3
/audio/test.ogg
/audio/test.wav
This code is not complicated, but uses a little license in the mobile terminal restrictions. When it is played in the user trigger event, it can be played again in the subsequent operations.
As long as we play the audio after the user triggers and pause or mute it in time, we can not hear the audio. Then we can play it again in the network request callback, dynamic play.
Original link
https://blog.51cto.com/php2012web/2066930