mirror of
https://github.com/Goldenkrew3000/OSSP_OpenSource.git
synced 2025-12-19 00:04:44 +10:00
Improved player logic and discord RPC, and fixed some memory leaks
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include "external/discord-rpc/include/discord_rpc.h"
|
#include "external/discord-rpc/include/discord_rpc.h"
|
||||||
#include "libopensubsonic/logger.h"
|
#include "libopensubsonic/logger.h"
|
||||||
#include "configHandler.h"
|
#include "configHandler.h"
|
||||||
@@ -87,11 +88,14 @@ void discordrpc_update(discordrpc_data** discordrpc_struct) {
|
|||||||
asprintf(&detailsString, "Idle");
|
asprintf(&detailsString, "Idle");
|
||||||
presence.details = detailsString;
|
presence.details = detailsString;
|
||||||
} else if ((*discordrpc_struct)->state == DISCORDRPC_STATE_PLAYING) {
|
} else if ((*discordrpc_struct)->state == DISCORDRPC_STATE_PLAYING) {
|
||||||
|
time_t currentTime = time(NULL);
|
||||||
asprintf(&detailsString, "%s", (*discordrpc_struct)->songTitle);
|
asprintf(&detailsString, "%s", (*discordrpc_struct)->songTitle);
|
||||||
asprintf(&stateString, "by %s", (*discordrpc_struct)->songArtist);
|
asprintf(&stateString, "by %s", (*discordrpc_struct)->songArtist);
|
||||||
presence.details = detailsString;
|
presence.details = detailsString;
|
||||||
presence.state = stateString;
|
presence.state = stateString;
|
||||||
presence.largeImageKey = (*discordrpc_struct)->coverArtUrl;
|
presence.largeImageKey = (*discordrpc_struct)->coverArtUrl;
|
||||||
|
presence.startTimestamp = (long)currentTime;
|
||||||
|
presence.endTimestamp = (long)currentTime + (*discordrpc_struct)->songLength;
|
||||||
if (configObj->discordrpc_showSysDetails) {
|
if (configObj->discordrpc_showSysDetails) {
|
||||||
presence.largeImageText = discordrpc_osString;
|
presence.largeImageText = discordrpc_osString;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../libopensubsonic/logger.h"
|
#include "../libopensubsonic/logger.h"
|
||||||
#include "../libopensubsonic/endpoint_getSong.h"
|
#include "../libopensubsonic/endpoint_getSong.h"
|
||||||
#include "../libopensubsonic/httpclient.h"
|
#include "../libopensubsonic/httpclient.h"
|
||||||
|
#include "playQueue.hpp"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
extern configHandler_config_t* configObj;
|
extern configHandler_config_t* configObj;
|
||||||
@@ -103,6 +104,8 @@ void* OSSPlayer_GMainLoop(void*) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* OSSPlayer_ThrdInit(void*) {
|
void* OSSPlayer_ThrdInit(void*) {
|
||||||
|
bool haveIssuedDiscordRPCIdle = true;
|
||||||
|
|
||||||
// Player init function for pthread entry
|
// Player init function for pthread entry
|
||||||
logger_log_important(__func__, "Player thread running.");
|
logger_log_important(__func__, "Player thread running.");
|
||||||
OSSPlayer_GstInit();
|
OSSPlayer_GstInit();
|
||||||
@@ -114,24 +117,21 @@ void* OSSPlayer_ThrdInit(void*) {
|
|||||||
// Poll play queue for new items to play
|
// Poll play queue for new items to play
|
||||||
while (true) { // TODO use global bool instead
|
while (true) { // TODO use global bool instead
|
||||||
if (internal_OSSPQ_GetItemCount() != 0 && isPlaying == false) {
|
if (internal_OSSPQ_GetItemCount() != 0 && isPlaying == false) {
|
||||||
printf("IS VALID\n");
|
|
||||||
// Player is not playing and a song is in the song queue
|
// Player is not playing and a song is in the song queue
|
||||||
OSSPQ_SongStruct* pq = OSSPlayer_QueuePopFront();
|
|
||||||
if (pq == NULL) {
|
// Pull new song from the song queue
|
||||||
|
OSSPQ_SongStruct* songObject = OSSPlayer_QueuePopFront();
|
||||||
|
if (songObject == NULL) {
|
||||||
printf("FUCK\n");
|
printf("FUCK\n");
|
||||||
// TODO: this
|
// TODO: this
|
||||||
}
|
}
|
||||||
|
|
||||||
char* id = strdup(pq->id);
|
// NOTE: Using a few strdup()'s because the cleanup/deinit functions perform free's so to avoid UAF's/Double free's
|
||||||
//free(pq);
|
// Fetch song information from the /getSong endpoint
|
||||||
|
|
||||||
// NOTE: Using a few strdup()'s because the cleanup/deinit functions perform free's and to avoid UAFs/Double frees
|
|
||||||
|
|
||||||
// Fetch song information
|
|
||||||
opensubsonic_httpClient_URL_t* song_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
opensubsonic_httpClient_URL_t* song_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
||||||
opensubsonic_httpClient_URL_prepare(&song_url);
|
opensubsonic_httpClient_URL_prepare(&song_url);
|
||||||
song_url->endpoint = OPENSUBSONIC_ENDPOINT_GETSONG;
|
song_url->endpoint = OPENSUBSONIC_ENDPOINT_GETSONG;
|
||||||
song_url->id = strdup(id);
|
song_url->id = strdup(songObject->id);
|
||||||
opensubsonic_httpClient_formUrl(&song_url);
|
opensubsonic_httpClient_formUrl(&song_url);
|
||||||
opensubsonic_getSong_struct* songStruct;
|
opensubsonic_getSong_struct* songStruct;
|
||||||
opensubsonic_httpClient_fetchResponse(&song_url, (void**)&songStruct);
|
opensubsonic_httpClient_fetchResponse(&song_url, (void**)&songStruct);
|
||||||
@@ -140,21 +140,24 @@ void* OSSPlayer_ThrdInit(void*) {
|
|||||||
opensubsonic_httpClient_URL_t* coverart_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
opensubsonic_httpClient_URL_t* coverart_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
||||||
opensubsonic_httpClient_URL_prepare(&coverart_url);
|
opensubsonic_httpClient_URL_prepare(&coverart_url);
|
||||||
coverart_url->endpoint = OPENSUBSONIC_ENDPOINT_GETCOVERART;
|
coverart_url->endpoint = OPENSUBSONIC_ENDPOINT_GETCOVERART;
|
||||||
coverart_url->id = strdup(id);
|
coverart_url->id = strdup(songObject->id);
|
||||||
opensubsonic_httpClient_formUrl(&coverart_url);
|
opensubsonic_httpClient_formUrl(&coverart_url);
|
||||||
|
|
||||||
// Update Discord RPC
|
// Prepare Discord RPC
|
||||||
discordrpc_data* discordrpc = NULL;
|
discordrpc_data* discordrpc = NULL;
|
||||||
discordrpc_struct_init(&discordrpc);
|
discordrpc_struct_init(&discordrpc);
|
||||||
discordrpc->state = DISCORDRPC_STATE_PLAYING;
|
discordrpc->state = DISCORDRPC_STATE_PLAYING;
|
||||||
|
discordrpc->songLength = songStruct->duration;
|
||||||
discordrpc->songTitle = strdup(songStruct->title);
|
discordrpc->songTitle = strdup(songStruct->title);
|
||||||
discordrpc->songArtist = strdup(songStruct->artist);
|
discordrpc->songArtist = strdup(songStruct->artist);
|
||||||
discordrpc->coverArtUrl = strdup(coverart_url->formedUrl);
|
//discordrpc->coverArtUrl = strdup(coverart_url->formedUrl);
|
||||||
discordrpc_update(&discordrpc);
|
discordrpc_update(&discordrpc);
|
||||||
discordrpc_struct_deinit(&discordrpc);
|
discordrpc_struct_deinit(&discordrpc);
|
||||||
|
|
||||||
|
// Free the cover art URL
|
||||||
opensubsonic_httpClient_URL_cleanup(&coverart_url);
|
opensubsonic_httpClient_URL_cleanup(&coverart_url);
|
||||||
|
|
||||||
|
// Free the /getSong info
|
||||||
opensubsonic_getSong_struct_free(&songStruct);
|
opensubsonic_getSong_struct_free(&songStruct);
|
||||||
opensubsonic_httpClient_URL_cleanup(&song_url);
|
opensubsonic_httpClient_URL_cleanup(&song_url);
|
||||||
|
|
||||||
@@ -162,13 +165,38 @@ void* OSSPlayer_ThrdInit(void*) {
|
|||||||
opensubsonic_httpClient_URL_t* stream_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
opensubsonic_httpClient_URL_t* stream_url = malloc(sizeof(opensubsonic_httpClient_URL_t));
|
||||||
opensubsonic_httpClient_URL_prepare(&stream_url);
|
opensubsonic_httpClient_URL_prepare(&stream_url);
|
||||||
stream_url->endpoint = OPENSUBSONIC_ENDPOINT_STREAM;
|
stream_url->endpoint = OPENSUBSONIC_ENDPOINT_STREAM;
|
||||||
stream_url->id = id;
|
stream_url->id = strdup(songObject->id);
|
||||||
opensubsonic_httpClient_formUrl(&stream_url);
|
opensubsonic_httpClient_formUrl(&stream_url);
|
||||||
|
|
||||||
|
// Free song queue object
|
||||||
|
// TODO: Go through abstraction
|
||||||
|
internal_OSSPQ_FreeSongObject(songObject);
|
||||||
|
|
||||||
|
// Configure discord RPC idle boolean for when a song isn't playing
|
||||||
|
haveIssuedDiscordRPCIdle = false;
|
||||||
|
|
||||||
|
// Configure playbin3, free stream URL, send discord RPC, and start playing
|
||||||
g_object_set(playbin, "uri", stream_url->formedUrl, NULL);
|
g_object_set(playbin, "uri", stream_url->formedUrl, NULL);
|
||||||
|
opensubsonic_httpClient_URL_cleanup(&stream_url);
|
||||||
isPlaying = true;
|
isPlaying = true;
|
||||||
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
gst_element_set_state(pipeline, GST_STATE_PLAYING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (internal_OSSPQ_GetItemCount() == 0 && !isPlaying) {
|
||||||
|
// No song currently playing, and the queue is empty
|
||||||
|
|
||||||
|
// Only send idle Discord RPC if needed to avoid spamming
|
||||||
|
if (!haveIssuedDiscordRPCIdle) {
|
||||||
|
printf("Issuing idle Discord RPC\n");
|
||||||
|
haveIssuedDiscordRPCIdle = true;
|
||||||
|
|
||||||
|
discordrpc_data* discordrpc = NULL;
|
||||||
|
discordrpc_struct_init(&discordrpc);
|
||||||
|
discordrpc->state = DISCORDRPC_STATE_IDLE;
|
||||||
|
discordrpc_update(&discordrpc);
|
||||||
|
discordrpc_struct_deinit(&discordrpc);
|
||||||
|
}
|
||||||
|
}
|
||||||
usleep(200 * 1000);
|
usleep(200 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user