From 004ea21e3fbc8c97e261cf9c212f8aa492d5a4ab Mon Sep 17 00:00:00 2001 From: badaix Date: Wed, 1 Sep 2021 18:18:36 +0200 Subject: [PATCH] Make metadata part of the properties --- common/properties.hpp | 34 ++++++++++- control/meta_mpd.py | 73 ++++++++++++++---------- control/snapcast_mpris.py | 19 ++---- doc/json_rpc_api/stream_plugin.md | 72 +++++++++++------------ server/server.cpp | 17 ------ server/server.hpp | 1 - server/streamreader/airplay_stream.cpp | 2 +- server/streamreader/librespot_stream.cpp | 4 +- server/streamreader/meta_stream.cpp | 11 ---- server/streamreader/meta_stream.hpp | 1 - server/streamreader/pcm_stream.cpp | 49 +++++----------- server/streamreader/pcm_stream.hpp | 3 - test/test_main.cpp | 1 - 13 files changed, 134 insertions(+), 153 deletions(-) diff --git a/common/properties.hpp b/common/properties.hpp index 43408e11..e0e2346b 100644 --- a/common/properties.hpp +++ b/common/properties.hpp @@ -26,6 +26,8 @@ #include "common/aixlog.hpp" #include "common/json.hpp" +#include "common/metatags.hpp" + using json = nlohmann::json; @@ -152,6 +154,8 @@ public: fromJson(j); } + /// Meta data + std::optional metatags; /// https://www.musicpd.org/doc/html/protocol.html#tags /// The current playback status std::optional playback_status; @@ -202,6 +206,8 @@ public: addTag(j, "canPause", can_pause); addTag(j, "canSeek", can_seek); addTag(j, "canControl", can_control); + if (metatags.has_value()) + addTag(j, "metadata", metatags->toJson()); return j; } @@ -209,7 +215,7 @@ public: { static std::set rw_props = {"loopStatus", "shuffle", "volume", "rate"}; static std::set ro_props = {"playbackStatus", "loopStatus", "shuffle", "volume", "position", "minimumRate", "maximumRate", - "canGoNext", "canGoPrevious", "canPlay", "canPause", "canSeek", "canControl"}; + "canGoNext", "canGoPrevious", "canPlay", "canPause", "canSeek", "canControl", "metadata"}; for (const auto& element : j.items()) { bool is_rw = (rw_props.find(element.key()) != rw_props.end()); @@ -243,12 +249,38 @@ public: readTag(j, "canPause", can_pause, false); readTag(j, "canSeek", can_seek, false); readTag(j, "canControl", can_control, false); + + if (j.contains("metadata")) + { + Metatags m; + m.fromJson(j["metadata"]); + metatags = m; + } + else + metatags = std::nullopt; } bool operator==(const Properties& other) const { // expensive, but not called ofetn and less typing return (toJson() == other.toJson()); + + // clang-format off + // return (playback_status == other.playback_status && + // loop_status == other.loop_status && + // rate == other.rate && + // shuffle == other.shuffle && + // volume == other.volume && + // position == other.position && + // minimum_rate == other.minimum_rate && + // maximum_rate == other.maximum_rate && + // can_go_next == other.can_go_next && + // can_go_previous == other.can_go_previous && + // can_play == other.can_play && + // can_pause == other.can_pause && + // can_seek == other.can_seek && + // can_control == other.can_control); + // clang-format on } private: diff --git a/control/meta_mpd.py b/control/meta_mpd.py index 5e4bcee0..1c2fb82a 100755 --- a/control/meta_mpd.py +++ b/control/meta_mpd.py @@ -376,7 +376,8 @@ class MPDWrapper(object): success = True command = request['params']['command'] params = request['params'].get('params', {}) - logger.debug(f'Control command: {command}, params: {params}') + logger.debug( + f'Control command: {command}, params: {params}') if command == 'Next': self.next() elif command == 'Previous': @@ -495,8 +496,20 @@ class MPDWrapper(object): def __track_key(self, snapmeta): return hash(snapmeta.get('artist', [''])[0] + snapmeta.get('album', snapmeta.get('title', ''))) - def update_albumart(self, snapmeta): + def get_albumart(self, snapmeta, cached): album_key = 'musicbrainzAlbumId' + track_key = self.__track_key(snapmeta) + album_art = self._album_art_map.get(track_key) + if album_art is not None: + if album_art == '': + return None + else: + return album_art + + if cached: + return None + + self._album_art_map[track_key] = '' try: if not album_key in snapmeta: mbartist = None @@ -521,22 +534,21 @@ class MPDWrapper(object): data = musicbrainzngs.get_image_list(snapmeta[album_key]) for image in data["images"]: if "Front" in image["types"] and image["approved"]: - snapmeta['artUrl'] = image["thumbnails"]["small"] + album_art = image["thumbnails"]["small"] logger.debug( - f'{snapmeta["artUrl"]} is an approved front image') - logger.info(f'Snapmeta: {snapmeta}') - self._album_art_map[self.__track_key( - snapmeta)] = snapmeta['artUrl'] - send( - {"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Metadata", "params": snapmeta}) + f'{album_art} is an approved front image') + self._album_art_map[track_key] = album_art break except musicbrainzngs.musicbrainz.ResponseError as e: logger.error( f'Error while getting cover for {snapmeta[album_key]}: {e}') - self._album_art_map[self.__track_key(snapmeta)] = '' + album_art = self._album_art_map[track_key] + if album_art == '': + return None + return album_art - def update_metadata(self): + def get_metadata(self): """ Translate metadata returned by MPD to the MPRIS v2 syntax. http://www.freedesktop.org/wiki/Specifications/mpris-spec/metadata @@ -586,19 +598,12 @@ class MPDWrapper(object): snapmeta['artist'] = [fields[0]] snapmeta['title'] = fields[1] - track_key = self.__track_key(snapmeta) - if track_key in self._album_art_map: - art_url = self._album_art_map[track_key] + art_url = self.get_albumart(snapmeta, True) + if art_url is not None: logger.info(f'album art cache hit: "{art_url}"') - if art_url != '': - snapmeta['artUrl'] = art_url + snapmeta['artUrl'] = art_url - send({"jsonrpc": "2.0", - "method": "Plugin.Stream.Player.Metadata", "params": snapmeta}) - if not track_key in self._album_art_map: - # t = threading.Thread(target=self.update_albumart, args=[snapmeta]) - # t.start() - self.update_albumart(snapmeta) + return snapmeta def __diff_map(self, old_map, new_map): diff = {} @@ -662,14 +667,11 @@ class MPDWrapper(object): logger.debug('nothing to do') return - logger.info(f'new status: {new_status}') - logger.info(f'changed_status: {changed_status}') - logger.info(f'changed_song: {changed_song}') + logger.info( + f'new status: {new_status}, changed_status: {changed_status}, changed_song: {changed_song}') self._time = new_time = int(time.time()) snapstatus = self._get_properties(new_status) - send({"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Properties", - "params": snapstatus}) if 'elapsed' in new_status: new_position = float(new_status['elapsed']) @@ -682,9 +684,9 @@ class MPDWrapper(object): # "player" subsystem - force = len(changed_song) > 0 + new_song = len(changed_song) > 0 - if not force: + if not new_song: if new_status['state'] == 'play': expected_position = old_position + (new_time - old_time) else: @@ -698,7 +700,18 @@ class MPDWrapper(object): else: # Update current song metadata - self.update_metadata() + snapstatus["metadata"] = self.get_metadata() + + send({"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Properties", + "params": snapstatus}) + + if new_song: + if 'artUrl' not in snapstatus['metadata']: + album_art = self.get_albumart(snapstatus['metadata'], False) + if album_art is not None: + snapstatus['metadata']['artUrl'] = album_art + send( + {"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Properties", "params": snapstatus}) # Compatibility functions diff --git a/control/snapcast_mpris.py b/control/snapcast_mpris.py index 0bde96a0..798324da 100755 --- a/control/snapcast_mpris.py +++ b/control/snapcast_mpris.py @@ -331,12 +331,12 @@ class SnapcastWrapper(object): if not 'mpris:artUrl' in self._metadata: self._metadata['mpris:artUrl'] = f'http://{self._params["host"]}:{self._params["port"]}/snapcast-512.png' - logger.info(f'mpris meta: {self._metadata}') + logger.debug(f'mpris meta: {self._metadata}') self.notify_about_track(self._metadata) new_meta = self._dbus_service.update_property('org.mpris.MediaPlayer2.Player', 'Metadata') - logger.info(f'new meta {new_meta}') + logger.debug(f'new meta {new_meta}') except Exception as e: logger.error(f'Error in update_metadata: {str(e)}') @@ -344,11 +344,10 @@ class SnapcastWrapper(object): try: if props is None: props = {} - logger.info(f'Properties: "{props}"') + logger.debug(f'Properties: "{props}"') # store the last receive time stamp for better position estimation if 'position' in props: props['_received'] = time.time() - # ignore "internal" properties, starting with "_" changed_properties = {} for key, value in props.items(): @@ -369,6 +368,8 @@ class SnapcastWrapper(object): if key in property_mapping: self._dbus_service.update_property( 'org.mpris.MediaPlayer2.Player', property_mapping[key]) + if 'metadata' in changed_properties: + self.__update_metadata(props.get('metadata', None)) except Exception as e: logger.error(f'Error in update_properties: {str(e)}') @@ -388,8 +389,6 @@ class SnapcastWrapper(object): logger.info(f'Stream id: {self._stream_id}') for stream in jmsg['result']['server']['streams']: if stream['id'] == self._stream_id: - if 'metadata' in stream: - self.__update_metadata(stream['metadata']) if 'properties' in stream: self.__update_properties(stream['properties']) break @@ -399,14 +398,6 @@ class SnapcastWrapper(object): logger.info(f'Stream id: {self._stream_id}') elif jmsg['method'] == "Group.OnStreamChanged": self.send_request("Server.GetStatus") - elif jmsg["method"] == "Stream.OnMetadata": - stream_id = jmsg["params"]["id"] - logger.info(f'Stream meta changed for "{stream_id}"') - if self._stream_id != stream_id: - return - meta = jmsg["params"]["metadata"] - self.__update_metadata(meta) - elif jmsg["method"] == "Stream.OnProperties": stream_id = jmsg["params"]["id"] logger.info( diff --git a/doc/json_rpc_api/stream_plugin.md b/doc/json_rpc_api/stream_plugin.md index d7e11559..557c604d 100644 --- a/doc/json_rpc_api/stream_plugin.md +++ b/doc/json_rpc_api/stream_plugin.md @@ -4,11 +4,11 @@ A stream plugin is (this might change in future) an executable binary or script that is started by the server for a specific stream and offers playback control capabilities and provides information about the stream's state, as well as metadata for the currently playing track. The Snapcast server communicates via stdin/stdout with the plugin and sends newline delimited JSON-RPC commands and receives responses and notifications from the plugin, as described below. In upcoming releases shared library plugins might be supported as well. -## Requests: +## Requests A Stream plugin must support and handle the following requests, sent by the Snapcast server -### Plugin.Stream.Player.Control: +### Plugin.Stream.Player.Control Used to control the player @@ -19,33 +19,33 @@ Used to control the player Supported `command`s: - `Play`: Start playback - - `params`: none + - `params`: none - `Pause`: Stop playback - - `params`: none + - `params`: none - `PlayPause`: Toggle play/pause - - `params`: none + - `params`: none - `Stop`: Stop playback - - `params`: none + - `params`: none - `Next`: Skip to next track - - `params`: none + - `params`: none - `Previous`: Skip to previous track - - `params`: none + - `params`: none - `Seek`: Seek forward or backward in the current track - - `params`: - - `Offset`: [float] seek offset in seconds + - `params`: + - `Offset`: [float] seek offset in seconds - `SetPosition`: Set the current track position in seconds - - `params`: - - `Position`: [float] the new track position - - `TrackId`: [string] the optional currently playing track's identifier + - `params`: + - `Position`: [float] the new track position + - `TrackId`: [string] the optional currently playing track's identifier -#### Example: +#### Example ```json {"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.Control", "params": {"command": "SetPosition", "params": { "Position": 170966827, "TrackId": "/org/mpris/MediaPlayer2/Track/2"}}} ``` -#### Expected response: +#### Expected response Success: @@ -59,23 +59,23 @@ Error: todo ``` -### Plugin.Stream.Player.SetProperty: +### Plugin.Stream.Player.SetProperty ```json {"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.SetProperty", "params": {"", }} ``` -#### Supported `property`s: +#### Supported `property`s - `loopStatus`: [string] the current repeat status, one of: - - `none`: the playback will stop when there are no more tracks to play - - `track`: the current track will start again from the begining once it has finished playing - - `playlist`: the playback loops through a list of tracks + - `none`: the playback will stop when there are no more tracks to play + - `track`: the current track will start again from the begining once it has finished playing + - `playlist`: the playback loops through a list of tracks - `shuffle`: [bool] play playlist in random order - `volume`: [int] voume in percent, valid range [0..100] - `rate`: [float] The current playback rate, valid range (0..) -#### Expected response: +#### Expected response Success: @@ -95,7 +95,7 @@ todo {"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.GetProperties"} ``` -#### Expected response: +#### Expected response Success: @@ -106,13 +106,13 @@ Success: #### Supported `property`s - `playbackStatus`: [string] The current playback status, one of: - - `playing` - - `paused` - - `stopped` + - `playing` + - `paused` + - `stopped` - `loopStatus`: [string] The current repeat status, one of: - - `none`: The playback will stop when there are no more tracks to play - - `track`: The current track will start again from the begining once it has finished playing - - `playlist`: The playback loops through a list of tracks + - `none`: The playback will stop when there are no more tracks to play + - `track`: The current track will start again from the begining once it has finished playing + - `playlist`: The playback loops through a list of tracks - `rate`: [float] The current playback rate, valid range (0..) - `shuffle`: [bool] Traverse through the playlist in random order - `volume`: [int] Voume in percent, valid range [0..100] @@ -132,11 +132,13 @@ todo ### Plugin.Stream.Player.GetMetadata +TODO: Metadata are part of the properties + ```json {"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.GetMetadata"} ``` -#### Expected response: +#### Expected response Success: @@ -144,10 +146,12 @@ Success: {"id": 1, "jsonrpc": "2.0", "result": {"artist":["Travis Scott & HVME"],"file":"http://wdr-1live-live.icecast.wdr.de/wdr/1live/live/mp3/128/stream.mp3","name":"1Live, Westdeutscher Rundfunk Koeln","title":"Goosebumps (Remix)","trackId":"3"}} ``` -## Notifications: +## Notifications ### Plugin.Stream.Player.Metadata +TODO: Metadata are part of the properties + ```json {"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Metadata", "params": {"artist":["Travis Scott & HVME"],"file":"http://wdr-1live-live.icecast.wdr.de/wdr/1live/live/mp3/128/stream.mp3","name":"1Live, Westdeutscher Rundfunk Koeln","title":"Goosebumps (Remix)","trackId":"3"}} ``` @@ -199,7 +203,6 @@ Success: - `spotifyArtistId`: [string] The [Spotify Artist ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) - `spotifyTrackId`: [string] The [Spotify Track ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) - ### Plugin.Stream.Player.Properties ```json @@ -234,12 +237,11 @@ The plugin shall send this notification when it's up and ready to receive comman {"jsonrpc": "2.0", "method": "Plugin.Stream.Ready"} ``` - -# Server: +# Server TODO: this belongs to doc/json_rpc_api/v2_0_0.md -## Requests: +## Requests To control the stream state, the following commands can be sent to the Snapcast server and will be forwarded to the respective stream: @@ -251,7 +253,7 @@ To control the stream state, the following commands can be sent to the Snapcast {"id": 1, "jsonrpc": "2.0", "method": "Stream.SetProperty", "params": {"id": "Pipe", "property": property, "value": value}} ``` -## Notifications: +## Notifications ```json {"jsonrpc": "2.0", "method": "Stream.OnMetadata", "params": {"id": "Pipe", "metadata": {}}} diff --git a/server/server.cpp b/server/server.cpp index c84055f3..12c67523 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -49,23 +49,6 @@ void Server::onNewSession(std::shared_ptr session) } -void Server::onMetadataChanged(const PcmStream* pcmStream, const Metatags& metadata) -{ - // clang-format off - // Notification: {"jsonrpc":"2.0","method":"Stream.OnMetadata","params":{"id":"stream 1", "metadata": {"album": "some album", "artist": "some artist", "track": "some track"...}}} - // clang-format on - - LOG(DEBUG, LOG_TAG) << "Metadata changed, stream: " << pcmStream->getName() << ", meta: " << metadata.toJson().dump(3) << "\n"; - - // streamServer_->onMetadataChanged(pcmStream, meta); - - // Send meta to all connected clients - json notification = jsonrpcpp::Notification("Stream.OnMetadata", jsonrpcpp::Parameter("id", pcmStream->getId(), "metadata", metadata.toJson())).to_json(); - controlServer_->send(notification.dump(), nullptr); - // cout << "Notification: " << notification.dump() << "\n"; -} - - void Server::onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) { LOG(DEBUG, LOG_TAG) << "Properties changed, stream: " << pcmStream->getName() << ", properties: " << properties.toJson().dump(3) << "\n"; diff --git a/server/server.hpp b/server/server.hpp index 226f6a1e..41144490 100644 --- a/server/server.hpp +++ b/server/server.hpp @@ -78,7 +78,6 @@ private: void onNewSession(std::shared_ptr session) override; /// Implementation of PcmListener - void onMetadataChanged(const PcmStream* pcmStream, const Metatags& metadata) override; void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; diff --git a/server/streamreader/airplay_stream.cpp b/server/streamreader/airplay_stream.cpp index 9797d12b..f422024e 100644 --- a/server/streamreader/airplay_stream.cpp +++ b/server/streamreader/airplay_stream.cpp @@ -183,7 +183,7 @@ void AirplayStream::push() // mden = metadata end, pcen == picture end if (metadata_dirty_ && entry_->type == "ssnc" && (entry_->code == "mden" || entry_->code == "pcen")) { - setMetadata(metadata_); + // setMetadata(metadata_); metadata_dirty_ = false; } } diff --git a/server/streamreader/librespot_stream.cpp b/server/streamreader/librespot_stream.cpp index d794b117..eaa9d107 100644 --- a/server/streamreader/librespot_stream.cpp +++ b/server/streamreader/librespot_stream.cpp @@ -161,7 +161,7 @@ void LibrespotStream::onStderrMsg(const std::string& line) Metatags meta; meta.artist = std::vector{j["ARTIST"].get()}; meta.title = j["TITLE"].get(); - setMetadata(meta); + // TODO setMetadata(meta); } else if (regex_search(line, m, re_track_loaded)) { @@ -169,7 +169,7 @@ void LibrespotStream::onStderrMsg(const std::string& line) Metatags meta; meta.title = string(m[1]); meta.duration = cpt::stod(m[2]) / 1000.; - setMetadata(meta); + // TODO setMetadata(meta); Properties properties; // properties.can_seek = true; // properties.can_control = true; diff --git a/server/streamreader/meta_stream.cpp b/server/streamreader/meta_stream.cpp index d931d880..3b7e11b4 100644 --- a/server/streamreader/meta_stream.cpp +++ b/server/streamreader/meta_stream.cpp @@ -84,16 +84,6 @@ void MetaStream::stop() } -void MetaStream::onMetadataChanged(const PcmStream* pcmStream, const Metatags& metadata) -{ - LOG(DEBUG, LOG_TAG) << "onMetadataChanged: " << pcmStream->getName() << "\n"; - std::lock_guard lock(mutex_); - if (pcmStream != active_stream_.get()) - return; - setMetadata(metadata); -} - - void MetaStream::onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) { LOG(DEBUG, LOG_TAG) << "onPropertiesChanged: " << pcmStream->getName() << "\n"; @@ -118,7 +108,6 @@ void MetaStream::onStateChanged(const PcmStream* pcmStream, ReaderState state) LOG(INFO, LOG_TAG) << "Stream: " << name_ << ", switching active stream: " << (active_stream_ ? active_stream_->getName() : "") << " => " << new_stream->getName() << "\n"; active_stream_ = new_stream; - setMetadata(active_stream_->getMetadata()); setProperties(active_stream_->getProperties()); resampler_ = make_unique(active_stream_->getSampleFormat(), sampleFormat_); }; diff --git a/server/streamreader/meta_stream.hpp b/server/streamreader/meta_stream.hpp index b651c129..6f1632bf 100644 --- a/server/streamreader/meta_stream.hpp +++ b/server/streamreader/meta_stream.hpp @@ -62,7 +62,6 @@ public: protected: /// Implementation of PcmListener - void onMetadataChanged(const PcmStream* pcmStream, const Metatags& metadata) override; void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) override; void onStateChanged(const PcmStream* pcmStream, ReaderState state) override; void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) override; diff --git a/server/streamreader/pcm_stream.cpp b/server/streamreader/pcm_stream.cpp index 58493622..e8f9032a 100644 --- a/server/streamreader/pcm_stream.cpp +++ b/server/streamreader/pcm_stream.cpp @@ -137,12 +137,7 @@ void PcmStream::onControlNotification(const jsonrpcpp::Notification& notificatio try { LOG(INFO, LOG_TAG) << "Notification method: " << notification.method() << ", params: " << notification.params().to_json() << "\n"; - if (notification.method() == "Plugin.Stream.Player.Metadata") - { - LOG(DEBUG, LOG_TAG) << "Received metadata notification\n"; - setMetadata(notification.params().to_json()); - } - else if (notification.method() == "Plugin.Stream.Player.Properties") + if (notification.method() == "Plugin.Stream.Player.Properties") { LOG(DEBUG, LOG_TAG) << "Received properties notification\n"; setProperties(notification.params().to_json()); @@ -155,15 +150,10 @@ void PcmStream::onControlNotification(const jsonrpcpp::Notification& notificatio if (response.error().code() == 0) setProperties(response.result()); }); - stream_ctrl_->command({++req_id_, "Plugin.Stream.Player.GetMetadata"}, [this](const jsonrpcpp::Response& response) { - LOG(INFO, LOG_TAG) << "Response for Plugin.Stream.Player.GetMetadata: " << response.to_json() << "\n"; - if (response.error().code() == 0) - setMetadata(response.result()); - }); // TODO: Add capabilities or settings? // {"jsonrpc": "2.0", "method": "Plugin.Stream.Ready", "params": {"pollProperties": 10, "responseTimeout": 5}} - pollProperties(); + // pollProperties(); } else if (notification.method() == "Plugin.Stream.Log") { @@ -452,44 +442,31 @@ void PcmStream::play(ResultHandler handler) } -void PcmStream::setMetadata(const Metatags& metadata) -{ - std::lock_guard lock(mutex_); - if (metadata == metadata_) - { - LOG(DEBUG, LOG_TAG) << "setMetadata: Metadata did not change\n"; - return; - } - - metadata_ = metadata; - LOG(INFO, LOG_TAG) << "setMetadata, stream: " << getId() << ", metadata: " << metadata_.toJson() << "\n"; - - // Trigger a stream update - for (auto* listener : pcmListeners_) - { - if (listener != nullptr) - listener->onMetadataChanged(this, metadata_); - } -} - - void PcmStream::setProperties(const Properties& properties) { std::lock_guard lock(mutex_); - if (properties == properties_) + + Properties props = properties; + // Missing metadata means, they didn't change, so + // enrich the new properites with old metadata + if (!props.metatags.has_value() && properties_.metatags.has_value()) + props.metatags = properties_.metatags; + + if (props == properties_) { LOG(DEBUG, LOG_TAG) << "setProperties: Properties did not change\n"; return; } - properties_ = properties; + properties_ = std::move(props); + LOG(INFO, LOG_TAG) << "setProperties, stream: " << getId() << ", properties: " << properties_.toJson() << "\n"; // Trigger a stream update for (auto* listener : pcmListeners_) { if (listener != nullptr) - listener->onPropertiesChanged(this, properties); + listener->onPropertiesChanged(this, properties_); } } diff --git a/server/streamreader/pcm_stream.hpp b/server/streamreader/pcm_stream.hpp index 854f4b9b..13aa47bc 100644 --- a/server/streamreader/pcm_stream.hpp +++ b/server/streamreader/pcm_stream.hpp @@ -30,7 +30,6 @@ #include "common/error_code.hpp" #include "common/json.hpp" -#include "common/metatags.hpp" #include "common/properties.hpp" #include "common/sample_format.hpp" #include "encoder/encoder.hpp" @@ -98,7 +97,6 @@ static constexpr auto kControlScript = "controlscript"; class PcmListener { public: - virtual void onMetadataChanged(const PcmStream* pcmStream, const Metatags& metadata) = 0; virtual void onPropertiesChanged(const PcmStream* pcmStream, const Properties& properties) = 0; virtual void onStateChanged(const PcmStream* pcmStream, ReaderState state) = 0; virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& chunk) = 0; @@ -166,7 +164,6 @@ protected: void resync(const std::chrono::nanoseconds& duration); void chunkEncoded(const encoder::Encoder& encoder, std::shared_ptr chunk, double duration); - void setMetadata(const Metatags& metadata); void setProperties(const Properties& properties); void pollProperties(); diff --git a/test/test_main.cpp b/test/test_main.cpp index 0b49c088..4675fef4 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -22,7 +22,6 @@ #include #include "common/aixlog.hpp" -#include "common/metatags.hpp" #include "common/properties.hpp" #include "common/utils/string_utils.hpp" #include "server/streamreader/control_error.hpp"