Init Commit
This commit is contained in:
parent
23663f9a11
commit
0f141119a2
|
@ -0,0 +1,19 @@
|
||||||
|
##
|
||||||
|
# radio_plus_plus
|
||||||
|
#
|
||||||
|
# @MakeFile
|
||||||
|
# @version 0.1
|
||||||
|
|
||||||
|
all: compile install config
|
||||||
|
|
||||||
|
compile:
|
||||||
|
g++ --verbose -o radio *.cpp *.h `wx-config --cxxflags --libs` -lvlc -lcurl -ljsoncpp -fgcse-after-reload -fipa-cp-clone -floop-interchange -floop-unroll-and-jam -fpeel-loops -fpredictive-commoning -fsplit-loops -fsplit-paths -ftree-loop-distribution -ftree-partial-pre -funswitch-loops -fvect-cost-model=dynamic -fversion-loops-for-strides
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp -v radio /usr/local/bin
|
||||||
|
|
||||||
|
config:
|
||||||
|
mkdir -p ~/.config/radio++
|
||||||
|
touch ~/.config/radio++/sender
|
||||||
|
|
||||||
|
# end
|
30
README.md
30
README.md
|
@ -1,3 +1,29 @@
|
||||||
# radio_plus_plus
|
# Radio ++
|
||||||
|
### Dependencies
|
||||||
|
> g++ \
|
||||||
|
> wxgtk3 \
|
||||||
|
> vlc \
|
||||||
|
> curl \
|
||||||
|
> jsoncpp
|
||||||
|
|
||||||
A cool c++ Internet Radio Player
|
### Arch
|
||||||
|
```
|
||||||
|
sudo pacman -S gcc wxgtk3 vlc curl jsoncpp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debian/Ubuntu
|
||||||
|
```
|
||||||
|
sudo apt-get install g++ libwxgtk3.0-dev libvlc-dev libcurl-dev libjsoncpp-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gentoo GNU/Linux
|
||||||
|
```
|
||||||
|
doas emerge -aq jsoncpp vlc x11-libs/wxGTK-3.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installing
|
||||||
|
```
|
||||||
|
git clone https://github.com/MIROowo/radio_plus_plus.git
|
||||||
|
cd radio_plus_plus
|
||||||
|
sh compile.sh
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
g++ -o radio *.cpp *.h `wx-config --cxxflags --libs` -lvlc -lcurl -ljsoncpp
|
||||||
|
|
||||||
|
if [ -x ./radio ]
|
||||||
|
then
|
||||||
|
read -p "Do u want to install the Binary? [y/N] " input
|
||||||
|
|
||||||
|
if [ $input = "y" ] || [ $input = "Y" ]
|
||||||
|
then
|
||||||
|
mkdir -p ~/.config/radio++/
|
||||||
|
touch ~/.config/radio++/sender
|
||||||
|
doas cp -v radio /usr/local/bin/
|
||||||
|
echo "Finished!"
|
||||||
|
else
|
||||||
|
echo "bye :c"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "something went wrong :/"
|
||||||
|
echo "exit..."
|
||||||
|
fi
|
|
@ -0,0 +1,220 @@
|
||||||
|
#include "main.h"
|
||||||
|
#include "search.h"
|
||||||
|
|
||||||
|
// Binding events to functions
|
||||||
|
wxBEGIN_EVENT_TABLE(cFrame, wxFrame)
|
||||||
|
EVT_BUTTON(1001, cFrame::OnPP)
|
||||||
|
EVT_SLIDER(1002, cFrame::OnScroll)
|
||||||
|
EVT_BUTTON(1003, cFrame::OnAdd)
|
||||||
|
EVT_BUTTON(1004, cFrame::OnRemove)
|
||||||
|
EVT_BUTTON(1005, cFrame::OnSearch)
|
||||||
|
EVT_BUTTON(1008, cFrame::refreshEvent)
|
||||||
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
|
// Window content
|
||||||
|
cFrame::cFrame() : wxFrame(nullptr, wxID_ANY, "Radio++", wxPoint(30, 30), wxSize(450, 600)) {
|
||||||
|
|
||||||
|
wxFrame::SetMinSize(wxSize(450, 600));
|
||||||
|
wxFrame::SetMaxSize(wxSize(450, 600));
|
||||||
|
|
||||||
|
menuBar->Append(menuHelp, "&Help");
|
||||||
|
menuHelp->Append(wxID_ABOUT);
|
||||||
|
menuHelp->AppendSeparator();
|
||||||
|
menuHelp->Append(wxID_EXIT);
|
||||||
|
|
||||||
|
SetMenuBar(menuBar);
|
||||||
|
|
||||||
|
Bind(wxEVT_MENU, &cFrame::OnAbout, this, wxID_ABOUT);
|
||||||
|
Bind(wxEVT_MENU, &cFrame::OnExit, this, wxID_EXIT);
|
||||||
|
|
||||||
|
b_pp = new wxButton(this, 1001, "Play", wxPoint(10, 10), wxSize(100,50));
|
||||||
|
t_box = new wxTextCtrl(this, wxID_ANY, "", wxPoint(10, 190), wxSize(250, 30));
|
||||||
|
t_show = new wxStaticText(this, wxID_ANY, "None", wxPoint(10, 80), wxSize(50, 100));
|
||||||
|
s_val = new wxStaticText(this, wxID_ANY, "70", wxPoint(150, 100), wxSize(50, 100));
|
||||||
|
s_volume = new wxSlider(this, 1002, 70, 0, 100, wxPoint(50, 100), wxSize(220, 80));
|
||||||
|
|
||||||
|
b_add = new wxButton(this, 1003, "Add", wxPoint(280, 230), wxSize(80,30));
|
||||||
|
b_add = new wxButton(this, 1004, "Remove", wxPoint(280, 270), wxSize(80,30));
|
||||||
|
s_sender = new wxButton(this, 1005, "Search", wxPoint(280, 310), wxSize(80,30));
|
||||||
|
b_refresh = new wxButton(this, 1008, "Refresh", wxPoint(280, 350), wxSize(80,30));
|
||||||
|
l_sender = new wxListBox(this, wxID_ANY, wxPoint(10, 230), wxSize(250, 300));
|
||||||
|
|
||||||
|
// Text for the Statusbar
|
||||||
|
CreateStatusBar();
|
||||||
|
SetStatusText("Radio++");
|
||||||
|
|
||||||
|
cFrame::refreshList();
|
||||||
|
}
|
||||||
|
|
||||||
|
cFrame::~cFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFrame::refreshList() {
|
||||||
|
|
||||||
|
l_sender->Clear();
|
||||||
|
|
||||||
|
readfile.open(homedir+"/.config/radio++/sender");
|
||||||
|
|
||||||
|
if (readfile.is_open())
|
||||||
|
{
|
||||||
|
while ( getline (readfile,line) )
|
||||||
|
{
|
||||||
|
wxString wx_line(line);
|
||||||
|
l_sender->Append(wx_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
readfile.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFrame::refreshEvent(wxCommandEvent &evt) {
|
||||||
|
|
||||||
|
l_sender->Clear();
|
||||||
|
|
||||||
|
readfile.open(homedir+"/.config/radio++/sender");
|
||||||
|
|
||||||
|
if (readfile.is_open())
|
||||||
|
{
|
||||||
|
while ( getline (readfile,line) )
|
||||||
|
{
|
||||||
|
wxString wx_line(line);
|
||||||
|
l_sender->Append(wx_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
readfile.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Slider Value and sets Volume
|
||||||
|
void cFrame::OnScroll(wxCommandEvent &evt) {
|
||||||
|
|
||||||
|
wxString value = wxString::Format(wxT("%d"), (int)s_volume->GetValue());
|
||||||
|
|
||||||
|
s_val->SetLabel(value);
|
||||||
|
int vol = wxAtoi(value);
|
||||||
|
if (b_pp->GetLabel() == "Pause") {
|
||||||
|
libvlc_audio_set_volume(mp, vol);
|
||||||
|
}
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plays Radio sound yee
|
||||||
|
void cFrame::playRadio(const char* url) {
|
||||||
|
|
||||||
|
sender = libvlc_media_new_location(inst, url);
|
||||||
|
mp = libvlc_media_player_new_from_media(sender);
|
||||||
|
libvlc_media_player_play(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Play/Pause Button
|
||||||
|
void cFrame::OnPP(wxCommandEvent &evt) {
|
||||||
|
|
||||||
|
if(b_pp->GetLabel() == "Play") {
|
||||||
|
|
||||||
|
t_show->SetLabel("Playing...");
|
||||||
|
b_pp->SetLabel("Pause");
|
||||||
|
|
||||||
|
std::string url = std::string(l_sender->GetStringSelection().mb_str());
|
||||||
|
const char * c_url = url.c_str();
|
||||||
|
|
||||||
|
cFrame::playRadio(c_url);
|
||||||
|
|
||||||
|
wxString value = s_val->GetLabel();
|
||||||
|
int vol = wxAtoi(value);
|
||||||
|
libvlc_audio_set_volume(mp, vol);
|
||||||
|
|
||||||
|
} else if (b_pp->GetLabel() == "Pause") {
|
||||||
|
|
||||||
|
t_show->SetLabel("Paused");
|
||||||
|
b_pp->SetLabel("Play");
|
||||||
|
|
||||||
|
libvlc_media_player_stop(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
|
||||||
|
}
|
||||||
|
// Add Button
|
||||||
|
void cFrame::OnAdd(wxCommandEvent &evt) {
|
||||||
|
l_sender->Append(t_box->GetValue());
|
||||||
|
|
||||||
|
std::string item = std::string(t_box->GetValue().mb_str());
|
||||||
|
|
||||||
|
writefile.open(homedir+"/.config/radio++/sender", std::ios::app);
|
||||||
|
writefile << item << "\n";
|
||||||
|
|
||||||
|
writefile.close();
|
||||||
|
|
||||||
|
t_box->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Button
|
||||||
|
void cFrame::OnRemove(wxCommandEvent &evt) {
|
||||||
|
|
||||||
|
if (l_sender->GetSelection() != wxNOT_FOUND) {
|
||||||
|
|
||||||
|
std::string deleteline = std::string(l_sender->GetStringSelection().mb_str());
|
||||||
|
|
||||||
|
l_sender->Delete(l_sender->GetSelection());
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/26576714/deleting-specific-line-from-file
|
||||||
|
|
||||||
|
std::string path = homedir+"/.config/radio++/sender";
|
||||||
|
std::string tempfile = homedir+"/.config/radio++/temp.txt";
|
||||||
|
std::string line;
|
||||||
|
std::ifstream fin;
|
||||||
|
|
||||||
|
fin.open(path);
|
||||||
|
// contents of path must be copied to a temp file then
|
||||||
|
// renamed back to the path file
|
||||||
|
std::ofstream temp;
|
||||||
|
temp.open(homedir+"/.config/radio++/temp.txt");
|
||||||
|
|
||||||
|
while (getline(fin, line)) {
|
||||||
|
// write all lines to temp other than the line marked for erasing
|
||||||
|
if (line != deleteline)
|
||||||
|
temp << line << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.close();
|
||||||
|
fin.close();
|
||||||
|
|
||||||
|
// required conversion for remove and rename functions
|
||||||
|
const char * t = tempfile.c_str();
|
||||||
|
const char * p = path.c_str();
|
||||||
|
remove(p);
|
||||||
|
rename(t, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search Button
|
||||||
|
void cFrame::OnSearch(wxCommandEvent &evt)
|
||||||
|
{
|
||||||
|
cSearch* m_frame2 = new cSearch();
|
||||||
|
m_frame2->Show(true);
|
||||||
|
evt.Skip();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// OnAbout
|
||||||
|
void cFrame::OnAbout(wxCommandEvent &evt)
|
||||||
|
{
|
||||||
|
wxMessageBox("By MIRO#5825",
|
||||||
|
"About", wxOK | wxICON_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnExit
|
||||||
|
void cFrame::OnExit(wxCommandEvent &evt) {
|
||||||
|
libvlc_release (inst);
|
||||||
|
Close(true);
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <vlc/vlc.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
|
||||||
|
class cFrame : public wxFrame {
|
||||||
|
public:
|
||||||
|
cFrame();
|
||||||
|
~cFrame();
|
||||||
|
|
||||||
|
struct passwd *pw = getpwuid(getuid());
|
||||||
|
std::string homedir = pw->pw_dir;
|
||||||
|
|
||||||
|
// Window content declaration
|
||||||
|
|
||||||
|
libvlc_media_player_t *mp;
|
||||||
|
libvlc_media_t *sender;
|
||||||
|
|
||||||
|
libvlc_instance_t * inst = libvlc_new (0, NULL);
|
||||||
|
|
||||||
|
wxMenuBar *menuBar = new wxMenuBar;
|
||||||
|
wxMenu *menuHelp = new wxMenu;
|
||||||
|
|
||||||
|
wxTextCtrl *t_box = nullptr;
|
||||||
|
wxStaticText *t_show = nullptr;
|
||||||
|
|
||||||
|
wxListBox *l_sender = nullptr;
|
||||||
|
|
||||||
|
wxButton *b_pp = nullptr;
|
||||||
|
wxButton *b_add = nullptr;
|
||||||
|
wxButton *s_sender = nullptr;
|
||||||
|
wxButton *b_refresh = nullptr;
|
||||||
|
|
||||||
|
wxStaticText *s_val = nullptr;
|
||||||
|
wxSlider *s_volume = nullptr;
|
||||||
|
|
||||||
|
std::ifstream readfile;
|
||||||
|
std::ofstream writefile;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
void refreshList();
|
||||||
|
|
||||||
|
void refreshEvent(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void eraseFileLine(std::string path, std::string eraseLine);
|
||||||
|
|
||||||
|
void OnScroll(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void playRadio(const char* url);
|
||||||
|
|
||||||
|
void OnPP(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnAbout(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnExit(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnAdd(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnRemove(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void OnSearch(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
wxDECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,95 @@
|
||||||
|
#include "search.h"
|
||||||
|
|
||||||
|
wxBEGIN_EVENT_TABLE(cSearch, wxFrame)
|
||||||
|
EVT_BUTTON(1006, cSearch::onSearch)
|
||||||
|
EVT_BUTTON(1007, cSearch::onAdd)
|
||||||
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
|
cSearch::cSearch() : wxFrame(nullptr, wxID_ANY, "Search", wxPoint(30, 30), wxSize(500, 700))
|
||||||
|
{
|
||||||
|
wxFrame::SetMinSize(wxSize(500, 700));
|
||||||
|
wxFrame::SetMaxSize(wxSize(500, 700));
|
||||||
|
|
||||||
|
searchBox = new wxTextCtrl(this, wxID_ANY, "", wxPoint(10, 20), wxSize(300, 40));
|
||||||
|
searchButton = new wxButton(this, 1006, "Search", wxPoint(365, 20), wxSize(80, 40));
|
||||||
|
searchAdd = new wxButton(this, 1007, "Add", wxPoint(365, 70), wxSize(80, 40));
|
||||||
|
searchList = new wxListBox(this, wxID_ANY, wxPoint(10, 130), wxSize(480, 500));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cSearch::~cSearch()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||||
|
{
|
||||||
|
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cSearch::onSearch(wxCommandEvent &evt) {
|
||||||
|
|
||||||
|
searchList->Clear();
|
||||||
|
|
||||||
|
wxString boxValue(searchBox->GetValue());
|
||||||
|
std::string api = "https://api.laut.fm/search/stations?query=" + std::string(boxValue.mb_str());
|
||||||
|
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
std::string readBuffer;
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, api.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
|
||||||
|
bool j_parse = jread.parse(readBuffer, jval, false);
|
||||||
|
|
||||||
|
if (j_parse) {
|
||||||
|
|
||||||
|
Json::Value arrays = jval["results"][0]["items"];
|
||||||
|
|
||||||
|
int arraynum = arrays.size();
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < arraynum; i++)
|
||||||
|
{
|
||||||
|
std::string name = fastWriter.write(jval["results"][0]["items"][i]["station"]["stream_url"]);
|
||||||
|
searchList->Append(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSearch::onAdd(wxCommandEvent &evt)
|
||||||
|
{
|
||||||
|
if (searchList->GetSelection() != wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
std::string item = std::string(searchList->GetStringSelection());
|
||||||
|
|
||||||
|
item.erase(0, 1);
|
||||||
|
|
||||||
|
int start{item.length()-2};
|
||||||
|
int end{item.length()-1};
|
||||||
|
|
||||||
|
item.erase(start, end);
|
||||||
|
|
||||||
|
std::ofstream writefile;
|
||||||
|
|
||||||
|
writefile.open(homedir+"/.config/radio++/sender", std::ios::app);
|
||||||
|
writefile << item << "\n";
|
||||||
|
writefile.close();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
class cSearch : public wxFrame {
|
||||||
|
public:
|
||||||
|
cSearch();
|
||||||
|
~cSearch();
|
||||||
|
|
||||||
|
struct passwd *pw = getpwuid(getuid());
|
||||||
|
std::string homedir = pw->pw_dir;
|
||||||
|
|
||||||
|
Json::FastWriter fastWriter;
|
||||||
|
Json::Reader jread;
|
||||||
|
Json::Value jval;
|
||||||
|
|
||||||
|
wxTextCtrl *searchBox = nullptr;
|
||||||
|
wxButton *searchButton = nullptr;
|
||||||
|
wxButton *searchAdd =nullptr;
|
||||||
|
|
||||||
|
wxListBox *searchList = nullptr;
|
||||||
|
|
||||||
|
void onSearch(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
void onAdd(wxCommandEvent &evt);
|
||||||
|
|
||||||
|
wxDECLARE_EVENT_TABLE();
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "window.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
wxIMPLEMENT_APP(cWindow);
|
||||||
|
|
||||||
|
cWindow::cWindow() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cWindow::~cWindow() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GUI Init
|
||||||
|
bool cWindow::OnInit() {
|
||||||
|
|
||||||
|
m_frame1 = new cFrame();
|
||||||
|
m_frame1->Show(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue