diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h
index 4ceb037e09fe7ed2e64f046e53d9e981efe72b5f..897f0d06c5c2771032c0a0ea5b1420355c4bf696 100644
--- a/indra/llaudio/llstreamingaudio.h
+++ b/indra/llaudio/llstreamingaudio.h
@@ -30,6 +30,10 @@
 
 #include "stdtypes.h" // from llcommon
 
+#include "llsd.h"
+
+#include "boost/signals2.hpp"
+
 class LLSD;
 
 // Entirely abstract.  Based exactly on the historic API.
@@ -52,10 +56,18 @@ class LLStreamingAudioInterface
 	virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) = 0;
 
 	virtual bool supportsMetaData() = 0;
-	virtual const LLSD *getMetaData() = 0;
-	virtual bool hasNewMetaData() = 0;
+	using metadata_signal_t = boost::signals2::signal<void(const LLSD& metadata)>;
+	virtual boost::signals2::connection setMetadataUpdatedCallback(const metadata_signal_t::slot_type& cb)
+	{
+		return mMetadataUpdateSignal.connect(cb);
+	}
+	virtual LLSD getMetadata() const { return LLSD(); }
+
 	virtual bool supportsWaveData() = 0;
 	virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0;
+
+protected:
+	metadata_signal_t mMetadataUpdateSignal;
 };
 
 #endif // LL_STREAMINGAUDIO_H
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 817ddc509ba1a2c0a35705990d7ce7466cc2fcd2..faf575af23a8f35b65e4c8a86a4318dcf27c1888 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -117,8 +117,7 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
     mFMODInternetStreamChannelp(nullptr),
     mGain(1.0f),
     mWasAlreadyPlaying(false),
-    mMetaData(nullptr),
-    mNewMetadata(true)
+    mMetadata(LLSD::emptyMap())
 {
     // Number of milliseconds of audio to buffer for the audio card.
     // Must be larger than the usual Second Life frame stutter time.
@@ -168,7 +167,6 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
             LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
             mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, url);
             mURL = url;
-            mMetaData = new LLSD;
         }
         else
         {
@@ -237,7 +235,8 @@ void LLStreamingAudio_FMODSTUDIO::update()
         LL_INFOS() << "Starting internet stream: " << mPendingURL << LL_ENDL;
         mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, mPendingURL);
         mURL = mPendingURL;
-        mMetaData = new LLSD;
+        mMetadata = LLSD::emptyMap();
+        mMetadataUpdateSignal(mMetadata);
         mPendingURL.clear();
     }
 
@@ -294,19 +293,15 @@ void LLStreamingAudio_FMODSTUDIO::update()
 
     if (mFMODInternetStreamChannelp)
     {
-        if(!mMetaData)
-            mMetaData = new LLSD;
-
         FMOD::Sound *sound = nullptr;
 
         if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound)
         {
             FMOD_TAG tag;
             S32 tagcount, dirtytagcount;
-            if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount)
+            if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount > 0)
             {
-                mMetaData->clear();
-                mNewMetadata = true;
+                mMetadata = LLSD::emptyMap();
 
                 for(S32 i = 0; i < tagcount; ++i)
                 {
@@ -352,11 +347,11 @@ void LLStreamingAudio_FMODSTUDIO::update()
                     switch (tag.datatype)
                     {
                         case(FMOD_TAGDATATYPE_INT):
-                            (*mMetaData)[name]=*(LLSD::Integer*)(tag.data);
+                           mMetadata[name]=*(LLSD::Integer*)(tag.data);
                             LL_INFOS() << tag.name << ": " << *(int*)(tag.data) << LL_ENDL;
                             break;
                         case(FMOD_TAGDATATYPE_FLOAT):
-                            (*mMetaData)[name]=*(LLSD::Real*)(tag.data);
+                            mMetadata[name]=*(LLSD::Real*)(tag.data);
                             LL_INFOS() << tag.name << ": " << *(float*)(tag.data) << LL_ENDL;
                             break;
                         case(FMOD_TAGDATATYPE_STRING):
@@ -364,7 +359,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
                             std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen));
                             if (out.length() && out[out.size() - 1] == 0)
                                 out.erase(out.size() - 1);
-                            (*mMetaData)[name]=out;
+                            mMetadata[name]=out;
                             LL_INFOS() << tag.name << "(RAW): " << out << LL_ENDL;
                             break;
                         }
@@ -376,7 +371,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
                             std::string out((char*)tag.data + offs, tag.datalen - offs);
                             if (out.length() && out[out.size() - 1] == 0)
                                 out.erase(out.size() - 1);
