Воспроизведение аудио В конце воспроизведения Нового файла

#javascript #php #jquery #html5-audio

Вопрос:

У меня есть веб-приложение, которое загружает и воспроизводит звуковые дорожки, когда вы нажимаете на ссылку с помощью ajax/jquery. Все работает нормально, но когда трек заканчивается, трек зацикливается, и это может продолжаться вечно. Я бы хотел, чтобы плеер автоматически загружал случайный трек из базы данных и воспроизводил его, когда один трек заканчивается. Звук настроен как таковой.

 <div id="player"><audio title="Audio title" controls loop autoplay controlsList="nodownload" preload="auto" id="myAudio" /><source src="audio.mp3" type="audio/mp3" id="audioID"></div>
 

Я использую jquery для загрузки нового трека в раздел #player, когда вы нажимаете на него. например;

 <a href="javascript:;" onClick="loadurl('player.php?play=audioID','player')">Track One</a>

<script type="text/javascript">

<!-- ajaxified -->
function loadurl(dest, targetID) {
    
var XMLHttpRequestObject = false; 
    if (window.XMLHttpRequest) { 
            XMLHttpRequestObject = new XMLHttpRequest(); 
        } else if (window.ActiveXObject) { 
            XMLHttpRequestObject = new 
            ActiveXObject("Microsoft.XMLHttp"); 
    } 

if(XMLHttpRequestObject) { 
            XMLHttpRequestObject.open("GET", dest); 
            XMLHttpRequestObject.onreadystatechange = function() { 
            
        if (XMLHttpRequestObject.readyState == 4 amp;amp; 
            XMLHttpRequestObject.status == 200) { 
            document.getElementById(targetID).innerHTML = 
            XMLHttpRequestObject.responseText; 
            delete XMLHttpRequestObject; 
            XMLHttpRequestObject = null; 
            } 
        } 
        XMLHttpRequestObject.send(null); 
    } 
} 

</script>
 

В моем player.php файл, который у меня есть;

 <?php  
.... fetch track from db where id = $_GET['play']; ......
?>

<audio title="Audio Title" controls loop autoplay controlsList="nodownload" preload="auto" id="myAudio" /> 
<source src="audio2.mp3" type="audio/mp3" id="audioID">
 

Я попробовал несколько предложений здесь и в Интернете, таких как добавление;

 <script type="text/javascript">

const audio = document.querySelector('myAudio');

audio.onended = (event) => {
  console.log('Video stopped either because 1) it was over, '  
      'or 2) no further data is available.');
};

</script>
 

и это…

 <script type="text/javascript">
const audio = document.querySelector('myAudio');

audio.addEventListener('ended', (event) => {
  console.log('Video stopped either because 1) it was over, '  
      'or 2) no further data is available.');
});

</script>
 

и это…

 <script type="text/javascript">
myAudio.addEventListener("ended", function(){
     myAudio.currentTime = 0;
     console.log("ended");
     alert("ended");
});

</script>
 

Но ни один из них не работает. Что я делаю не так?

Обновить

Благодаря вкладу @Roko C. Буляна я смог использовать следующий сценарий для загрузки нового трека в проигрыватель div#. Когда трек заканчивается, щелчок моделируется с помощью функции ajax loadurl, и новая дорожка загружается в #плеер. Это загружает новую дорожку, но когда эта дорожка заканчивается, она не загружает другую дорожку. Как я могу это исправить?

 <a href="javascript:;" id="randomplay" onClick="loadurl('player.php?random=1','player')"></a>
<script type="text/javascript">

const audio = document.querySelector('#myAudio');

audio.addEventListener("ended", () => {

        $("#randomplay").click();

    }); 

</script>
 

Комментарии:

1. пс… ПРЕКРАТИТЕ использовать on* встроенные обработчики JS. JS (такой же, как СТИЛЬ) должен быть в соответствующих тегах или файлах. Используйте addEventListener вместо этого. Также text/javascript не требуется в <script> теге начиная с HTML5.

2. Кроме того, document.querySelector('#myAudio'); не должно быть document.querySelector('myAudio');

