Бесшовная звуковая петля в произвольное положение
Одна из вещей, которые мне больше всего нравятся в формате MOD, - это способность возвращаться к любой заданной точке песни, делая ее идеальной для песен, которые имеют "enter", а затем "основной цикл".
Конечно, MP3 не может этого сделать.
До сих пор я делал такие вещи:
<audio src="/path/to/song.mp3" onEnded="this.currentTime = 12.345;"></audio>
Где значение float - это время начала основного цикла.
В то время как это работает, есть заметная доля секунды, когда звук перезапускается. Я могу уменьшить эффект этой паузы, установив целевое время немного впереди, где это должно быть, поэтому биты, по крайней мере, со временем приближаются, однако это не идеально.
Главной альтернативой, о которой я могу думать, является ручная запись аудиофайла (например, в Audacity путем копирования) для создания песни, которая больше, чем она, скорее всего, понадобится, но проблема заключается в том, что это привело бы к большому количеству потраченного впустую места на жестком диске и пропускной способности, и это не решило бы проблему людей, любящих песню, и прекратить слушать ее в течение длительного времени.
Так что мне было интересно, есть ли способ спеть поток MP3. Если я правильно понимаю формат, я должен быть в состоянии определить, в какой позиции в файле (в байтах) начинается основной цикл (в секундах), поэтому теоретически я мог бы построить поток, который циклически бесконечно. Однако будет ли такой поток поддерживаться с помощью HTM5 audio?
Ответы
Ответ 1
Пробуйте измерять задержку каждый раз:
function playSeamless(clip, next) {
if(!next) {
next = clip.cloneNode(true);
next.controls = false;
}
var start = Date.now();
clip.play();
setTimeout(function() {
var time = (Date.now() - start) / 1000;
var position = clip.currentTime;
var delay = time - position;
setTimeout(function() {
// Set desired currentTime on next here and adjust delay above
playSeamless(next, clip);
}, (clip.duration - clip.currentTime - delay * 2.35) * 1000 | 0);
}, 200);
}
playSeamless(yourAudioClip);
Это было лучше, но не совсем точно, поэтому мне нужно настроить * 2.35
или сделать его вычитанием или чем-то.