-                            (*mMetaData)[name] = out;
+                            mMetadata[name] = out;
                             LL_INFOS() << tag.name << "(UTF8): " << out << LL_ENDL;
                             break;
                         }
@@ -385,7 +380,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
                             std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16);
                             if (out.length() && out[out.size() - 1] == 0)
                                 out.erase(out.size() - 1);
-                            (*mMetaData)[name] = out;
+                            mMetadata[name] = out;
                             LL_INFOS() << tag.name << "(UTF16): " << out << LL_ENDL;
                             break;
                         }
@@ -394,7 +389,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
                             std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16BE);
                             if (out.length() && out[out.size() - 1] == 0)
                                 out.erase(out.size() - 1);
-                            (*mMetaData)[name] = out;
+                            mMetadata[name] = out;
                             LL_INFOS() << tag.name << "(UTF16BE): " << out << LL_ENDL;
                             break;
                         }
@@ -402,6 +397,8 @@ void LLStreamingAudio_FMODSTUDIO::update()
                             break;
                     }
                 }
+
+                mMetadataUpdateSignal(mMetadata);
             }
 
             if (starving)
@@ -428,11 +425,8 @@ void LLStreamingAudio_FMODSTUDIO::stop()
     mPendingURL.clear();
     mWasAlreadyPlaying = false;
 
-    if(mMetaData)
-    {
-        delete mMetaData;
-        mMetaData = nullptr;
-    }
+    mMetadata = LLSD::emptyMap();
+    mMetadataUpdateSignal(mMetadata);
     
     if (mFMODInternetStreamChannelp)
     {
@@ -525,19 +519,6 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
     }
 }
 
