It sort of works now. Pause button works, and shows album art locally and via https. Amazing.
This commit is contained in:
		
							parent
							
								
									a68b76fed6
								
							
						
					
					
						commit
						1cfb148453
					
				
					 4 changed files with 189 additions and 65 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -25,7 +25,7 @@ LDFLAGS = -g | |||
| LDLIBS += -L lib/ | ||||
| #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 | ||||
| 
 | ||||
| EXTRA_DIRS = $(OBJ_DIR)/rlImGui | ||||
|  |  | |||
							
								
								
									
										196
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						
									
										196
									
								
								src/main.cpp
									
										
									
									
									
								
							|  | @ -36,6 +36,7 @@ | |||
| #include <iostream> | ||||
| #include <sdbus-c++/sdbus-c++.h> | ||||
| #include <string> | ||||
| #include <curl/curl.h> | ||||
| extern "C" { | ||||
| #include "testc.h" | ||||
| } | ||||
|  | @ -136,6 +137,53 @@ std::vector<std::string> GetMprisServices() { | |||
|     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 ratio = std::min(dst.x/src.x, dst.y/src.y); | ||||
|     return ratio; | ||||
|  | @ -158,8 +206,10 @@ int main(int argc, char *argv[]) { | |||
|     TestC(); | ||||
|     TestCPPFunc(); | ||||
| 
 | ||||
|     curl_global_init(CURL_GLOBAL_ALL); | ||||
| 
 | ||||
|     bool run = true; | ||||
|     bool showIMgui = 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); | ||||
| 
 | ||||
| 
 | ||||
|         // start ImGui content
 | ||||
|         rlImGuiBegin(); | ||||
| 
 | ||||
|         // if you want windows to dock to the viewport, call this.
 | ||||
| #ifdef IMGUI_HAS_DOCK | ||||
|         ImGui::DockSpaceOverViewport(); | ||||
| #endif | ||||
|         if ( IsWindowFocused()  ) { | ||||
|             const float buttonsize = 0.1; | ||||
|             Vector2 screen = (Vector2) {(float) GetScreenWidth(), (float) GetScreenHeight()}; | ||||
|             Vector2 centerline; | ||||
|             centerline.x = screen.x / 2; | ||||
|             centerline.y = screen.y * 0.8; | ||||
| 
 | ||||
|         // show a simple menu bar
 | ||||
|         if (ImGui::BeginMainMenuBar()) { | ||||
|             if (ImGui::BeginMenu("File")) { | ||||
| #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; | ||||
|             Color transblack = BLACK; | ||||
|             transblack.a = (200); | ||||
|             DrawCircleV(centerline, 0.05*GetScreenWidth(), transblack); | ||||
| 
 | ||||
|                 ImGui::EndMenu(); | ||||
|             if (current_player.playstate == "Playing") { | ||||
|                 DrawPause(centerline, 0.1*GetScreenWidth(), WHITE); | ||||
|             } else { | ||||
|                 DrawPlay(centerline, 0.1*GetScreenWidth(), WHITE); | ||||
|             } | ||||
| 
 | ||||
|             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")) { | ||||
|             if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointCircle(GetMousePosition(), centerline, 0.05*GetScreenWidth()) ) { | ||||
|                 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(¤t_player.tex.tex);
 | ||||
|             rlImGuiImageSize(¤t_player.tex.tex,300,300); | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|         ImGui::End(); | ||||
| 
 | ||||
|         if (showDemoWindow) | ||||
|             ImGui::ShowDemoWindow(&showDemoWindow); | ||||
| 
 | ||||
|         // end ImGui Content
 | ||||
|         rlImGuiEnd(); | ||||
|         if (IsKeyPressed(KEY_SLASH)) { | ||||
|             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(¤t_player.tex.tex);
 | ||||
|                 rlImGuiImageSize(¤t_player.tex.tex,300,300); | ||||
|             } | ||||
|             ImGui::End(); | ||||
| 
 | ||||
|             if (showDemoWindow) | ||||
|                 ImGui::ShowDemoWindow(&showDemoWindow); | ||||
| 
 | ||||
|             // end ImGui Content
 | ||||
|             rlImGuiEnd(); | ||||
|         } | ||||
| 
 | ||||
|         EndDrawing(); | ||||
|         //----------------------------------------------------------------------------------
 | ||||
|  | @ -296,6 +368,6 @@ int main(int argc, char *argv[]) { | |||
|     //--------------------------------------------------------------------------------------
 | ||||
|     CloseWindow(); // Close window and OpenGL context
 | ||||
|     //--------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     curl_global_cleanup(); | ||||
|     return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -5,9 +5,11 @@ | |||
| #define IMGUI_DEFINE_MATH_OPERATORS | ||||
| #include "imgui.h" | ||||
| 
 | ||||
| #include <curl/curl.h> | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| #include <ostream> | ||||
| #include <magic.h> | ||||
| #include <ostream> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| MprisPlayer::MprisPlayer(std::string servicename) { | ||||
|  | @ -53,6 +55,7 @@ void MprisPlayer::Refresh() { | |||
|         identity = PlayerProxy->getProperty("Identity") | ||||
|                        .onInterface("org.mpris.MediaPlayer2") | ||||
|                        .get<std::string>(); | ||||
|         playstate = PlayerProxy->getProperty("PlaybackStatus").onInterface("org.mpris.MediaPlayer2.Player").get<std::string>(); | ||||
|         current_metadata = PlayerProxy->getProperty("Metadata") | ||||
|                                .onInterface("org.mpris.MediaPlayer2.Player") | ||||
|                                .get<std::unordered_map<std::string, sdbus::Variant>>(); | ||||
|  | @ -64,12 +67,60 @@ void MprisPlayer::Refresh() { | |||
|     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() { | ||||
|     std::string filename = image_path_cache; | ||||
|     std::cout << filename << std::endl; | ||||
|     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') { | ||||
|             std::cout << "parsing as file" << std::endl; | ||||
|             std::cout << filename << std::endl; | ||||
|             std::string path = filename.substr(7); | ||||
|             FILE * f = fopen(path.c_str(), "r"); | ||||
|             if (f == NULL) { | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ class MprisPlayer { | |||
|     void Next(); | ||||
|     void Prev(); | ||||
|     std::string identity; | ||||
|     std::string playstate; | ||||
|     std::string GetIdentity(); | ||||
|     std::unordered_map<std::string, sdbus::Variant> current_metadata; | ||||
|     std::unordered_map<std::string, sdbus::Variant> GetCurrentMetadata(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue