Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как проиграть рандомный отрезок аудио? (https://javascript.ru/forum/misc/78688-kak-proigrat-randomnyjj-otrezok-audio.html)

VeliaR 20.10.2019 21:51

Как проиграть рандомный отрезок аудио?
 
Нужно выбрать рандомное аудио из папки и затем проиграть рандомный отрезок из этого аудио (допустим, 3-5 секунд).
Каким образом это можно сделать?
Заранее спасибо!

Опан1 21.10.2019 09:52

Допустим, в папке 10 аудиофайлов с именнами 1.mp3, 2.mp3 и т. д.
<button onclick="myplay()"> play </button>

var audio = new Audio();
function myplay(){
	audio.src = Math.ceil(Math.random() * 10) + ".mp3";
	audio.onloadeddata = function(){
		this.currentTime = Math.random() * this.duration;
		this.play();
		setTimeout(function(){audio.pause()}, 3 + Math.random() * 2);
	}
}

laimas 21.10.2019 11:12

Опан1,
таймер тут лишний, есть событие timeupdate.

Опан1 21.10.2019 12:21

Как бы там ни было, но если ничего не предпринять, то сразу после объявления src свойство duration не успеет прочитаться из файла и выдаст NaN.

laimas 21.10.2019 12:30

Цитата:

Сообщение от Опан1
Как бы там ни было, но если ничего не предпринять, то сразу после объявления src свойство duration

Ну для этого и есть событие onloadeddata, а далее нужно обрабатывать изменение иного события. Странно другое, ведь кость может выпасть и на все, и уж коли случайно, то по идее не более T.

Опан1 21.10.2019 13:02

Не совсем понял, о чём Вы? А перед этим ещё хотел спросить, как тут можно применить timeupdate?
...
Да, я не сразу сориентировался, но всё равно, разве удобней будет с помощью timeupdate задать рандомное время 3-5 сек, чем таймером?

laimas 21.10.2019 13:51

Цитата:

Сообщение от Опан1
Не совсем понял, о чём Вы?

Не обращать внимания, просто автоматом да не о том. )

Опан1 21.10.2019 14:26

Ещё второй вариант я вижу - сравнивать с currentTime, который будет через 3-5 сек, тогда будет без таймера, но чем это лучше, не знаю.

laimas 21.10.2019 14:44

Цитата:

Сообщение от Опан1
тогда будет без таймера, но чем это лучше, не знаю.

Но а зачем он нужен, если через каждую секунду (приблизительно) у проигрывателя срабатывает событие timeupdate, в котором и нужно сравнивать текущее положение с заданным?

Опан1 21.10.2019 15:35

Тут похоже, что оно выполняетя где-то 4 раза в секунду. Это ещё ничего, я сначала думал, что оно срабатывает чаще - с каждым новым семплом или что-то в этом роде. Вот бы грузило браузер. Фактически currentTime меняется с каждым семплом.

laimas 21.10.2019 16:55

<audio id="my" autoplay="" controls="" src="https://fotodushi.ru/mus/engsong8090/11_Chris_Rea-And_you_my_love.mp3"></audio>
<script>
document.getElementById('my').addEventListener("timeupdate", function() { 
    if(this.currentTime > this.duration * .3) this.pause()
}, true);
</script>

VeliaR 21.10.2019 17:16

Почему то не срабатывает.
Забыл добавить, что все это должно выполняться в цикле с рандомными промежутками.
Вот мой код:

<script>
function mp3play(){
    var rnd_num = Math.floor(Math.random() * 1200) + 1;		// max delay in seconds
	var audio = new Audio();
	audio.volume = 1;
	audio.src = "/mp3/" + (Math.floor(Math.random() * 40) + 1) + ".mp3";		// count of files in folder
    audio.onloadeddata = function(){
        audio.currentTime = Math.random() * audio.duration;
        audio.play();
        setTimeout(function(){audio.pause()}, 3 + Math.random() * 2);
    }
	setTimeout(mp3play,rnd_num * 1000);
}

mp3play();
</script>


Что здесь не так?

рони 21.10.2019 17:26

VeliaR,
если ошибок нет, файлы просто неуспевают прогрузится, возможно rnd_num маловато, и смотрите консоль.

Опан1 21.10.2019 17:47

А в консоли не появляется ошибка, что файл не найден? Если да, то попробуйте в 6 строке убрать первый слеш, оставить audio.src = "mp3/"...
Ещё у Вас типичная ошибка - запуск плеера вез взаимодействя с посетителем сайта. Для этого я и был всавил button.

