audioplay: clean up, add missing code for audio/internet player functionality

* favorites handling
* auto play
* xml data/logo handling
* locales
* settings
* clean ups

taken from https://bitbucket.org/neutrino-images/ni-neutrino-hd
This commit is contained in:
2018-05-28 21:36:35 +02:00
parent 730a357368
commit 3ac8217d07
10 changed files with 163 additions and 80 deletions

View File

@@ -37,8 +37,6 @@
#include <driver/rcinput.h>
#include <driver/audioplay.h>
#include <driver/audiometadata.h>
#include <driver/display.h>
#include <system/httptool.h>
#include <daemonc/remotecontrol.h>
@@ -95,8 +93,10 @@ extern cVideo * videoDecoder;
#define AUDIOPLAYER_START_SCRIPT CONFIGDIR "/audioplayer.start"
#define AUDIOPLAYER_END_SCRIPT CONFIGDIR "/audioplayer.end"
#define DEFAULT_RADIOSTATIONS_XMLFILE CONFIGDIR "/radio-stations.xml"
#define DEFAULT_RADIOFAVORITES_XMLFILE CONFIGDIR "/radio-favorites.xml"
const char RADIO_STATION_XML_FILE[] = {DEFAULT_RADIOSTATIONS_XMLFILE};
const char RADIO_FAVORITES_XML_FILE[] = {DEFAULT_RADIOFAVORITES_XMLFILE};
CAudiofileExt::CAudiofileExt() : CAudiofile(), firstChar('\0')
{
@@ -253,6 +253,13 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey)
m_select_title_by_name = g_settings.audioplayer_select_title_by_name;
}
//auto-load favorites
if ((m_inetmode) && (m_playlist.empty()))
{
if (access(RADIO_FAVORITES_XML_FILE, F_OK) == 0)
scanXmlFile(RADIO_FAVORITES_XML_FILE);
}
if (m_playlist.empty())
m_current = -1;
else
@@ -305,6 +312,10 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey)
m_LastMode = CNeutrinoApp::getInstance()->getMode();
CNeutrinoApp::getInstance()->handleMsg(NeutrinoMessages::CHANGEMODE , NeutrinoModes::mode_audio);
// wake up hdd
printf("[audioplayer.cpp] wakeup_hdd(%s)\n", g_settings.network_nfs_audioplayerdir.c_str());
wakeup_hdd(g_settings.network_nfs_audioplayerdir.c_str()/*,true*/);
puts("[audioplayer.cpp] executing " AUDIOPLAYER_START_SCRIPT ".");
if (my_system(AUDIOPLAYER_START_SCRIPT) != 0)
perror(AUDIOPLAYER_START_SCRIPT " failed");
@@ -352,10 +363,20 @@ int CAudioPlayerGui::show()
bool clear_before_update = false;
m_key_level = 0;
// auto-play first entry from favorites
if (g_settings.inetradio_autostart)
{
if ((m_inetmode) && (!m_playlist.empty()))
{
m_current = 0;
m_selected = 0;
play(m_selected);
}
}
while (loop)
{
updateMetaData();
updateTimes();
// stop if mode was changed in another thread
@@ -437,7 +458,7 @@ int CAudioPlayerGui::show()
if (m_state != CAudioPlayerGui::STOP)
stop();
}
#if 0 //add RC_favorites for internetradio
//add RC_favorites for internetradio
else if ((msg == CRCInput::RC_favorites) && (m_inetmode))
{
if (m_key_level == 0)
@@ -453,7 +474,6 @@ int CAudioPlayerGui::show()
}
}
}
#endif
else if (msg == CRCInput::RC_left || msg == CRCInput::RC_previoussong)
{
if (m_key_level == 1)
@@ -635,7 +655,7 @@ int CAudioPlayerGui::show()
// keylevel 2 can only be reached if the currently played file
// is no stream, so we do not have to test for this case
int seconds=0;
CIntInput secondsInput(LOCALE_AUDIOPLAYER_JUMP_DIALOG_TITLE,
CIntInput secondsInput( LOCALE_AUDIOPLAYER_JUMP_DIALOG_TITLE,
&seconds,
5,
LOCALE_AUDIOPLAYER_JUMP_DIALOG_HINT1,
@@ -685,6 +705,10 @@ int CAudioPlayerGui::show()
CMenuSelectorTarget *InetRadioInputChanger = new CMenuSelectorTarget(&select);
// -- setup menue for inetradio input
sprintf(cnt, "%d", count);
InputSelector.addItem(new CMenuForwarder(
LOCALE_AUDIOPLAYER_ADD_FAV, true, NULL, InetRadioInputChanger,
cnt, CRCInput::convertDigitToKey(count + 1)), old_select == count);
sprintf(cnt, "%d", ++count);
InputSelector.addItem(new CMenuForwarder(
LOCALE_AUDIOPLAYER_ADD_LOC, true, NULL, InetRadioInputChanger,
cnt, CRCInput::convertDigitToKey(count + 1)), old_select == count);
@@ -711,21 +735,28 @@ int CAudioPlayerGui::show()
switch (select)
{
case 0:
scanXmlFile(RADIO_STATION_XML_FILE);
scanXmlFile(RADIO_FAVORITES_XML_FILE);
CVFD::getInstance()->setMode(CVFD::MODE_AUDIO);
paintLCD();
break;
case 1:
readDir_ic();
scanXmlFile(RADIO_STATION_XML_FILE);
CVFD::getInstance()->setMode(CVFD::MODE_AUDIO);
paintLCD();
break;
case 2:
readDir_ic();
CVFD::getInstance()->setMode(CVFD::MODE_AUDIO);
paintLCD();
break;
case 3:
openSCbrowser();
break;
default:
break;
}
m_current = 0;
m_selected = 0;
update=true;
}
else if (shufflePlaylist())
@@ -745,7 +776,7 @@ int CAudioPlayerGui::show()
// keylevel 2 can only be reached if the currently played file
// is no stream, so we do not have to test for this case
int seconds=0;
CIntInput secondsInput(LOCALE_AUDIOPLAYER_JUMP_DIALOG_TITLE,
CIntInput secondsInput( LOCALE_AUDIOPLAYER_JUMP_DIALOG_TITLE,
&seconds,
5,
LOCALE_AUDIOPLAYER_JUMP_DIALOG_HINT1,
@@ -1032,7 +1063,7 @@ bool CAudioPlayerGui::shufflePlaylist(void)
return(result);
}
void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const time_t bitrate)
void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const char *logo, const time_t bitrate)
{
CAudiofileExt mp3(url, CFile::STREAM_AUDIO);
//tmp = tmp.substr(0,tmp.length()-4); //remove .url
@@ -1043,19 +1074,27 @@ void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const t
}
else
{
std::string tmp = mp3.Filename.substr(mp3.Filename.rfind('/')+1);
mp3.MetaData.title = tmp;
std::string filename = mp3.Filename.substr(mp3.Filename.rfind('/') + 1);
mp3.MetaData.title = filename;
}
if (logo != NULL)
mp3.MetaData.logo = logo;
else
mp3.MetaData.logo.clear();
if (bitrate)
mp3.MetaData.total_time = bitrate;
else
mp3.MetaData.total_time = 0;
mp3.MetaData.url = url;
if (url[0] != '#')
addToPlaylist(mp3);
}
void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, const time_t tim)
void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, const char *logo, const time_t tim)
{
CURL *curl_handle;
struct MemoryStruct chunk;
@@ -1079,8 +1118,7 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons
/* we pass our 'chunk' struct to the callback function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
/* some servers don't like requests that are made without a user-agent
field, so we provide one */
/* some servers don't like requests that are made without a user-agent field, so we provide one */
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
/* don't use signal for timeout */
@@ -1093,15 +1131,15 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons
curl_easy_perform(curl_handle);
/*
* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*
* Do something nice with it!
*
* You should be aware of the fact that at this point we might have an
* allocated data block, and nothing has yet deallocated that data. So when
* you're done with it, you should free() it as a nice application.
*/
Now, our chunk.memory points to a memory block that is chunk.size
bytes big and contains the remote file.
Do something nice with it!
You should be aware of the fact that at this point we might have an
allocated data block, and nothing has yet deallocated that data. So when
you're done with it, you should free() it as a nice application.
*/
long res_code;
if (curl_easy_getinfo(curl_handle, CURLINFO_HTTP_CODE/*CURLINFO_RESPONSE_CODE*/, &res_code) == CURLE_OK)
@@ -1134,7 +1172,7 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons
tmp = strchr(line, '\n');
if (tmp != NULL)
*tmp = '\0';
addUrl2Playlist(ptr, name, tim);
addUrl2Playlist(ptr, name, logo, tim);
break;
}
}
@@ -1192,7 +1230,7 @@ void CAudioPlayerGui::readDir_ic(void)
{
xmlDocPtr answer_parser = parseXml(answer.c_str());
scanBox->hide();
scanXmlData(answer_parser, "listen_url", "server_name", "bitrate", true);
scanXmlData(answer_parser, "listen_url", "server_name", "", "bitrate", true);
}
else
scanBox->hide();
@@ -1203,10 +1241,10 @@ void CAudioPlayerGui::readDir_ic(void)
void CAudioPlayerGui::scanXmlFile(std::string filename)
{
xmlDocPtr answer_parser = parseXmlFile(filename.c_str());
scanXmlData(answer_parser, "url", "name");
scanXmlData(answer_parser, "url", "name", "logo");
}
void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, const char *nametag, const char *bitratetag, bool usechild)
void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, const char *nametag, const char *logotag, const char *bitratetag, bool usechild)
{
#define IC_typetag "server_type"
@@ -1241,6 +1279,8 @@ void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, c
const char *ptr = NULL;
const char *name = NULL;
const char *url = NULL;
const char *logo = NULL;
time_t bitrate = 0;
bool skip = true;
listPos++;
@@ -1258,10 +1298,12 @@ void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, c
xmlNodePtr child = xmlChildrenNode(element);
while (child)
{
if (strcmp(xmlGetName(child), nametag) == 0)
name = xmlGetData(child);
else if (strcmp(xmlGetName(child), urltag) == 0)
if (strcmp(xmlGetName(child), urltag) == 0)
url = xmlGetData(child);
else if (strcmp(xmlGetName(child), nametag) == 0)
name = xmlGetData(child);
else if (strcmp(xmlGetName(child), logotag) == 0)
logo = xmlGetData(child);
else if (strcmp(xmlGetName(child), IC_typetag) == 0)
type = xmlGetData(child);
else if (bitratetag && strcmp(xmlGetName(child), bitratetag) == 0)
@@ -1284,6 +1326,7 @@ void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, c
{
url = xmlGetAttribute(element, urltag);
name = xmlGetAttribute(element, nametag);
logo = xmlGetAttribute(element, logotag);
if (bitratetag)
{
ptr = xmlGetAttribute(element, bitratetag);
@@ -1298,9 +1341,9 @@ void CAudioPlayerGui::scanXmlData(xmlDocPtr answer_parser, const char *urltag, c
progress.showStatusMessageUTF(url);
//printf("Processing %s, %s\n", url, name);
if (strstr(url, ".m3u") || strstr(url, ".pls"))
processPlaylistUrl(url, name);
processPlaylistUrl(url, name, logo);
else
addUrl2Playlist(url, name, bitrate);
addUrl2Playlist(url, name, logo, bitrate);
}
element = xmlNextNode(element);
g_RCInput->getMsg(&msg, &data, 0);
@@ -1357,7 +1400,7 @@ bool CAudioPlayerGui::openFilebrowser(void)
#endif // LCD_UPDATE
}
if (
(files->getType() == CFile::FILE_CDR)
(files->getType() == CFile::FILE_CDR)
|| (files->getType() == CFile::FILE_OGG)
|| (files->getType() == CFile::FILE_MP3)
|| (files->getType() == CFile::FILE_WAV)
@@ -1417,7 +1460,7 @@ bool CAudioPlayerGui::openFilebrowser(void)
if (strstr(url, ".m3u") || strstr(url, ".pls"))
processPlaylistUrl(url);
else
addUrl2Playlist(url, name, duration);
addUrl2Playlist(url, name, NULL, duration);
}
else if ((url = strstr(cLine, "icy://")) != NULL)
{
@@ -1458,7 +1501,7 @@ bool CAudioPlayerGui::openFilebrowser(void)
playlistItem.Name = filename;
CFile::FileType fileType = playlistItem.getType();
if (
fileType == CFile::FILE_CDR
fileType == CFile::FILE_CDR
|| fileType == CFile::FILE_MP3
|| fileType == CFile::FILE_OGG
|| fileType == CFile::FILE_WAV
@@ -1561,7 +1604,7 @@ bool CAudioPlayerGui::openSCbrowser(void)
#endif // LCD_UPDATE
}
//printf("processPlaylistUrl(%s, %s)\n", files->Url.c_str(), files->Name.c_str());
processPlaylistUrl(files->Url.c_str(), files->Name.c_str(), files->Time);
processPlaylistUrl(files->Url.c_str(), files->Name.c_str(), NULL, files->Time);
g_RCInput->getMsg(&msg, &data, 0);
}
if (m_select_title_by_name)
@@ -1798,7 +1841,7 @@ void CAudioPlayerGui::paintCover()
if (cover_object)
{
cover_object->doPaintBg(false);
cover_object->SetTransparent(CFrameBuffer::TM_BLACK);
// cover_object->SetTransparent(CFrameBuffer::TM_BLACK);
cover_object->setHeight(m_title_height - 2*OFFSET_INNER_SMALL, true);
cover_object->paint();
@@ -1952,32 +1995,43 @@ void CAudioPlayerGui::paintDetailsLine(int pos)
m_infobox->forceTextPaint(false);
}
//title
std::string text_info = m_playlist[m_selected].MetaData.title;
// first line
std::string text_info("");
getFileInfoToDisplay(text_info, m_playlist[m_selected]);
//date, genre
if (m_playlist[m_selected].MetaData.genre.empty())
text_info = m_playlist[m_selected].MetaData.date;
else if (m_playlist[m_selected].MetaData.date.empty())
text_info = m_playlist[m_selected].MetaData.genre;
text_info += "\n";
// second line; url or date and genre
if (m_inetmode)
{
if (!m_playlist[m_selected].MetaData.url.empty())
{
text_info += m_playlist[m_selected].MetaData.url;
}
else
text_info += " ";
}
else
{
text_info = m_playlist[m_selected].MetaData.genre;
text_info += " / ";
text_info += m_playlist[m_selected].MetaData.date;
}
bool got_date = false;
if (!m_playlist[m_selected].MetaData.date.empty())
{
got_date = true;
text_info += m_playlist[m_selected].MetaData.date;
}
//artist, album
text_info = m_playlist[m_selected].MetaData.artist;
if (!(m_playlist[m_selected].MetaData.album.empty()))
{
text_info += " (";
text_info += m_playlist[m_selected].MetaData.album;
text_info += ')';
}
bool got_genre = false;
if (!m_playlist[m_selected].MetaData.genre.empty())
{
got_genre = true;
if (got_date)
text_info += " / ";
text_info += m_playlist[m_selected].MetaData.genre;
}
// 'simulate' a second line; maybe usefull for some more informations e.g. url or so
text_info += "\n ";
if (!got_date && !got_genre)
text_info += " ";
}
m_infobox->setText(text_info, CTextBox::AUTO_WIDTH, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO], COL_MENUCONTENTDARK_TEXT);
m_infobox->paint(false);
@@ -2280,13 +2334,13 @@ void CAudioPlayerGui::updateTimes(const bool force)
int x_total_time = m_x + m_width - OFFSET_INNER_MID - w_total_time - 2*m_titlebox->getFrameThickness();
// played time offset to align this value on the right side
int o_played_time = std::max(w_faked_time - w_played_time, 0);
int x_faked_time = m_x + m_width - OFFSET_INNER_MID - w_total_time - w_faked_time;
int x_faked_time = x_total_time - w_faked_time;
int x_played_time = x_faked_time + o_played_time;
int y_times = m_y + OFFSET_INNER_SMALL;
if (updateTotal && !m_inetmode)
{
m_frameBuffer->paintBoxRel(x_total_time, y_times, w_total_time + OFFSET_INNER_MID, m_item_height, m_titlebox->getColorBody());
m_frameBuffer->paintBoxRel(x_total_time, y_times, w_total_time, m_item_height, m_titlebox->getColorBody());
if (m_time_total > 0)
{
g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x_total_time, y_times + m_item_height, w_total_time, total_time, COL_MENUHEAD_TEXT); //total time
@@ -2444,26 +2498,29 @@ void CAudioPlayerGui::getFileInfoToDisplay(std::string &fileInfo, CAudiofileExt
if (g_settings.audioplayer_display == TITLE_ARTIST)
{
fileInfo += title;
if (!title.empty() && !artist.empty()) fileInfo += ", ";
if (!title.empty() && !artist.empty())
fileInfo += " - ";
fileInfo += artist;
}
else //if (g_settings.audioplayer_display == ARTIST_TITLE)
{
fileInfo += artist;
if (!title.empty() && !artist.empty()) fileInfo += ", ";
if (!title.empty() && !artist.empty())
fileInfo += " - ";
fileInfo += title;
}
if (!file.MetaData.album.empty())
{
fileInfo += " (";
fileInfo += " - ";
fileInfo += file.MetaData.album;
fileInfo += ')';
}
if (fileInfo.empty())
{
fileInfo += "Unknown";
}
file.firstChar = (char)tolower(fileInfo[0]);
//info += fileInfo;
}
@@ -2473,7 +2530,7 @@ void CAudioPlayerGui::addToPlaylist(CAudiofileExt &file)
//printf("add2Playlist: %s\n", file.Filename.c_str());
if (m_select_title_by_name)
{
std::string t = "";
std::string t("");
getFileInfoToDisplay(t,file);
}
else
@@ -2655,8 +2712,8 @@ unsigned char CAudioPlayerGui::getFirstChar(CAudiofileExt &file)
{
if (file.firstChar == '\0')
{
std::string info;
getFileInfoToDisplay(info,file);
std::string info("");
getFileInfoToDisplay(info, file);
}
//printf("getFirstChar: %c\n",file.firstChar);
return file.firstChar;
@@ -2766,7 +2823,7 @@ void CAudioPlayerGui::savePlaylist()
snprintf(msg, msgsize,
"%s\n%s",
g_Locale->getText(LOCALE_AUDIOPLAYER_PLAYLIST_FILEERROR_MSG),
absPlaylistFilename.c_str());
absPlaylistFilename.c_str());
DisplayErrorMessage(msg);
// refresh view
@@ -2798,14 +2855,13 @@ bool CAudioPlayerGui::askToOverwriteFile(const std::string& filename)
snprintf(msg, filename.length() + 126,
"%s\n%s",
g_Locale->getText(LOCALE_AUDIOPLAYER_PLAYLIST_FILEOVERWRITE_MSG),
filename.c_str());
filename.c_str());
bool res = (ShowMsg(LOCALE_AUDIOPLAYER_PLAYLIST_FILEOVERWRITE_TITLE, msg, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo) == CMsgBox::mbrYes);
this->paint();
return res;
}
std::string CAudioPlayerGui::absPath2Rel(const std::string& fromDir,
const std::string& absFilename)
std::string CAudioPlayerGui::absPath2Rel(const std::string& fromDir, const std::string& absFilename)
{
std::string res = "";