MetadataLiveSource does not register inside the Event Server background plugin?

Hi,

I attempted to set up a background service that listens to MetadataLiveSource, but it does not function when I use it within the EnvironmentType.Service. However, it works when I use EnvironmentType.Administration. Is there a workaround for this issue, or am I overlooking something?

Not sure if this is a timing issue since EnvironmentType.Service is within the Event Server. Is there a way to determine when the event server has fully finished loading?

public override void Init()
        {
            _stop = false;
            _thread = new Thread(new ThreadStart(Run));
            _thread.Name = "MetadataPlugin Background Thread";
            _thread.Start();
        }
 
        void _messageCommunication_ConnectionStateChangedEvent(object sender, EventArgs e)
        {
            if (_messageCommunication.IsConnected && !commReady)
            {
 
                try
                {
                    if (_alarmClient == null)
                    {
                        _alarmClient = _alarmClientManager.GetAlarmClient(EnvironmentManager.Instance.MasterSite.ServerId);
                    }
 
                    if (_metadataLiveSources.Count == 0)
                    {
                        IList<Item> metadataItems = _metadataService.GetMetadataItems();
                        if (metadataItems != null && metadataItems.Count > 0)
                        {
                            foreach (Item item in metadataItems)
                            {
                                MetadataLiveSource metadataLiveSource = new MetadataLiveSource(item);
 
                                try
                                {
                                    metadataLiveSource.LiveModeStart = true;
                                    metadataLiveSource.Init();
                                    metadataLiveSource.LiveContentEvent += OnLiveContentEvent;
                                    _metadataLiveSources.Add(metadataLiveSource);
                                    _liveSourceToItem[metadataLiveSource] = item;
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    EnvironmentManager.Instance.Log(false, "MetadataPlugin", $"Error initializing AlarmClient or MetadataLiveSources: {ex}", null);
                }
                finally
                {
                    commReady = true;
                    EnvironmentManager.Instance.Log(false, "MetadataPlugin", "Communication is ready", null);
                }
            }
        }
 
        private void Run()
        {
            EnvironmentManager.Instance.Log(false, "MetadataPlugin background thread", "Now starting...", null);
 
            MessageCommunicationManager.Start(EnvironmentManager.Instance.MasterSite.ServerId);
            _messageCommunication = MessageCommunicationManager.Get(EnvironmentManager.Instance.MasterSite.ServerId);
            _messageCommunication.ConnectionStateChangedEvent += new
                    EventHandler(_messageCommunication_ConnectionStateChangedEvent);
 
            while (!_stop)
            {
                Thread.Sleep(2000);
            }
            EnvironmentManager.Instance.Log(false, "MetadataPlugin background thread", "Now stopping...", null);
            _thread = null;
        }
 
 
 /// <summary>
 /// Define in what Environments the current background task should be started.
 /// </summary>
 public override List<EnvironmentType> TargetEnvironments
 {
     get { return new List<EnvironmentType>() { EnvironmentType.Administration }; }
 }

Upon further investigation, I discovered that retrieving the metadata items within the background service is ineffective.

  List<Item> metadataItems = Configuration.Instance
   .GetItemsByKind(Kind.Metadata)
   .Traverse(item => item.GetChildren())
   .Where(item =>
       item.FQID.Kind == Kind.Metadata &&
       item.FQID.FolderType == 0).ToList();
 
  List<Item> cameraList = Configuration.Instance
   .GetItemsByKind(Kind.Camera)
   .Traverse(item => item.GetChildren())
   .Where(item =>
       item.FQID.Kind == Kind.Camera &&
       item.FQID.FolderType == 0).ToList();
 
  EnvironmentManager.Instance.Log(false, "MetadataPlugin", $"Fetched {metadataItems.Count} metadata items.", null);
  EnvironmentManager.Instance.Log(false, "MetadataPlugin", $"Fetched {cameraList.Count} camera items.", null);

**UPDATE**

Since I cannot access the metadata items via Kind.Metadata, I attempted to retrieve the camera’s metadata using GetRelated(). This approach successfully obtains the metadata items, but it does not resolve the MetadataLiveSource issue.

List<Item> relatedItems = Configuration.Instance
.GetItemsByKind(Kind.Camera)
.Traverse(item => item.GetChildren())
.Where(item =>
    item.FQID.Kind == Kind.Camera &&
    item.FQID.FolderType == 0)
.SelectMany(item => item.GetRelated()
    .Where(r => r.Name.Equals(metadataListItem.Name, StringComparison.OrdinalIgnoreCase)))
.ToList();
 
metadataItems.AddRange(relatedItems);
 
  foreach (Item item in metadataItems)
  {
      MetadataLiveSource metadataLiveSource = new MetadataLiveSource(item);
      EnvironmentManager.Instance.Log(false, "MetadataPlugin", $"Fetched {item.Name} camera items.", null);
 
      try
      {
          metadataLiveSource.LiveModeStart = true;
          metadataLiveSource.Init();
          metadataLiveSource.LiveContentEvent += OnLiveContentEvent;
          _metadataLiveSources.Add(metadataLiveSource);
          _liveSourceToItem[metadataLiveSource] = item;
      }
      catch (Exception ex)
      {
          EnvironmentManager.Instance.Log(false, "MetadataPlugin", $"Error processing metadata live source: {ex}", null);
      }
  }

If you look at the description of MetadataLiveSource – https://doc.developer.milestonesys.com/html/index.html?base=miphelp/class_video_o_s_1_1_platform_1_1_live_1_1_metadata_live_source.html&tree=tree_search.html?search=metadatalivesource -

This class is responsible for delivering live metadata from a device.

Only supported in Smart Client and standalone environments.

So not implemented in the Event Server environment.

Event Server is not suited for large data handling, that is the reason that many classes for handling metadata or video data isn’t implemented.

To use the class make an application or service instead of an Event Server plugin.

Hi @Bo Ellegård Andersen (Milestone Systems)​ ,

Thank you very much for the feedback. A service worker is likely the best option that requires no user interaction.