-bool LLStreamingAudio_FMODSTUDIO::hasNewMetaData()
-{
-    if (mCurrentInternetStreamp && mNewMetadata)
-    {
-        mNewMetadata = false;
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
 /* virtual */
 bool LLStreamingAudio_FMODSTUDIO::getWaveData(float* arr, S32 count, S32 stride/*=1*/)
 {
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h
index ccfc16961f6de1c243b624da334819b65fea6fd6..0bc2dc5089a66ff96520f18959fdaafdc60e3e53 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.h
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.h
@@ -31,6 +31,9 @@
 
 #include "llstreamingaudio.h"
 #include "lltimer.h"
+#include "llsd.h"
+
+#include "boost/signals2.hpp"
 
 //Stubs
 class LLAudioStreamManagerFMODSTUDIO;
@@ -62,8 +65,7 @@ class LLStreamingAudio_FMODSTUDIO final : public LLStreamingAudioInterface
 	/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) override;
 
 	/*virtual*/ bool supportsMetaData() override {return true;}
-	/*virtual*/ const LLSD *getMetaData() override { return mMetaData; }	//return NULL if not playing.
-	/*virtual*/ bool hasNewMetaData() override;
+	/*virtual*/ LLSD getMetadata() const override { return mMetadata; }	//return NULL if not playing.
 	/*virtual*/ bool supportsWaveData() override {return true;}
 	/*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1) override;
 private:
@@ -84,8 +86,7 @@ class LLStreamingAudio_FMODSTUDIO final : public LLStreamingAudioInterface
 
     bool mWasAlreadyPlaying;
 
-	LLSD *mMetaData;
-	bool mNewMetadata;
+	LLSD mMetadata;
 };
 
 
diff --git a/indra/newview/alpanelmusicticker.cpp b/indra/newview/alpanelmusicticker.cpp
index 9dd56825cddac464fba209f1d6f6433254627b31..24281af50cd837474214c1edbb0803f8c09dc642 100644
--- a/indra/newview/alpanelmusicticker.cpp
+++ b/indra/newview/alpanelmusicticker.cpp
@@ -46,6 +46,14 @@ ALPanelMusicTicker::ALPanelMusicTicker() : LLPanel(),
 {
 }
 
+ALPanelMusicTicker::~ALPanelMusicTicker()
+{
+	if (mMetadataUpdateConnection.connected())
+	{
+		mMetadataUpdateConnection.disconnect();
+	}
+}
+
 BOOL ALPanelMusicTicker::postBuild()
 {
 	mArtistText =	getChild<LLTextBox>("artist_text");
@@ -54,8 +62,17 @@ BOOL ALPanelMusicTicker::postBuild()
 	mszLoading	=	getString("loading");
 	mszPaused	=	getString("paused");
 	mOscillatorColor = LLUIColorTable::getInstance()->getColor("ALMediaTickerOscillatorColor");
-	
-	setPaused(true);
+
+	if (gAudiop && gAudiop->getStreamingAudioImpl() && gAudiop->getStreamingAudioImpl()->supportsMetaData())
+	{
+		mMetadataUpdateConnection = gAudiop->getStreamingAudioImpl()->setMetadataUpdatedCallback([this](const LLSD& metadata) { metadataUpdateCallback(metadata); });
+
+		metadataUpdateCallback(gAudiop->getStreamingAudioImpl()->getMetadata());
+	}
+	else
+	{
+		metadataUpdateCallback(LLSD());
+	}
 
 	return LLPanel::postBuild();
 }
@@ -83,45 +100,34 @@ void ALPanelMusicTicker::reshape(S32 width, S32 height, BOOL called_from_parent/
 
 void ALPanelMusicTicker::updateTickerText() //called via draw.
 {
-	if(!gAudiop)
-		return;
+	iterateTickerOffset();
+}
 
-	bool stream_paused = gAudiop->getStreamingAudioImpl()->isPlaying() != 1;	//will return 1 if playing.
+void ALPanelMusicTicker::metadataUpdateCallback(const LLSD& metadata)
+{
+	bool stream_paused = true;
+	
+	if (gAudiop && gAudiop->getStreamingAudioImpl())
+	{
+		stream_paused = gAudiop->getStreamingAudioImpl()->isPlaying() != 1;	//will return 1 if playing.
+	}
 
 	bool dirty = setPaused(stream_paused);
-	if(!stream_paused)
+	if (!stream_paused)
 	{
-		if (dirty || gAudiop->getStreamingAudioImpl()->hasNewMetaData())
-		{
-			const LLSD* metadata = gAudiop->getStreamingAudioImpl()->getMetaData();
-			LLSD artist = metadata ? metadata->get("ARTIST") : LLSD();
-			LLSD title = metadata ? metadata->get("TITLE") : LLSD();
-	
-			dirty |= setArtist(artist.isDefined() ? artist.asString() : mszLoading);
-			dirty |= setTitle(title.isDefined() ? title.asString() : mszLoading);
-			if(artist.isDefined() && title.isDefined())
-				mLoadTimer.stop();
-			else if(dirty)
-				mLoadTimer.start();
-			else if(mLoadTimer.getStarted() && mLoadTimer.getElapsedTimeF64() > 10.f) //It has been 10 seconds.. give up.
-			{
-				if(!artist.isDefined())
-					dirty |= setArtist(LLStringUtil::null);
-				if(!title.isDefined())
-					dirty |= setTitle(LLStringUtil::null);
-				mLoadTimer.stop();
-			}
-		}
+			LLSD artist = metadata["ARTIST"];
+			LLSD title = metadata["TITLE"];
+
+			dirty |= setArtist(artist.isDefined() ? artist.asString() : LLStringUtil::null);
+			dirty |= setTitle(title.isDefined() ? title.asString() : LLStringUtil::null);
 	}
-	if(dirty)
+	if (dirty)
 		resetTicker();
-	else 
-		iterateTickerOffset();
 }
 
 void ALPanelMusicTicker::drawOscilloscope() //called via draw.
 {
-	if(!gAudiop || !mVisualizer || !gAudiop->getStreamingAudioImpl()->supportsWaveData())
+	if(!gAudiop || !mVisualizer || !gAudiop->getStreamingAudioImpl() || !gAudiop->getStreamingAudioImpl()->supportsWaveData())
 		return;
 
 	static const S32 NUM_LINE_STRIPS = 64;			//How many lines to draw. 64 is more than enough.
diff --git a/indra/newview/alpanelmusicticker.h b/indra/newview/alpanelmusicticker.h
index 6e3168330db4d2a4e9a34a237b76116c42910092..61f9519e810de69764ab15891922b7894adc26f8 100644
--- a/indra/newview/alpanelmusicticker.h
+++ b/indra/newview/alpanelmusicticker.h
@@ -30,6 +30,7 @@ class ALPanelMusicTicker final : public LLPanel
 {
 public:
 	ALPanelMusicTicker();	//ctor
+	~ALPanelMusicTicker();
 
 	BOOL postBuild() final override;
 	void draw() final override;
@@ -44,6 +45,8 @@ class ALPanelMusicTicker final : public LLPanel
 	S32 countExtraChars(LLTextBox *texbox, const std::string &text);	//calculates how many characters are truncated by bounds.
 	void iterateTickerOffset();	//Logic that actually shuffles the text to the left.
 
+	void metadataUpdateCallback(const LLSD&);
+
 	enum ePlayState
 	{
 		STATE_PAUSED,
@@ -67,6 +70,8 @@ class ALPanelMusicTicker final : public LLPanel
 	LLTextBox* mArtistText;
 	LLTextBox* mTitleText;
 	LLUICtrl* mVisualizer;
+
+	boost::signals2::connection mMetadataUpdateConnection;
 };
 
 #endif // AL_PANELMUSICTICKER_H
diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h
index 830d36b3c308fd3556100d8d0f8dcf884ccb690b..6fb1c575fd6824fa9da3e71a8db7d534dd634084 100644
--- a/indra/newview/llviewermedia_streamingaudio.h
+++ b/indra/newview/llviewermedia_streamingaudio.h
@@ -54,8 +54,6 @@ class LLStreamingAudio_MediaPlugins final : public LLStreamingAudioInterface
 	void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) override {};
 
 	virtual bool supportsMetaData() override { return false; }
-	virtual const LLSD *getMetaData() override { return nullptr; }
-	virtual bool hasNewMetaData() override { return false; }
 	virtual bool supportsWaveData() override { return false; }
 	virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) override { return false; }
 
diff --git a/indra/newview/skins/default/xui/en/floater_music_ticker.xml b/indra/newview/skins/default/xui/en/floater_music_ticker.xml
index 99daa03b410cf2de60ff6df31d945ae8b6f0487e..991c2d83c7d716def65a309616d8f2f50bd42cc8 100644
--- a/indra/newview/skins/default/xui/en/floater_music_ticker.xml
+++ b/indra/newview/skins/default/xui/en/floater_music_ticker.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- width="320"
- height="39"
+ width="360"
+ height="46"
  layout="topleft"
- min_width="300"
- min_height="39"
+ min_width="280"
+ min_height="46"
  name="floater_music_ticker"
  positioning="cascading"
  title=""
@@ -21,7 +21,7 @@
    filename="panel_music_ticker.xml"
    layout="topleft"
    follows="all"
-   width="296"
+   width="336"
    top="0"
    mouse_opaque="false"/>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/panel_music_ticker.xml b/indra/newview/skins/default/xui/en/panel_music_ticker.xml
index 4c380ec932d7fed3471ced17c1b5ff5ca91b6ad2..033b8b1f0f380e88d0781b8f63991c6ab465fb17 100644
--- a/indra/newview/skins/default/xui/en/panel_music_ticker.xml
+++ b/indra/newview/skins/default/xui/en/panel_music_ticker.xml
@@ -3,7 +3,7 @@
  layout="topleft"
  follows="top|right|left"
  width="300"
- height="38"
+ height="46"
  name="music_ticker">
     <string name="paused">
         (not playing)
@@ -12,7 +12,7 @@
         (loading...)
     </string>
     <icon
-     top="19"
+     top="23"
      color="AlAshGrey"
      follows="left|top|right" 
      height="1"
@@ -47,9 +47,9 @@
      bg_visible="false"
      border_visible="false"
      layout="topleft"
-     top="0"
+     top="2"
      follows="top|left"
-     font="SansSerifBold"
+     font="SansSerifBoldLarge"
      h_pad="0"
      halign="left"
      height="16"
@@ -64,13 +64,13 @@
      bg_visible="false" 
      border_visible="false"
      layout="topleft"
-     top="0" 
+     top="2" 
      follows="top|left|right"
-     font="SansSerifBold" 
+     font="SansSerifLarge" 
      h_pad="0" 
      halign="left" 
      height="16" 
-     left="50"
+     left="56"
      mouse_opaque="false" 
      name="artist_text" 
      v_pad="0" 
@@ -81,9 +81,9 @@
      bg_visible="false"
      border_visible="false" 
      layout="topleft"
-     top="19" 
+     top="26" 
      follows="top|left"
-     font="SansSerifBold"
+     font="SansSerifBoldLarge"
      h_pad="0" 
      halign="left" 
      height="16" 
@@ -98,9 +98,9 @@
      bg_visible="false" 
      border_visible="false" 
      layout="topleft"
-     top="19"
+     top="26"
      follows="top|left|right"
-     font="SansSerifBold"
+     font="SansSerifLarge"
      h_pad="0"
      halign="left"
      height="16"
@@ -109,5 +109,6 @@
      name="title_text"
      v_pad="0"
      width="193">
+     Cummies
     </text>
 </panel>