[Сайт] Запросы песен

djsoft

Administrator
Команда форума
Скрипт запроса песен для RadioBOSS. Пример реализации системы запроса песен в RadioBOSS.

Руководство пользователя по запросам песен: https://manual.djsoft.net/radioboss/ru/songrequests.htm

Как это работает
Скрипт показывает три поля: исполнитель, название и сообщение. Как минимум одно из полей (название или исполнитель) должно быть заполнено.

Запрошенная песня ищется в базе. Если трек найден, то он помещается в список запрошенных треков в RadioBOSS наряду с сообщеним.

Рекомендуется некоторе знание web технологий для установки и использования скрипта.

Если скрипт не работает, вы можете установить $show_errors в 1 для показа детальных сообщений об ошибке. Не забудьте установить обратно в 0 как только отладка закончена.

Дополнительная информация и настраиваемые параметры расположены в начале файла.

Код:
<?php
/*
    RadioBOSS Song Request demo script

    To play the requested songs in RadioBOSS, schedule an event with "playrequestedsong" command:
    http://manual.djsoft.net/radioboss/en/scheduler_commands.htm#songrequest

    Please make sure the RadioBOSS API is enabled and a password is set:
    http://manual.djsoft.net/radioboss/en/remote_controlapi.htm

	If RadioBOSS is installed on a server, please make sure the API port (9000 by default) is allowed in firewall.

    Home or studio PC:
	If RadioBOSS is installed on a home or studio PC, please make sure it has a static IP address.
    If a static IP address is not available, a Dynamic DNS address has to be used instead
    The IP address (or dynamic DNS address) is entered into the $rb_server variable (please do not include http://)
	
	If a computer is behing a NAT (this is usually the case when a router is used), then API port (9000 by default) has
	to be forwarded in router settings - please see the port forwarding documentation for your router.
*/

//---------------//
// CONFIGURATION //
//---------------//
//RadioBOSS API connection details
$rb_server = '127.0.0.1'; //RadioBOSS hostname or IP
$rb_port = '9000'; //RadioBOSS port
$rb_password = '7bNR5UK'; //API password
//music library name, omitting the .xml extension, the library is loaded from "Music library folder" as set in RadioBOSS settings
$rb_library = 'music';

//show detailed error messages (1 - show error details, 0 - show only general error messages)
//IMPORTANT! Make sure this is set to 0 once everything is configured and working to avoid revealing too many details to users!
//Error messages may contain passwords and other sensitive information
//Set this to 1 only if something's not working to get more details
$show_errors = 0;

//-------------------//
// SONG REQUEST FORM //
//-------------- ----//
//API URL base
$rb_api = "http://$rb_server:$rb_port?pass=$rb_password";
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title>RadioBOSS Song Request demo</title>
    <style>
        body {
            font-family: Tahoma, sans-serif;
            font-size: 0.8em;
        }
        label {
            display: block;
            margin-bottom: 5pt;
        }
    </style>
</head>
<body>
<?php

$last_err = ''; //last HTTPGet error message

function HTTPGet($url) {
    global $last_err;
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    $res = curl_exec($curl);
    if ($res === false) {
        $last_err = curl_error($curl);
    }
    curl_close($curl);
    return $res;
}

function result($msg) {
    $back_link = '<a href="javascript:history.back();">Back</a>';
    exit("$msg $back_link");
}

$type = isset($_POST['type']) ? $_POST['type'] : '';
if ($type === '') {
    echo '<form method="post">
            <input type="hidden" name="type" value="request">
            <label>Artist
<input size="30" name="artist"></label>
            <label>Title
<input size="30" name="title"></label>
            <label>Message
<textarea cols="30" rows="3" name="message"></textarea></label>
            <button>Request a song</button>
        </form>';
} elseif ($type === 'request') {
    //requested artist
    $artist = mb_strtolower(trim($_POST['artist']));
    if ($artist === '') {
        $artist = false;
    }
    //requested title
    $title = mb_strtolower(trim($_POST['title']));
    if ($title === '') {
        $title = false;
    }
    if (($artist === false) && ($title === false)) {
        result('No artist or title entered.');
    }
    //load library
    $library_raw = HTTPGet("$rb_api&action=library&filename=" . urlencode($rb_library));
    if ($library_raw === false) {
        $err = 'Song request failed: unable to load music library.';
        if ($show_errors) {
            $err .= ' Error: ' . $last_err;
        }
        result($err);
    }
    //parse XML data
    $xml = simplexml_load_string($library_raw);
    if ($xml === false) {
        result('Song request failed: unable to parse music library XML data.');
    }
    $fn = false;
    //search requested song in a music library
    foreach ($xml as $x) {
        if ($x->getName() !== 'Track') {
            continue;
        }
        $found = (($artist === false) || (mb_strtolower((string)$x['artist']) === $artist)) &&
            (($title === false) || (mb_strtolower((string)$x['title']) === $title));
        if ($found) {
            $fn = (string)$x['filename'];
            break;
        }
    }
    //song found, add to requested songs list in RadioBOSS
    if ($fn !== false) {
        $msg = isset($_POST['message']) ? $_POST['message'] : '';
        $res = HTTPGet("$rb_api&action=songrequest&filename=" . urlencode($fn) . '&message=' . urlencode($msg));
        if ($res === 'OK') {
            result('Song requested successfully!');
        } else {
            $err = 'An error occurred while adding song request.';
            if ($show_errors) {
                $err .= ' Error: ' . $last_err;
            }
            result($err);
        }
    } else {
        result('Requested song not found in the music library.');
    }
}
?>
</body>
</html>
 

Вложения

  • songrequest.php
    5,3 КБ · Просмотры: 421
pluta сказал(а):
спасибо, пять лет ждал
Вы бы спросили, скрипт уже несколько лет как доступен на английской части форума :) При недавнем обновлении скрипта выложили его и сюда - видно, не зря.
 
Предлагаю поразмышлять над темой организации онлайн системы для РБ...
Посмотрел на АПИ (это конечно боль) и думал как бы все прописать... но есть моменты...

Например как вариант получить базу командой library и хранить ее на сервере, потому что каждый раз дергать и обрабатывать базу с РБ это жесть, тем более планируется у меня база довольно крупная. И тут встает вопрос поддержания ее в актуальном состоянии. Как вариант может быть можно было бы как-то фиксировать в муз.базе дату изменения треков (там теги добавились/удалились, рейтинг и т.п.) и получать с РБ какой-то командой по АПИ только измененные там допустим раз в час или в сутки и обновлять их на сервере, а не всю базу каждый раз...

! Да, и пока не забыл, не нашел какой командой можно получить все о конкретном треке, есть базу целиком, есть плейлист, текущий, следующий трек, а вот именно как получить всю инфу о любом из базы нет, если только колбасить всю базу и вытягивать... но это все выглядит как жесть каждый раз дергать всю базу... Было бы неплохо добавить такую команду в АПИ.

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

Дальше пока думаю... пока не будет решения с максимально оперативной актуализацией и синхронизацией инфы по трекам между муз.базой локальной РБ и сервером дальше двигаться не вижу как.... а постоянно нагружающие варианты запроса и постоянной обработки всей муз.базы это вообще не подходит от слова совсем.... ибо это жесть...


Какие есть мысли, идеи?
 
Например как вариант получить базу командой library и хранить ее на сервере, потому что каждый раз дергать и обрабатывать базу с РБ это жесть, тем более планируется у меня база довольно крупная.
Если база и правда настолько большая, что ее сложно получить командой library (то есть, проверено, что на практике это действительно неприемлемо долго) - то можно использовать MySQL/MariaDB и получать данные напрямую из базы.

Да, и пока не забыл, не нашел какой командой можно получить все о конкретном треке, есть базу целиком, есть плейлист, текущий, следующий трек, а вот именно как получить всю инфу о любом из базы нет, если только колбасить всю базу и вытягивать... но это все выглядит как жесть каждый раз дергать всю базу... Было бы неплохо добавить такую команду в АПИ.
Или получить всю базу, или получить плейлист командой getplaylist2 или получить информацию о конкретном треке через readtag.
 
Дальше возвращаясь к скрипту, как вариант как-то придумать, чтобы при изменении в треках муз.базы программой чего-то автоматом типа рейтинга или вручную, чтоб как-то сразу изменения по треку отправлялись на сервер и там обновлялись (это было бы вообще риалтайм круто) - но как...
Здесь опять же вариант c MariaDB и подключением к базе напрямую.

постоянно нагружающие варианты запроса и постоянной обработки всей муз.базы это вообще не подходит от слова совсем.... ибо это жесть...
База должна быть действительно большой, чтобы это было проблемой.
 
можно использовать MySQL/MariaDB и получать данные напрямую из базы
Хм... что-то я про этот вариант забыл, наверное потому что у меня на сервере более старые версии и обновить сложновато, так как есть другие проекты... да и не очень хотелось менять локально Sqlite. Но в принципе то как вариант, спасибо, что напомнили. По возможности испытаю.

