#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
примере функции. Как использовать JSfetch
… что ж, надеюсь, вы сможете поискать это в Google! В противном случае я могу привести вам краткий пример, если вам это покажется слишком сложным.3. Я попробовал ваше предложение, но получил неперехваченную ошибку (в обещании). Исключение DOMException: воспроизвести() не удалось, потому что пользователь сначала не взаимодействовал с документом. Я думаю, мне понадобится этот быстрый пример выборки JS, когда мы туда доберемся 🙂
4. @JaySmoke добавил пример и исправил другой.
5. Теперь, так
~~(Math.random() * songs.length)
как мог бы случайно дать снова тот же индекс и воспроизвести ту же песню… ваша задача как инженера-убедиться, что вы больше не будете играть одну и ту же песню. Это задание/домашнее задание для читателя.