3. @RokoC. Булян, привет, братан! Так что я заставил его работать до некоторой степени, но я не могу заставить его загрузить следующий трек. Есть какие-нибудь идеи? Я использую ajax для загрузки страницы php в div, но после загрузки следующего трека она не может загрузиться снова.

Ответ №1:

Tl;Dr: Используйте: audio.addEventListener("ended", playNextFn);

Есть две возможности:

1. Если у клиента нет полного списка треков:

Создайте маршрут на своем сервере, который может отвечать случайным треком, и отправьте его обратно через AJAX клиенту в формате JSON {"src": "bazzz.mp3", "name": "", "group": "", "year": "", "cover": ""} .

 const audio = new Audio(); // or: document.querySelector('#myAudio');

const playRandomFile = () => {
  fetch("/api/getRandomSong.php").then(res => res.json).then(data => {
    audio.src = data.src;
    audio.play();
  });
};

audio.addEventListener("ended", playRandomFile); // ♫♪♫...♪♫♪♫♪...♫♪!
 

Надеюсь, вы знаете, как написать PHP-код, который получает случайную запись из songs таблицы базы данных и возвращает ее в формате JSON.

2. Если клиент заранее знает все треки:

Используйте JS для переключения на случайную дорожку при "ended" событии.

 const songs = [
  {src: "xyz.mp3", name: "", group: "", year:"", cover: ""},
  {src: "foo.mp3", name: "", group: "", year:"", cover: ""},
  {src: "bar.mp3", name: "", group: "", year:"", cover: ""},
];

const audio = new Audio(); // or: document.querySelector('#myAudio');

const playRandomFile = () => {
  audio.src = songs[~~(Math.random() * songs.length)].src;
  audio.play();
};

audio.addEventListener("ended", playRandomFile); // ♫♪♫...♪♫♪♫♪...♫♪!
 

Совет дня: вы можете сгенерировать свой HTML в JS прямо из songs массива.

Полный Пример

с аудиофайлами Викимедиа и <audio> элементом HTML:

 const songs = [
  {src: "https://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg", name: "", group: "", year:"", cover: ""},
  {src: "https://upload.wikimedia.org/wikipedia/en/3/39/Metallica_-_Enter_Sandman.ogg", name: "", group: "", year:"", cover: ""},
  {src: "https://upload.wikimedia.org/wikipedia/en/5/5e/U2_One.ogg", name: "", group: "", year:"", cover: ""},
];

const audio = document.querySelector('#myAudio');
const getRandomSong = () => songs[~~(Math.random() * songs.length)];

audio.addEventListener("ended", () => {
  audio.src = getRandomSong().src
  audio.play()
}); 

audio.src = getRandomSong().src // on DOM ready 
 <audio id="myAudio" controls></audio> 

Комментарии:

1. Спасибо за это, но будет ли это означать, что все песни должны быть перечислены первыми, верно? Если в бд более 1000 песен, все они должны быть перечислены, а затем случайным образом выбраны одна? Есть ли способ вместо этого просто извлечь одну песню из базы данных в конце трека?

2. @JaySmoke Да, в таком случае вам нужен PHP-маршрут, например: /api/getRandomSong.php это отвечает JSON, например {file: "bazzz.mp3", name: "", group: "", year:"", cover: ""} , и с этого момента вы просто загружаете его в аудиообъект, как в playRandomFile примере функции. Как использовать JS fetch … что ж, надеюсь, вы сможете поискать это в Google! В противном случае я могу привести вам краткий пример, если вам это покажется слишком сложным.

3. Я попробовал ваше предложение, но получил неперехваченную ошибку (в обещании). Исключение DOMException: воспроизвести() не удалось, потому что пользователь сначала не взаимодействовал с документом. Я думаю, мне понадобится этот быстрый пример выборки JS, когда мы туда доберемся 🙂

4. @JaySmoke добавил пример и исправил другой.

5. Теперь, так ~~(Math.random() * songs.length) как мог бы случайно дать снова тот же индекс и воспроизвести ту же песню… ваша задача как инженера-убедиться, что вы больше не будете играть одну и ту же песню. Это задание/домашнее задание для читателя.