или получить информацию о конкретном треке через readtag
Круто, то что надо! Только добавить возврат атрибута Language как в команде library, может пригодиться. И еще обратил внимание, что этой командой возвращается также обложка, которой нет в library. А если надо выводить, например, результат поиска по базе с обложками или даже тупо всю базу табличкой с обложками?

А дальше опять боль... включая головную..
Плохо, что разные команды возвращают результаты с разным названием атрибутов, например в getplaylist2 доп. поля как F1="" F2="" и время в формате HH:MM, когда library возвращает RBField1="" RBField2="" и время в секундах.
Получается нельзя написать какую-то универсальную функцию попроще, надо для разных команд учитывать разные названия эти... КАША... Зачем и почему так делать?


Что это за параметры FT_IDX="-1" и PQUEUE="0" возвращаемые командой getplaylist2 ?

Эти два параметра я так пока понял одно и то же или чем-то отличаются? Во втором, как я понял из примера в справке вся история проигрываний, только разделить бы какой-то запятой, а то пробелом и так разделена дата и время....

1644533780616.png
 
База должна быть действительно большой, чтобы это было проблемой.
Большой по вашему мнению, это насколько большой?
Ну и надо учитывать еще, что запросы будут умножаться при одновременном просмотре данных разными посетителями...
 
