mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-31 14:37:59 +00:00
libshairport: add metadata support, add some upstream patches
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
f171837b58
commit
efdcefdcf9
@ -0,0 +1,31 @@
|
|||||||
|
From ab175ba28508445f6aff57386a8ce04b58a86f60 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Memphiz <memphis@machzwo.de>
|
||||||
|
Date: Fri, 11 May 2012 19:56:37 +0200
|
||||||
|
Subject: [PATCH] [fix] - reapply fix for airtunes with AE which was lost
|
||||||
|
during merge
|
||||||
|
|
||||||
|
---
|
||||||
|
xbmc/network/AirTunesServer.cpp | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp
|
||||||
|
index 285a0a6..a60ad09 100644
|
||||||
|
--- a/xbmc/network/AirTunesServer.cpp
|
||||||
|
+++ b/xbmc/network/AirTunesServer.cpp
|
||||||
|
@@ -125,11 +125,11 @@ ao_device* CAirTunesServer::AudioOutputFunctions::ao_open_live(int driver_id, ao
|
||||||
|
if (ao_get_option(option, "name"))
|
||||||
|
item.GetMusicInfoTag()->SetTitle(ao_get_option(option, "name"));
|
||||||
|
|
||||||
|
- g_application.getApplicationMessenger().PlayFile(item);
|
||||||
|
-
|
||||||
|
ThreadMessage tMsg2 = { TMSG_GUI_ACTIVATE_WINDOW, WINDOW_VISUALISATION, 0 };
|
||||||
|
g_application.getApplicationMessenger().SendMessage(tMsg2, true);
|
||||||
|
|
||||||
|
+ g_application.getApplicationMessenger().PlayFile(item);
|
||||||
|
+
|
||||||
|
return (ao_device*) device;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From b7fb4615609c684a98dc1cc27906aaa0f117837f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Memphiz <memphis@machzwo.de>
|
||||||
|
Date: Wed, 9 May 2012 18:53:45 +0200
|
||||||
|
Subject: [PATCH] [airtunes] - add dmap metadata parsing
|
||||||
|
|
||||||
|
---
|
||||||
|
xbmc/network/AirTunesServer.cpp | 13 ++++++++++++-
|
||||||
|
xbmc/network/AirTunesServer.h | 2 ++
|
||||||
|
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/xbmc/network/AirTunesServer.cpp b/xbmc/network/AirTunesServer.cpp
|
||||||
|
index e14da90..2ad097e 100644
|
||||||
|
--- a/xbmc/network/AirTunesServer.cpp
|
||||||
|
+++ b/xbmc/network/AirTunesServer.cpp
|
||||||
|
@@ -47,7 +47,6 @@
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
-
|
||||||
|
using namespace XFILE;
|
||||||
|
|
||||||
|
#if defined(TARGET_WINDOWS)
|
||||||
|
@@ -390,6 +389,16 @@ int CAirTunesServer::AudioOutputFunctions::ao_close(ao_device *device)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void CAirTunesServer::AudioOutputFunctions::ao_set_metadata(const char *buffer, unsigned int size)
|
||||||
|
+{
|
||||||
|
+ CAirTunesServer::SetMetadataFromBuffer(buffer, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void CAirTunesServer::AudioOutputFunctions::ao_set_metadata_coverart(const char *buffer, unsigned int size)
|
||||||
|
+{
|
||||||
|
+ CAirTunesServer::SetCoverArtFromBuffer(buffer, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* -- Device Setup/Playback/Teardown -- */
|
||||||
|
int CAirTunesServer::AudioOutputFunctions::ao_append_option(ao_option **options, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
@@ -658,6 +667,8 @@ bool CAirTunesServer::Initialize(const CStdString &password)
|
||||||
|
ao.ao_append_option = AudioOutputFunctions::ao_append_option;
|
||||||
|
ao.ao_free_options = AudioOutputFunctions::ao_free_options;
|
||||||
|
ao.ao_get_option = AudioOutputFunctions::ao_get_option;
|
||||||
|
+ ao.ao_set_metadata = AudioOutputFunctions::ao_set_metadata;
|
||||||
|
+ ao.ao_set_metadata_coverart = AudioOutputFunctions::ao_set_metadata_coverart;
|
||||||
|
struct printfPtr funcPtr;
|
||||||
|
funcPtr.extprintf = shairport_log;
|
||||||
|
|
||||||
|
diff --git a/xbmc/network/AirTunesServer.h b/xbmc/network/AirTunesServer.h
|
||||||
|
index 4a30e0a..0a4ce5a 100644
|
||||||
|
--- a/xbmc/network/AirTunesServer.h
|
||||||
|
+++ b/xbmc/network/AirTunesServer.h
|
||||||
|
@@ -96,6 +96,8 @@ class CAirTunesServer : public CThread
|
||||||
|
static int ao_append_option(ao_option **options, const char *key, const char *value);
|
||||||
|
static void ao_free_options(ao_option *options);
|
||||||
|
static char* ao_get_option(ao_option *options, const char* key);
|
||||||
|
+ static void ao_set_metadata(const char *buffer, unsigned int size);
|
||||||
|
+ static void ao_set_metadata_coverart(const char *buffer, unsigned int size);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
--
|
||||||
|
1.7.10
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
--- a/src/socketlib.c 2012-01-04 20:41:05.000000000 +0100
|
||||||
|
+++ b/src/socketlib.c 2012-01-04 20:35:53.000000000 +0100
|
||||||
|
@@ -48,7 +48,7 @@
|
||||||
|
if((tSock==-1) && (pAddrInfo->ai_family == AF_INET6) && (errno == EAFNOSUPPORT))
|
||||||
|
{
|
||||||
|
//Fallback to ipv4
|
||||||
|
- perror("Failed to create ipv6 socket. Trying ipv4");
|
||||||
|
+ xprintf("Failed to create ipv6 socket. Trying ipv4");
|
||||||
|
pAddrInfo->ai_family = AF_INET;
|
||||||
|
tSock = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, 0);
|
||||||
|
}
|
||||||
|
@@ -158,8 +158,8 @@
|
||||||
|
sprintf(tService, "%d", pPort); // copies port to string
|
||||||
|
int tFamily = AF_INET;
|
||||||
|
#ifdef AF_INET6
|
||||||
|
- //printf("Listening on IPv6 Socket\n");
|
||||||
|
- //tFamily = AF_INET6;
|
||||||
|
+ xprintf("Listening on IPv6 Socket\n");
|
||||||
|
+ tFamily = AF_INET6;
|
||||||
|
#else
|
||||||
|
//printf("Listening on IPv4 Socket");
|
||||||
|
#endif
|
@ -0,0 +1,154 @@
|
|||||||
|
diff -ruP src/ao.h libshairport.new/src/ao.h
|
||||||
|
--- a/src/ao.h 2012-05-07 22:26:53.000000000 +0200
|
||||||
|
+++ b/src/ao.h 2012-05-08 18:46:42.000000000 +0200
|
||||||
|
@@ -152,5 +152,7 @@
|
||||||
|
/* -- Device Setup/Playback/Teardown -- */
|
||||||
|
int (*ao_append_option)(ao_option **, const char *, const char *);
|
||||||
|
void (*ao_free_options)(ao_option *);
|
||||||
|
- char* (*ao_get_option)(ao_option *, const char* );
|
||||||
|
+ char* (*ao_get_option)(ao_option *, const char* );
|
||||||
|
+ void (*ao_set_metadata)(const char *buffer, unsigned int size);
|
||||||
|
+ void (*ao_set_metadata_coverart)(const char *buffer, unsigned int size);
|
||||||
|
};
|
||||||
|
diff -ruP src/hairtunes.c src/hairtunes.c
|
||||||
|
--- a/src/hairtunes.c 2012-05-07 22:26:53.000000000 +0200
|
||||||
|
+++ b/src/hairtunes.c 2012-05-08 18:45:51.000000000 +0200
|
||||||
|
@@ -267,6 +267,16 @@
|
||||||
|
fix_volume = 65536.0 * volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void hairtunes_set_metadata(const char *buffer, unsigned int size)
|
||||||
|
+{
|
||||||
|
+ g_ao.ao_set_metadata(buffer, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size)
|
||||||
|
+{
|
||||||
|
+ g_ao.ao_set_metadata_coverart(buffer, size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void hairtunes_flush(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&ab_mutex);
|
||||||
|
diff -ruP src/hairtunes.h src/hairtunes.h
|
||||||
|
--- a/src/hairtunes.h 2011-08-21 00:06:21.000000000 +0200
|
||||||
|
+++ b/src/hairtunes.h 2012-05-08 18:46:00.000000000 +0200
|
||||||
|
@@ -4,6 +4,8 @@
|
||||||
|
int hairtunes_init(char *pAeskey, char *pAesiv, char *pFmtpstr, int pCtrlPort, int pTimingPort,
|
||||||
|
int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId);
|
||||||
|
void hairtunes_setvolume(float vol);
|
||||||
|
+void hairtunes_set_metadata(const char *buffer, unsigned int size);
|
||||||
|
+void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size);
|
||||||
|
void hairtunes_flush(void);
|
||||||
|
void hairtunes_cleanup(void);
|
||||||
|
|
||||||
|
diff -ruP src/shairport.c src/shairport.c
|
||||||
|
--- a/src/shairport.c 2012-05-07 22:26:53.000000000 +0200
|
||||||
|
+++ b/src/shairport.c 2012-05-08 18:45:30.000000000 +0200
|
||||||
|
@@ -513,7 +513,8 @@
|
||||||
|
while(1 == tMoreDataNeeded)
|
||||||
|
{
|
||||||
|
tError = readDataFromClient(pSock, &(tConn.recv));
|
||||||
|
- if(!tError && strlen(tConn.recv.data) > 0)
|
||||||
|
+ //if(!tError && strlen(tConn.recv.data) > 0)
|
||||||
|
+ if(!tError && tConn.recv.current > 0)
|
||||||
|
{
|
||||||
|
xprintf("Finished Reading some data from client\n");
|
||||||
|
// parse client request
|
||||||
|
@@ -632,7 +633,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
tSize = (int) (tShortest - tFound);
|
||||||
|
- xprintf("Found %.*s length: %d\n", tSize, tFound, tSize);
|
||||||
|
+ xprintf("Found %s length: %d\n",tFound, tSize);
|
||||||
|
if(pReturnSize != NULL)
|
||||||
|
{
|
||||||
|
*pReturnSize = tSize;
|
||||||
|
@@ -744,7 +745,7 @@
|
||||||
|
if(tContent != NULL)
|
||||||
|
{
|
||||||
|
int tContentSize = atoi(tContent);
|
||||||
|
- if(pConn->recv.marker == 0 || strlen(pConn->recv.data+pConn->recv.marker) != tContentSize)
|
||||||
|
+ if(pConn->recv.marker == 0 || pConn->recv.current-pConn->recv.marker != tContentSize)
|
||||||
|
{
|
||||||
|
if(isLogEnabledFor(HEADER_LOG_LEVEL))
|
||||||
|
{
|
||||||
|
@@ -752,7 +753,7 @@
|
||||||
|
if(pConn->recv.marker != 0)
|
||||||
|
{
|
||||||
|
xprintf("ContentPtr has %d, but needs %d\n",
|
||||||
|
- strlen(pConn->recv.data+pConn->recv.marker), tContentSize);
|
||||||
|
+ (pConn->recv.current-pConn->recv.marker), tContentSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if value in tContent > 2nd read from client.
|
||||||
|
@@ -989,15 +990,67 @@
|
||||||
|
{
|
||||||
|
propogateCSeq(pConn);
|
||||||
|
int tSize = 0;
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ char *contentType = getFromHeader(pConn->recv.data, "Content-Type", &tSize);
|
||||||
|
+ char *tContent = getFromHeader(pConn->recv.data, "Content-Length", NULL);
|
||||||
|
+ int iContentSize = 0;
|
||||||
|
+ int isJpg = 0;
|
||||||
|
+
|
||||||
|
+ if(tContent != NULL)
|
||||||
|
+ {
|
||||||
|
+ iContentSize = atoi(tContent);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if( tSize > 1 &&
|
||||||
|
+ (strncmp(contentType, "application/x-dmap-tagged", tSize) == 0) ||
|
||||||
|
+ (strncmp(contentType, "image/jpeg", tSize) == 0) )
|
||||||
|
+ {
|
||||||
|
+ if( (pConn->recv.current - pConn->recv.marker) == iContentSize && pConn->recv.marker != 0)
|
||||||
|
+ {
|
||||||
|
+ if(strncmp(contentType, "image/jpeg", tSize) == 0)
|
||||||
|
+ {
|
||||||
|
+ isJpg = 1;
|
||||||
|
+ }
|
||||||
|
+ buffer = (char *)malloc(iContentSize * sizeof(char));
|
||||||
|
+ memcpy(buffer, pConn->recv.data + pConn->recv.marker, iContentSize);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ iContentSize = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ iContentSize = 0;
|
||||||
|
+ }
|
||||||
|
char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize);
|
||||||
|
- xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol);
|
||||||
|
+ if( tVol)
|
||||||
|
+ {
|
||||||
|
+ xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol);
|
||||||
|
+ }
|
||||||
|
// TBD VOLUME
|
||||||
|
#ifndef XBMC
|
||||||
|
write(pConn->hairtunes->in[1], "vol: ", 5);
|
||||||
|
write(pConn->hairtunes->in[1], tVol, tSize);
|
||||||
|
write(pConn->hairtunes->in[1], "\n", 1);
|
||||||
|
#else
|
||||||
|
- hairtunes_setvolume(atof(tVol));
|
||||||
|
+ if(tVol)
|
||||||
|
+ {
|
||||||
|
+ hairtunes_setvolume(atof(tVol));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if(iContentSize)
|
||||||
|
+ {
|
||||||
|
+ if(isJpg)
|
||||||
|
+ {
|
||||||
|
+ hairtunes_set_metadata_coverart(buffer, iContentSize);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ hairtunes_set_metadata(buffer, iContentSize);
|
||||||
|
+ }
|
||||||
|
+ free(buffer);
|
||||||
|
+ }
|
||||||
|
#endif
|
||||||
|
xprintf("Finished writing data write data to hairtunes\n");
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user