laimas 21.10.2019 17:47

VeliaR,
по идее последующий запуск таймера нужно производить после проигрывания фрагмента, и это единственный таймер нужный.

рони 21.10.2019 17:56

VeliaR,
может поменять строки 6 и 7 местами?

Опан1 21.10.2019 18:02

Но тогда получится, что загрузка данных будет из неизвестного файла, так как src ещё будет неопределено.

рони 21.10.2019 18:15

Цитата:

Сообщение от Опан1
что загрузка данных будет из неизвестного файла

:-?

laimas 21.10.2019 18:17

<audio id="my" controls=""></audio>

<script>
var host = 'https://fotodushi.ru/mus/',
    mp3 = [
    'muzdushi/01La_Belle_Mixtape-Summer_Memories_O_Henri_Pfr.mp3',
    'muzdushi/02Oliver_Shanti-Sacral_Nirvana.mp3',
    'muzdushi/03Eroticheskiy_saksofon-Melodiya_lubvi.mp3',
    'muzdushi2/15Anugama-Rhythm_Of_Love.mp3',
    'muzdushi2/16Rondo_Veneziano-Musica_Fantasia.mp3',
    'muzzhizni/15-Tango_Orchester_Alfred_Hause-La_Cumparsita.mp3',
    'classic/01-Mihail_Oginskiy-Polonez.mp3',
    'muzlove/01-Mehdi-Guiding_Light.mp3',
    'muzlove/15-Elman_Namazoglu-Mehebbetim.mp3',
    'engsong8090/11_Chris_Rea-And_you_my_love.mp3',
    'krugosvet/01_Petr_Chaykovskiy-Chanson_triste.mp3',
    'france/09_Barimar-A_Paris.mp3',
    'france/16_Salvatore_Adamo-Tombe_la_neige.mp3',
    'italia/01_Biagio_Antonacci-Pazzo_Di_Lei.mp3',
    'russia/19_Aleksey_Arhipovskiy-Zolushka.mp3',
    'enigma/03_Enigma-Mea_Culpa_Part_II_(Fading_Shades_Mix).mp3'
], mp = document.getElementById('my');

function timer() {
    var wait = 1000 + Math.floor(Math.random() * 500),
        tm = 10 + Math.random() * 20,
        src = host + mp3[mp3.length * Math.random()|0];
        setTimeout(function(){
            mp.src = src;
            mp.oncanplay = function() {
                this.play()
            }
            mp.ontimeupdate = function() { 
                if(this.currentTime > tm) {
                    this.pause();
                    timer();    
                } 
            }
        }, wait);
}
timer();
</script>


PS. Math.random(), это псевдослучайность, а не случайность, значит будут повторы. По уму нужно удалять из массива уже проигранные.

VeliaR 21.10.2019 18:22

В консоли след. ошибка: Uncaught (in promise) DOMException
Что это может значить и как исправить?

Опан1 21.10.2019 18:29

Повесить запуск функции mp3play(); на нажатие кнопки или другое событие, связанное с взаимодействием с посетителем сайта..

VeliaR 21.10.2019 18:33

Цитата:

Сообщение от Опан1 (Сообщение 514350)
Повесить запуск функции mp3play(); на нажатие кнопки или другое событие, связанное с взаимодействием с посетителем сайта..

Уже сделал.
onclick="mp3play()"

Кроме того, в консоли появилась еще одна ошибка:
GET http://test.loc/mp3/23.mp3 net::ERR_CACHE_OPERATION_NOT_SUPPORTED

И так с разными другими файлами. Тоже интересно, что бы это могло значить?

рони 21.10.2019 18:43

laimas,
setTimeout зачем?
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">

</head>

<body>
<audio id="my" controls=""></audio>

