Как обслуживать случайный элемент, чтобы каждый пользователь получал одинаковый случайный элемент в одинаковом порядке? - PullRequest
0 голосов
/ 20 мая 2018

Я строю онлайн-радиостанцию.Я создал базу данных XML для хранения списка воспроизведения информации о песне, чтобы пользователи могли получать определенный аудиофайл, определенный списком воспроизведения (XML), в предопределенном порядке;таким образом создавая иллюзию шоу .Эти шоу обычно длятся час.Что я хочу сделать, так это случайно генерировать информацию о песне после окончания шоу, чтобы создать бесконечный, случайный список воспроизведения из всей моей базы данных.Но случайная песня должна быть предоставлена ​​всем пользователям, чтобы каждый из них получил одинаковый опыт (одну и ту же песню).Представляется важным также проиллюстрировать, как мои шоу обслуживаются в реальном времени, поскольку этот тип диктует, как должен работать мой генератор случайных чисел .Чтобы сэкономить время и пространство, я опущу некоторые функции этих функций, поскольку они могут быть довольно длинными.Если вы хотите увидеть эти опущенные функции, я могу отправить их по запросу.Моя первоначальная мысль создать этот генератор случайных чисел состояла в том, чтобы использовать SSE (события, отправленные сервером), но, возможно, есть более простой способ.

У меня есть документ Javascript, которыйиспользует AJAX для запроса базы данных (плейлиста):

load_prs(track_data_complete , "playlist.xml") ;

track_data_complete() получает ответ и обновляет аудиоплеер информацией о текущей песне, а затем совершает другой вызов AJAX на timestamp.php:

var current_play = 0 ; // current_play is global to indicate current song element in the playlist XML array
var track_length ; // Store current track length in seconds
var track_obj ; // object data for current song
var showtime ; // the shows beginning unix time
var timestamp ; // current unix time

function track_data_complete( XML )
{
var th = XML.children[current_play] ;
var band = get_val(th , "band") ; // get_val parses the XML data
var album = get_val(th , "album") ;
var title = get_val(th , "title") ;
var genre = get_val(th , "genre") ;
track_length = get_val(th , "length") ;
var tid = th.getAttribute("id") ;
var tsrc = "songs/" + tid + ".mp3" ;
track_obj = new tobj(band , album , title , genre , length , tsrc) ; // tobj creates a new object to store the data

showtime = Number(XML.getAttribute("showtime")) ;
load_prs(load_track , "timestamp.php?time=0") ;
}

timestamp.php

<?php echo ( time() + $_REQUEST['time'] . "" ) ; ?>

load_track() воспроизводит песню в режиме реального времени, используя метку времени Unix, возвращаемую timestamp.php, затем обновляет проигрыватель с информацией о песне:

function load_track( resp )
{
timestamp = Number(resp) ;
track_src.src = track_obj.tsrc ; // track_src is the audio element source
player_title.innerHTML = track_obj.band + " - " + track_obj.title ;
player_album.innerHTML = "Album: " + track_obj.album ;
track_audio.onended = function() { next_track() ; } ; // track_audio is the HTML audio element
track_audio.load() ;
begin_play() ;
}

begin_play() использует математику для расчета реального времени, чтобы решить, в какое время начать воспроизведение аудио.Это имитирует воспроизведение звука в реальном времени.если время превышает длину первой песни, переходите к следующей песне, пока текущее время не превысит showtime:

function begin_play()
{
swap("stop_track") ;
var time = timestamp - showtime ;
if ( time < track_length ) { track_audio.currentTime = time ; }
else { return next_track() ; }
track_audio.play() ;
}

next_track() увеличивает current_play и добавляет showtime и текущий track_length вместе, затем снова вызывает track_list_complete() и начинает этот процесс заново.

playlist.xml

<?xml version="1.0" encoding="UTF-8"?>
<playlist auto="no" showtime="1526448420">
  <track id="funeral_doom_003">
    <genre>Funeral Doom</genre>
    <band>Depressed Mode</band>
    <album>Ghosts of Devotion</album>
    <title>Words of Silence</title>
    <length>3016</length>
  </track>
  <track id="funeral_doom_001">
    <genre>Funeral Doom</genre>
    <band>Evoken</band>
    <album>A Caress of the Void</album>
    <title>Descend the Lifeless Womb</title>
    <length>4270</length>
  </track>
</playlist>

ПРИМЕЧАНИЕ. Вся моя база данных находится в файлах XML.Каждый файл - это жанр музыки.Поскольку у меня есть три жанра, есть три файла XML.Файл списка воспроизведения является отдельным, потому что он дает мне возможность создавать шоу.Файл списка воспроизведения и файлы жанра очень похожи по структуре, список воспроизведения содержит большинство одинаковых данных данной песни.На первый взгляд, вы думаете, что нужно просто выбрать случайную песню из базы данных жанров, но это даст потенциально разные песни для каждого пользователя.Аналогичным образом, выбор случайных песен из плейлиста оставляет мою базу данных.

1 Ответ

0 голосов
/ 20 мая 2018

Используйте PRNG на стороне клиента, чтобы перебрать список воспроизведения в случайном порядке, и дать каждому клиенту одинаковое начальное число, чтобы все они получали одинаковые бесконечные случайные числа .Вы можете реализовать свой собственный более простой PRNG, такой как линейный конгруэнтный генератор, который генерирует каждое число один раз, прежде чем появятся какие-либо повторы, или вы можете просто использовать PRNG для подачи алгоритма случайного перемешивания.

Вы можете простозакодируйте начальное значение, например 42, в файл .js или поместите его в часть <script> HTML-кода, сгенерированного php.Или, как вы говорите, если клиентам все равно нужно скачать файл XML, поместите туда параметры PRNG, чтобы вы могли легко редактировать файл списка воспроизведения, чтобы получить другой порядок.

Вы можете даже уменьшить размер того, чтоклиенты должны загрузить по всего , предоставив им параметры PRNG для генерации случайных чисел в диапазоне 0..N, и сопоставить эти числа с песнями на стороне сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...