It sort of works now. Pause button works, and shows album art locally and via https. Amazing.

This commit is contained in:
IXtreme 2024-12-21 22:36:12 -05:00
parent a68b76fed6
commit 1cfb148453
4 changed files with 189 additions and 65 deletions

View file

@ -25,7 +25,7 @@ LDFLAGS = -g
LDLIBS += -L lib/ LDLIBS += -L lib/
#LDLIBS += -L lib_web/ #LDLIBS += -L lib_web/
LD_DYNAMIC_LIBS = -lraylib -lsdbus-c++ -lmagic #only enable if dynamic mode LD_DYNAMIC_LIBS = -lraylib -lsdbus-c++ -lmagic -lcurl #only enable if dynamic mode
LD_STATIC_LIBS = -l:libraylib.a #only enable if static mode LD_STATIC_LIBS = -l:libraylib.a #only enable if static mode
EXTRA_DIRS = $(OBJ_DIR)/rlImGui EXTRA_DIRS = $(OBJ_DIR)/rlImGui

View file

@ -36,6 +36,7 @@
#include <iostream> #include <iostream>
#include <sdbus-c++/sdbus-c++.h> #include <sdbus-c++/sdbus-c++.h>
#include <string> #include <string>
#include <curl/curl.h>
extern "C" { extern "C" {
#include "testc.h" #include "testc.h"
} }
@ -136,6 +137,53 @@ std::vector<std::string> GetMprisServices() {
return ret; return ret;
} }
void DrawPlay(Vector2 Pos, float scale, Color color) {
Vector2 backtop = (Vector2) { .x=-0.29f, .y=-0.40f };
Vector2 backbot = (Vector2) { .x=-0.29f, .y=0.40f};
Vector2 front = (Vector2) {.x = 0.5f, .y=0};
backtop = Vector2Scale(backtop, scale);
backbot = Vector2Scale(backbot, scale);
front = Vector2Scale(front, scale);
backtop = Vector2Add(backtop, Pos);
backbot = Vector2Add(backbot, Pos);
front = Vector2Add(front, Pos);
DrawTriangle(backtop, backbot, front, color);
}
void DrawStop(Vector2 Pos, float scale, Color color) {
Vector2 topleft = (Vector2) {.x = -0.353f, .y = -0.353f };
Vector2 botright = (Vector2) {.x = 0.353f, .y = 0.353f };
topleft = Vector2Scale(topleft, scale);
botright = Vector2Scale(botright, scale*2);
topleft = Vector2Add(topleft, Pos);
DrawRectangleV(topleft, botright, color);
}
void DrawPause(Vector2 Pos, float scale, Color color) {
Vector2 topleft = (Vector2) {.x = -0.353f, .y = -0.353f };
Vector2 bar1topleft = Vector2Scale(topleft, scale);
bar1topleft = Vector2Add(bar1topleft, Pos);
Vector2 bar2topleft = Vector2Add(topleft, (Vector2) {0.706f*0.6f, .y=0});
bar2topleft = Vector2Scale(bar2topleft, scale);
bar2topleft = Vector2Add(bar2topleft, Pos);
Vector2 size = (Vector2) {.x=0.706f *0.4f, .y = 0.706f };
size = Vector2Scale(size, scale);
topleft = Vector2Add(topleft, Pos);
DrawRectangleV(bar1topleft, size, color);
DrawRectangleV(bar2topleft, size, color);
}
float ScaleToFit(Vector2 src, Vector2 dst) { float ScaleToFit(Vector2 src, Vector2 dst) {
float ratio = std::min(dst.x/src.x, dst.y/src.y); float ratio = std::min(dst.x/src.x, dst.y/src.y);
return ratio; return ratio;
@ -158,8 +206,10 @@ int main(int argc, char *argv[]) {
TestC(); TestC();
TestCPPFunc(); TestCPPFunc();
curl_global_init(CURL_GLOBAL_ALL);
bool run = true; bool run = true;
bool showIMgui = false;
bool showDemoWindow = false; bool showDemoWindow = false;
@ -216,76 +266,98 @@ int main(int argc, char *argv[]) {
DrawTextureEx(current_player.tex.tex, (Vector2) {0,0}, 0, ScaleToFit(imagesize, winwidth), WHITE); DrawTextureEx(current_player.tex.tex, (Vector2) {0,0}, 0, ScaleToFit(imagesize, winwidth), WHITE);
// start ImGui content
rlImGuiBegin();
// if you want windows to dock to the viewport, call this. if ( IsWindowFocused() ) {
#ifdef IMGUI_HAS_DOCK const float buttonsize = 0.1;
ImGui::DockSpaceOverViewport(); Vector2 screen = (Vector2) {(float) GetScreenWidth(), (float) GetScreenHeight()};
#endif Vector2 centerline;
centerline.x = screen.x / 2;
centerline.y = screen.y * 0.8;
// show a simple menu bar Color transblack = BLACK;
if (ImGui::BeginMainMenuBar()) { transblack.a = (200);
if (ImGui::BeginMenu("File")) { DrawCircleV(centerline, 0.05*GetScreenWidth(), transblack);
#ifdef IMGUI_HAS_DOCK
if (ImGui::MenuItem("Enable Docking")) {
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
}
if (ImGui::MenuItem("Disable Docking")) {
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_DockingEnable;
}
#endif
if (ImGui::MenuItem("Quit"))
run = false;
ImGui::EndMenu(); if (current_player.playstate == "Playing") {
DrawPause(centerline, 0.1*GetScreenWidth(), WHITE);
} else {
DrawPlay(centerline, 0.1*GetScreenWidth(), WHITE);
} }
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointCircle(GetMousePosition(), centerline, 0.05*GetScreenWidth()) ) {
if (ImGui::BeginMenu("Players")) {
for (auto item : serviceList) {
if (ImGui::MenuItem(item.c_str())) {
current_player = MprisPlayer(item);
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Window")) {
if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow))
showDemoWindow = !showDemoWindow;
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
// show some windows
if (ImGui::Begin("Player Control")) {
ImGui::Text("%s", current_player.GetIdentity().c_str());
if (ImGui::Button("Prev")) {
current_player.Prev();
}
if (ImGui::Button("Play/Pause")) {
current_player.PausePlay(); current_player.PausePlay();
current_player.playstate = current_player.playstate == "Playing" ? "Paused" : "Playing";
} }
if (ImGui::Button("Next")) {
current_player.Next();
}
if (ImGui::Button("Refresh")) {
current_player.Refresh();
current_player.UpdateTexture();
}
//rlImGuiImage(&current_player.tex.tex);
rlImGuiImageSize(&current_player.tex.tex,300,300);
} }
ImGui::End();
if (showDemoWindow)
ImGui::ShowDemoWindow(&showDemoWindow);
// end ImGui Content if (IsKeyPressed(KEY_SLASH)) {
rlImGuiEnd(); showIMgui = !showIMgui;
}
// start ImGui content
if (showIMgui) {
rlImGuiBegin();
// if you want windows to dock to the viewport, call this.
// show a simple menu bar
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Quit"))
run = false;
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Players")) {
for (auto item : serviceList) {
if (ImGui::MenuItem(item.c_str())) {
current_player = MprisPlayer(item);
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Window")) {
if (ImGui::MenuItem("Demo Window", nullptr, showDemoWindow))
showDemoWindow = !showDemoWindow;
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
// show some windows
if (ImGui::Begin("Player Control")) {
ImGui::Text("%s", current_player.GetIdentity().c_str());
if (ImGui::Button("Prev")) {
current_player.Prev();
}
if (ImGui::Button("Play/Pause")) {
current_player.PausePlay();
}
if (ImGui::Button("Next")) {
current_player.Next();
}
if (ImGui::Button("Refresh")) {
current_player.Refresh();
current_player.UpdateTexture();
}
//rlImGuiImage(&current_player.tex.tex);
rlImGuiImageSize(&current_player.tex.tex,300,300);
}
ImGui::End();
if (showDemoWindow)
ImGui::ShowDemoWindow(&showDemoWindow);
// end ImGui Content
rlImGuiEnd();
}
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -296,6 +368,6 @@ int main(int argc, char *argv[]) {
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
curl_global_cleanup();
return 0; return 0;
} }

View file

@ -5,9 +5,11 @@
#define IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui.h" #include "imgui.h"
#include <curl/curl.h>
#include <fstream>
#include <iostream> #include <iostream>
#include <ostream>
#include <magic.h> #include <magic.h>
#include <ostream>
#include <unordered_map> #include <unordered_map>
MprisPlayer::MprisPlayer(std::string servicename) { MprisPlayer::MprisPlayer(std::string servicename) {
@ -53,6 +55,7 @@ void MprisPlayer::Refresh() {
identity = PlayerProxy->getProperty("Identity") identity = PlayerProxy->getProperty("Identity")
.onInterface("org.mpris.MediaPlayer2") .onInterface("org.mpris.MediaPlayer2")
.get<std::string>(); .get<std::string>();
playstate = PlayerProxy->getProperty("PlaybackStatus").onInterface("org.mpris.MediaPlayer2.Player").get<std::string>();
current_metadata = PlayerProxy->getProperty("Metadata") current_metadata = PlayerProxy->getProperty("Metadata")
.onInterface("org.mpris.MediaPlayer2.Player") .onInterface("org.mpris.MediaPlayer2.Player")
.get<std::unordered_map<std::string, sdbus::Variant>>(); .get<std::unordered_map<std::string, sdbus::Variant>>();
@ -64,12 +67,60 @@ void MprisPlayer::Refresh() {
return; return;
} }
static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb,
void* userp) {
size_t realsize = size * nmemb;
auto& mem = *static_cast<std::string*>(userp);
mem.append(static_cast<char*>(contents), realsize);
return realsize;
}
void MprisPlayer::UpdateTexture() { void MprisPlayer::UpdateTexture() {
std::string filename = image_path_cache; std::string filename = image_path_cache;
std::cout << filename << std::endl;
if (filename.length() > 0) { if (filename.length() > 0) {
if (filename.c_str()[0] == 'h') {
CURL* curl_handle;
CURLcode res;
std::string chunk;
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, filename.c_str());
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &chunk);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
// added options that may be required
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); // redirects
curl_easy_setopt(curl_handle, CURLOPT_HTTPPROXYTUNNEL, 1L); // corp. proxies etc.
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // we want it all
// curl_easy_setopt(curl_handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << '\n';
} else {
std::cout << chunk.size() << " bytes retrieved\n";
}
std::ofstream output("/tmp/mpris-miniplayer-out");
if (output.is_open()) {
output << chunk;
output.close();
}
filename = "file:///tmp/mpris-miniplayer-out";
curl_easy_cleanup(curl_handle);
}
if (filename.c_str()[0] == 'f') { if (filename.c_str()[0] == 'f') {
std::cout << "parsing as file" << std::endl; std::cout << "parsing as file" << std::endl;
std::cout << filename << std::endl;
std::string path = filename.substr(7); std::string path = filename.substr(7);
FILE * f = fopen(path.c_str(), "r"); FILE * f = fopen(path.c_str(), "r");
if (f == NULL) { if (f == NULL) {

View file

@ -37,6 +37,7 @@ class MprisPlayer {
void Next(); void Next();
void Prev(); void Prev();
std::string identity; std::string identity;
std::string playstate;
std::string GetIdentity(); std::string GetIdentity();
std::unordered_map<std::string, sdbus::Variant> current_metadata; std::unordered_map<std::string, sdbus::Variant> current_metadata;
std::unordered_map<std::string, sdbus::Variant> GetCurrentMetadata(); std::unordered_map<std::string, sdbus::Variant> GetCurrentMetadata();