MediaRendererDevice::MediaRendererDevice(const std::string& udn, const std::string& descriptionXml, int32_t advertiseIntervalInSeconds, const std::string& audioOutput, const std::string& audioDevice, upnp::WebServer& webServer) : m_Playback(PlaybackFactory::create("Custom", "Doozy", audioOutput, audioDevice, m_Queue)) , m_RootDevice(udn, descriptionXml, advertiseIntervalInSeconds) , m_ConnectionManager(m_RootDevice, *this) , m_RenderingControl(m_RootDevice, *this) , m_AVTransport(m_RootDevice, *this) , m_WebServer(webServer) { m_Playback->PlaybackStateChanged.connect([this] (PlaybackState state) { setTransportVariable(0, AVTransport::Variable::TransportState, AVTransport::toString(PlaybackStateToTransportState(state))); }, this); m_Playback->AvailableActionsChanged.connect([this] (const std::set<PlaybackAction>& actions) { setTransportVariable(0, AVTransport::Variable::CurrentTransportActions, toString(actions)); }, this); m_Playback->ProgressChanged.connect([this] (double progress) { setTransportVariable(0, AVTransport::Variable::RelativeTimePosition, durationToString(progress)); }, this); m_Playback->NewTrackStarted.connect([this] (const std::shared_ptr<ITrack>& track) { auto item = std::dynamic_pointer_cast<PlayQueueItem>(track); assert(item); addAlbumArtToWebServer(item); setTransportVariable(0, AVTransport::Variable::CurrentTrackURI, item->getUri()); setTransportVariable(0, AVTransport::Variable::CurrentTrackMetaData, item->getMetadataString()); setTransportVariable(0, AVTransport::Variable::AVTransportURI, item->getAVTransportUri()); setTransportVariable(0, AVTransport::Variable::NextAVTransportURI, m_Queue.getNextUri()); setTransportVariable(0, AVTransport::Variable::CurrentTrackDuration, durationToString(m_Playback->getDuration())); setTransportVariable(0, AVTransport::Variable::NumberOfTracks, std::to_string(m_Queue.getNumberOfTracks())); }, this); }
int setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy) { shout_metadata_t *shout_mdata = NULL; char *songInfo; const char *artist, *title; int ret = SHOUTERR_SUCCESS; if (shout == NULL) { printf("%s: setMetadata(): Internal error: NULL shout_t\n", __progname); abort(); } if (mFlag) return (SHOUTERR_SUCCESS); if (mdata == NULL) return 1; if ((shout_mdata = shout_metadata_new()) == NULL) { printf("%s: shout_metadata_new(): %s\n", __progname, strerror(ENOMEM)); exit(1); } artist = metadata_get_artist(mdata); title = metadata_get_title(mdata); /* * We can do this, because we know how libshout works. This adds * "charset=UTF-8" to the HTTP metadata update request and has the * desired effect of letting newer-than-2.3.1 versions of Icecast know * which encoding we're using. */ if (shout_metadata_add(shout_mdata, "charset", "UTF-8") != SHOUTERR_SUCCESS) { /* Assume SHOUTERR_MALLOC */ printf("%s: shout_metadata_add(): %s\n", __progname, strerror(ENOMEM)); exit(1); } if ((songInfo = getMetadataString(pezConfig->metadataFormat, mdata)) == NULL) { if (artist[0] == '\0' && title[0] == '\0') songInfo = xstrdup(metadata_get_string(mdata)); else songInfo = metadata_assemble_string(mdata); if (artist[0] != '\0' && title[0] != '\0') { if (shout_metadata_add(shout_mdata, "artist", artist) != SHOUTERR_SUCCESS) { printf("%s: shout_metadata_add(): %s\n", __progname, strerror(ENOMEM)); exit(1); } if (shout_metadata_add(shout_mdata, "title", title) != SHOUTERR_SUCCESS) { printf("%s: shout_metadata_add(): %s\n", __progname, strerror(ENOMEM)); exit(1); } } else { if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) { printf("%s: shout_metadata_add(): %s\n", __progname, strerror(ENOMEM)); exit(1); } } } else if (shout_metadata_add(shout_mdata, "song", songInfo) != SHOUTERR_SUCCESS) { printf("%s: shout_metadata_add(): %s\n", __progname, strerror(ENOMEM)); exit(1); } if ((ret = shout_set_metadata(shout, shout_mdata)) != SHOUTERR_SUCCESS) printf("%s: shout_set_metadata(): %s\n", __progname, shout_get_error(shout)); shout_metadata_free(shout_mdata); if (ret == SHOUTERR_SUCCESS) { if (mdata_copy != NULL && *mdata_copy == NULL) *mdata_copy = xstrdup(songInfo); } xfree(songInfo); return (ret); }
char * buildCommandString(const char *extension, const char *fileName, metadata_t *mdata) { char *commandString = NULL; size_t commandStringLen = 0; char *encoder = NULL; char *decoder = NULL; char *newDecoder = NULL; char *newEncoder = NULL; char *localTitle = UTF8toCHAR(metadata_get_title(mdata), ICONV_REPLACE); char *localArtist = UTF8toCHAR(metadata_get_artist(mdata), ICONV_REPLACE); char *localMetaString = UTF8toCHAR(metadata_get_string(mdata), ICONV_REPLACE); decoder = xstrdup(getFormatDecoder(extension)); if (strlen(decoder) == 0) { printf("%s: Unknown extension '%s', cannot decode '%s'\n", __progname, extension, fileName); xfree(localTitle); xfree(localArtist); xfree(localMetaString); xfree(decoder); return (NULL); } newDecoder = replaceString(decoder, TRACK_PLACEHOLDER, fileName); if (strstr(decoder, ARTIST_PLACEHOLDER) != NULL) { char *tmpStr = replaceString(newDecoder, ARTIST_PLACEHOLDER, localArtist); xfree(newDecoder); newDecoder = tmpStr; } if (strstr(decoder, TITLE_PLACEHOLDER) != NULL) { char *tmpStr = replaceString(newDecoder, TITLE_PLACEHOLDER, localTitle); xfree(newDecoder); newDecoder = tmpStr; } /* * if meta * if (prog && format) * metatoformat * else * if (!prog && title) * emptymeta * else * replacemeta */ if (strstr(decoder, METADATA_PLACEHOLDER) != NULL) { if (metadataFromProgram && pezConfig->metadataFormat != NULL) { char *mdataString = getMetadataString(pezConfig->metadataFormat, mdata); char *tmpStr = replaceString(newDecoder, METADATA_PLACEHOLDER, mdataString); xfree(newDecoder); xfree(mdataString); newDecoder = tmpStr; } else { if (!metadataFromProgram && strstr(decoder, TITLE_PLACEHOLDER) != NULL) { char *tmpStr = replaceString(newDecoder, METADATA_PLACEHOLDER, ""); xfree(newDecoder); newDecoder = tmpStr; } else { char *tmpStr = replaceString(newDecoder, METADATA_PLACEHOLDER, localMetaString); xfree(newDecoder); newDecoder = tmpStr; } } } encoder = xstrdup(getFormatEncoder(pezConfig->format)); if (strlen(encoder) == 0) { if (vFlag) printf("%s: Passing through%s%s data from the decoder\n", __progname, (strcmp(pezConfig->format, THEORA_FORMAT) != 0) ? " (unsupported) " : " ", pezConfig->format); commandStringLen = strlen(newDecoder) + 1; commandString = xcalloc(commandStringLen, sizeof(char)); strlcpy(commandString, newDecoder, commandStringLen); xfree(localTitle); xfree(localArtist); xfree(localMetaString); xfree(decoder); xfree(encoder); xfree(newDecoder); return (commandString); } newEncoder = replaceString(encoder, ARTIST_PLACEHOLDER, localArtist); if (strstr(encoder, TITLE_PLACEHOLDER) != NULL) { char *tmpStr = replaceString(newEncoder, TITLE_PLACEHOLDER, localTitle); xfree(newEncoder); newEncoder = tmpStr; } if (strstr(encoder, METADATA_PLACEHOLDER) != NULL) { if (metadataFromProgram && pezConfig->metadataFormat != NULL) { char *mdataString = getMetadataString(pezConfig->metadataFormat, mdata); char *tmpStr = replaceString(newEncoder, METADATA_PLACEHOLDER, mdataString); xfree(newEncoder); xfree(mdataString); newEncoder = tmpStr; } else { if (!metadataFromProgram && strstr(encoder, TITLE_PLACEHOLDER) != NULL) { char *tmpStr = replaceString(newEncoder, METADATA_PLACEHOLDER, ""); xfree(newEncoder); newEncoder = tmpStr; } else { char *tmpStr = replaceString(newEncoder, METADATA_PLACEHOLDER, localMetaString); xfree(newEncoder); newEncoder = tmpStr; } } } commandStringLen = strlen(newDecoder) + strlen(" | ") + strlen(newEncoder) + 1; commandString = xcalloc(commandStringLen, sizeof(char)); snprintf(commandString, commandStringLen, "%s | %s", newDecoder, newEncoder); xfree(localTitle); xfree(localArtist); xfree(localMetaString); xfree(decoder); xfree(encoder); xfree(newDecoder); xfree(newEncoder); return (commandString); }