<script>
var host = 'https://fotodushi.ru/mus/',
    mp3 = [
    'muzdushi/01La_Belle_Mixtape-Summer_Memories_O_Henri_Pfr.mp3',
    'muzdushi/02Oliver_Shanti-Sacral_Nirvana.mp3',
    'muzdushi/03Eroticheskiy_saksofon-Melodiya_lubvi.mp3',
    'muzdushi2/15Anugama-Rhythm_Of_Love.mp3',
    'muzdushi2/16Rondo_Veneziano-Musica_Fantasia.mp3',
    'muzzhizni/15-Tango_Orchester_Alfred_Hause-La_Cumparsita.mp3',
    'classic/01-Mihail_Oginskiy-Polonez.mp3',
    'muzlove/01-Mehdi-Guiding_Light.mp3',
    'muzlove/15-Elman_Namazoglu-Mehebbetim.mp3',
    'engsong8090/11_Chris_Rea-And_you_my_love.mp3',
    'krugosvet/01_Petr_Chaykovskiy-Chanson_triste.mp3',
    'france/09_Barimar-A_Paris.mp3',
    'france/16_Salvatore_Adamo-Tombe_la_neige.mp3',
    'italia/01_Biagio_Antonacci-Pazzo_Di_Lei.mp3',
    'russia/19_Aleksey_Arhipovskiy-Zolushka.mp3',
    'enigma/03_Enigma-Mea_Culpa_Part_II_(Fading_Shades_Mix).mp3'
], mp = document.getElementById('my'), tm;

mp.addEventListener("canplay", function() {
    this.play()
}, true);

mp.addEventListener("timeupdate", function() {
                if(this.currentTime > tm) {
                    this.pause();
                    timer();
                }
            })

function timer() {
        tm = 10 + Math.random() * 20;
        mp.src = host + mp3[mp3.length * Math.random()|0];
}

timer();
</script>

</body>
</html>

laimas 21.10.2019 18:47

Цитата:

Сообщение от VeliaR
В консоли след. ошибка: Uncaught (in promise) DOMException

Это мне? Это я часть старого кода поместил, исправлено, должно работать. :)

laimas 21.10.2019 18:49

Цитата:

Сообщение от рони
setTimeout зачем?

По условию, что через случайное время проигрывать последующие:

Цитата:

Сообщение от VeliaR
Забыл добавить, что все это должно выполняться в цикле с рандомными промежутками.

Я лично бы тоже это убрал, так как продолжительность фрагмента случайна.

laimas 21.10.2019 23:07

Что-то не врублюсь почему с вызовом через таймер условие this.currentTime > this.duration * .1 срабатывает дважды (проигрывает через один), если наступление события timeupdate можно еще как-то было объяснить, то с условием не понять.

<audio id="my" controls=""></audio>
<div id="fl"></div>

<script>
var host = 'https://fotodushi.ru/mus/',
    mp3 = [
    'muzdushi/01La_Belle_Mixtape-Summer_Memories_O_Henri_Pfr.mp3',
    'muzdushi/02Oliver_Shanti-Sacral_Nirvana.mp3',
    'muzdushi/03Eroticheskiy_saksofon-Melodiya_lubvi.mp3',
    'muzdushi2/15Anugama-Rhythm_Of_Love.mp3',
    'muzdushi2/16Rondo_Veneziano-Musica_Fantasia.mp3',
    'muzzhizni/15-Tango_Orchester_Alfred_Hause-La_Cumparsita.mp3',
    'classic/01-Mihail_Oginskiy-Polonez.mp3',
    'muzlove/01-Mehdi-Guiding_Light.mp3',
    'muzlove/15-Elman_Namazoglu-Mehebbetim.mp3',
    'engsong8090/11_Chris_Rea-And_you_my_love.mp3',
    'krugosvet/01_Petr_Chaykovskiy-Chanson_triste.mp3',
    'france/09_Barimar-A_Paris.mp3',
    'france/16_Salvatore_Adamo-Tombe_la_neige.mp3',
    'italia/01_Biagio_Antonacci-Pazzo_Di_Lei.mp3',
    'russia/19_Aleksey_Arhipovskiy-Zolushka.mp3',
    'enigma/03_Enigma-Mea_Culpa_Part_II_(Fading_Shades_Mix).mp3'
], mp = document.getElementById('my'), f = document.getElementById('fl'), n = -1;


mp.addEventListener("canplay", function() {
    this.play()
}, true);
 
mp.addEventListener("timeupdate", function() {
    if(this.currentTime > this.duration * .1) {
        console.log(1)
        this.pause();
        this.currentTime = 0;
        setTimeout(timer, 1000);
    }
});
 
function timer() {
        n = Math.ceil(++n % mp3.length);
        f.textContent = (n+1) + ' >> ' + mp3[n].split('/').pop();
        mp.src = host + mp3[n];
}
 
timer();
</script>


Все ясно, нужно позицию в начало.


Часовой пояс GMT +3, время: 22:26.