Нашел вариант проверить, но... На сервере MariaDB 10.5.8, настроил все, сконвертировал доп.инфу (правда со второго раза получилось, первый раз ничего не сделало, даже таблиц не создало), так вот все вроде сконвертировало, правда таблица libraries пустая, но после переключения в РБ на MySQL в муз.базе пусто и нет выбора этой базы в меню Файл - Открыть... (появляется только при запуске муз.базы окошко с предложением на англ. открыть или создать новую... Как подтянуть не пойму..
 
Плохо, что разные команды возвращают результаты с разным названием атрибутов, например в getplaylist2 доп. поля как F1="" F2="" и время в формате HH:MM, когда library возвращает RBField1="" RBField2="" и время в секундах.
Получается нельзя написать какую-то универсальную функцию попроще, надо для разных команд учитывать разные названия эти... КАША... Зачем и почему так делать?
Основная причина почему так сделано - внутренние структуры преобразуются в XML, и выводятся почти как есть. Перевести одно в другое, в общем-то, проблема небольшая если вы уже пишете какой-то скрипт для этого.

Что это за параметры FT_IDX="-1" и PQUEUE="0" возвращаемые командой getplaylist2 ?
FT_IDX номер типа файла (2 - первый, 3 - второй и так далее). PQUEUE позиция в очереди воспроизведения.

Во втором, как я понял из примера в справке вся история проигрываний, только разделить бы какой-то запятой, а то пробелом и так разделена дата и время....
Он разделен символом Tab (0x09). Разбить строки можно просто по длительности - они имеют фиксированную длину.

Большой по вашему мнению, это насколько большой?
Ну и надо учитывать еще, что запросы будут умножаться при одновременном просмотре данных разными посетителями...
Большая это когда команды выполняются долго и/или возникает непримелемо высокая заугрзка процессора/сети. Если по факту этих проблем нет и, попросту говоря, "все работает" - то база небольшая. Если есть проблемы, то нужно переходить на MySQL/MariaDB.

правда таблица libraries пустая, но после переключения в РБ на MySQL в муз.базе пусто и нет выбора этой базы в меню Файл - Открыть... (появляется только при запуске муз.базы окошко с предложением на англ. открыть или создать новую... Как подтянуть не пойму..
Встроенного импорта нет. Самый простой вариант - создать базы заново.
 
Дааа... не думал я, что все окажется настолько неудобно с АПИ - это просто слезы и боль... что-то более-менее путевое сделать по интеграции на сайт, заказов и т.д. получается, как вы любите говорить, "экономически необоснованно"

Плохо, что нету отдельной таблицы в базе по запросам песен, это бы уже упростило немного.
Зачем отдельно таблица taginfo с парой полей, почему не добавить все в одну таблицу эту tracks2, проблемы как бы нет объединить в запросе, но это жуть какая-то... ну и еще с таблицей library_1 приходиться объединять, чтобы по пути получать track_id, которым они все связаны... прям дичь...

В запросах вообще не густо... добавить бы хотя бы поле автора сообщения, вместо столбца Сообщение в окошке, тем более что есть ниже большое поле с сообщением, также мне например нафиг не нужно видеть сколько минут назад было заказано, мне надо фиксировать датe/время заказа, чтобы блокировать трек к повторному заказу на какое-то время... но этого даже через АПИ не отдает..

Почему при отправке запрошенного трека в плейлист он остается торчать в списке запрошенных, может оно и где-то надо, но должна быть опция что удалять при постановке в плейлист. Также было бы хорошо чтоб какой-то префикс добавлялся к треку... чисто визуальная метка, что он заказан... плюс как его назначить в тип файла, чтоб выделить заказанные каким-то цветом и т.д. Куча недоработок по заказам...

И если бы все это писалось в отдельную таблицу БД, было проще с этим работать, а так надо городить непонятно что и не понятно как... например можно где-то в свою отдельную таблицу писать заказы, но как ее в релтайме синхронизировать с РБ... дергать каждую минуту по АПИ список запрошенных, парсить и сверять какой там трек уже отыграл какие нет... бред какой-то... короче ужас... прям перехотелось возиться с этим...

Эх... сижу вспоминаю дядюшку СЕМа... насколько там все было удобно реализовано... просто работаешь с базой и работаешь себе как с сайтом... а тут то по АПИ дергай РБ, то парсь XML, то обратно....туда-сюда гоняй что-то... зачем все так усложнять... вы сами то не путаетесь...

В общем не понятно как с этим работать, чтоб не насиловать мозг и без извращений...
 
Последнее редактирование:
Тема очень актуальная и для меня. Как только создам централизованную базу на MySQL, вплотную этим займусь. И давайте будем делиться наработками в этом направлении.
 
Плохо, что нету отдельной таблицы в базе по запросам песен, это бы уже упростило немного.
Список запрошенных песен можно получить через API RadioBOSS - в базе это не хранится, да и зачем? В работе программы это никак не используется.

Зачем отдельно таблица taginfo с парой полей, почему не добавить все в одну таблицу эту tracks2, проблемы как бы нет объединить в запросе, но это жуть какая-то... ну и еще с таблицей library_1 приходиться объединять, чтобы по пути получать track_id, которым они все связаны... прям дичь...
Это все стандартные вещи. INNER JOIN и прочее в помощь.

В запросах вообще не густо... добавить бы хотя бы поле автора сообщения, вместо столбца Сообщение в окошке, тем более что есть ниже большое поле с сообщением, также мне например нафиг не нужно видеть сколько минут назад было заказано, мне надо фиксировать датe/время заказа, чтобы блокировать трек к повторному заказу на какое-то время... но этого даже через АПИ не отдает..
Вы можете сделать свою форму заказа на сайте с любым количеством полей, и далее их форматировать как вам удобно (например, первая строка автор, далее сообщение) и отправлять как message при вызове функции API для создания заказанной песни.

Почему при отправке запрошенного трека в плейлист он остается торчать в списке запрошенных, может оно и где-то надо, но должна быть опция что удалять при постановке в плейлист. Также было бы хорошо чтоб какой-то префикс добавлялся к треку... чисто визуальная метка, что он заказан... плюс как его назначить в тип файла, чтоб выделить заказанные каким-то цветом и т.д. Куча недоработок по заказам...
Как вы ставите трек в плейлист? Через команду playrequestedsong трек будет удаляться из списка запрошенных.
Отдельный тип файла здесь создаст больше проблем - в частности, по кроссфейдам и прочие побочные эффекты. Зачем отмечать трек в плейлисте?

И если бы все это писалось в отдельную таблицу БД, было проще с этим работать, а так надо городить непонятно что и не понятно как... например можно где-то в свою отдельную таблицу писать заказы, но как ее в релтайме синхронизировать с РБ... дергать каждую минуту по АПИ список запрошенных, парсить и сверять какой там трек уже отыграл какие нет... бред какой-то... короче ужас... прям перехотелось возиться с этим...
Зачем нужно получать список запрошенных песен? Если просто вывести на сайт, достаточно просто периодически вызывать API для получения списка запросов.

Эх... сижу вспоминаю дядюшку СЕМа... насколько там все было удобно реализовано... просто работаешь с базой и работаешь себе как с сайтом... а тут то по АПИ дергай РБ, то парсь XML, то обратно....туда-сюда гоняй что-то... зачем все так усложнять... вы сами то не путаетесь...
Чем больше прямой работы с базой тем больше потенциальных проблем, неправильный запрос может серьезно повредить базу, исказить или удалить данные. Вызовы команд API намного более безопасны, т.к. RadioBOSS при исполнении команд делает массу различных проверок.
 
Я конечно в глубине души понимал, что ответ будет таким как всегда... но в то же время, как всегда, надеялся на что-то более адекватное... на понимание... К сожалению куда не поверни везде тупик!
 
Я конечно в глубине души понимал, что ответ будет таким как всегда... но в то же время, как всегда, надеялся на что-то более адекватное... на понимание... К сожалению куда не поверни везде тупик!
А как, по вашему, должно быть "адекватно"? Переделывать API под ваши нужды? Если есть конкретное предложение, например, добавить какую-то команду, или расширить имеющуюся - это очень часто делается, вы можете видеть это по форуму, а особенно в английской части. У вас же претензии в стиле "оказывается API еще и программировать надо" :)
 
Встроенного импорта нет. Самый простой вариант - создать базы заново.
Вот переделываю тут пробую и опять надо импортировать... э то просто дичь какя-то... что мешает тупо при конвертации перенести все с tracks.db в MySQL, то есть включая созданные БД. В SQlite есть записи в таблице libraries, а в Mysql после экспорта она пустая, и доп.таблиц вида libraries_1б libraries_1 и т.д. нету. Мало того непонятно нафига они вообще нужны там эти libraries_1 и т.д., где только id базы, id трека и путь к треку, нет просто в одной таблице tracks2 добавить столбец с id базы и все. Вот же у вас привычка везде закладывать неудобства для пользователя.

И еще после экспорта если глянуть сразу в меню Файл - Открыть то там пусто, нет выбора открытых ранее баз. Аналогично и при удалении несуществующих записей из БД.

Также открыл в Муз.Базе бд где 115 треков, очистил от удаленных, очистило также и в другой БД. Что это за самодеятельность, мне нужно было только в одной открытой текущей почистить...
 
нет просто в одной таблице tracks2 добавить столбец с id базы и все
Трек может быть более чем в одной базе. Плюс вообще непонятно, какая разница как устроена база? Она есть и работает.
По поводу переноса, это редкая задача, поэтому конвертера нет. Основной объем это информация о треках, сами базы можно быстро заново сделать.

Также открыл в Муз.Базе бд где 115 треков, очистил от удаленных, очистило также и в другой БД. Что это за самодеятельность, мне нужно было только в одной открытой текущей почистить...
Если вы делаете очистку базы от несуществующих на диске треков, они удаляются полностью, из всех баз.
 
Трек может быть более чем в одной базе.
Так я и говорю, что просто добавить один столбец с id базы в tracks2 и все... и эти доп. таблицы не нужны...

И если оно уж создает таблицу libraries то в чем проблема перенести туда и названия баз... нет вам вместо прописать одну строчку надо вынуждать пользователя создавать базы заново. Вот зачем? И какая разница редкая, не редкая задача - почему не сделать просто, чтоб все переносилось и все..


Еще при удалении несуществующих бывает зависает на 50%, то есть сразу быстро бац на 50% встает прогресс и все.. то ли надо ждать полчаса и я просто не дождался толи глюк.. Также иногда удалило несуществующие, через секунду запускаешь заново и еще пару файлов пишет удалено и т.д. Чего оно за раз не может удалить все несуществующие... между повторами файлы не трогались вообще никак..
При этом еще раз обращаю внимание, что при удалении несуществующих, а также при конвертации почему-то пропадают в меню Файл - Открыть записи существующих баз и появляются только после перезапуска муз.базы.
 
А вот этот столбец modified_tag в taginfo - это дата-время последнего изменения или что? Не пойму как его преобразовать в читаемый вид формата д-м-г ч:м
 
Так я и говорю, что просто добавить один столбец с id базы в tracks2 и все... и эти доп. таблицы не нужны...
В ваш id можно будет только одно значение внести, а трек может находиться в нескольких разных базах. Отдельно замечу, что в любом случае структура базы данных меняться не будет.

И какая разница редкая, не редкая задача - почему не сделать просто, чтоб все переносилось и все..
Потому что разработка это затраты, а вот эта функция нужна одному человеку из 10000 раз в год, а то и реже. Смысла нет.

При этом еще раз обращаю внимание, что при удалении несуществующих, а также при конвертации почему-то пропадают в меню Файл - Открыть записи существующих баз и появляются только после перезапуска муз.базы.
Эта ошибка не воспоизводится.
По удалению несуществующих треков, почему может быть медленно или еще что-то, тут сложно сказать, сама функция работает просто: идет по списку и если трека нет, удаляется запись. Зависания могут, вероятно, быть из-за антивирусов, т.к. тут идет довольно активная работа с диском.
 
Назад
Верх