protected virtual void OnPlaybackLoopChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var isLoop = (bool)message.FirstOrDefault();

            PlaybackLoopChanged?.Invoke(this, new PlaybackLoopEventArgs(isLoop, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipNameChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            PlaybackClipChanged?.Invoke(this, new PlaybackClipClipChangedEventArgs(message.Single().ToString(), message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipTimeChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var elapsed = (float)(message.ElementAtOrDefault(0));
            var total   = (float)(message.ElementAtOrDefault(1));

            PlaybackClipTimeChanged?.Invoke(this, new PlaybackClipTimeEventArgs(elapsed, total, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnStreamFramerateChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var fps      = (float)(message.ElementAtOrDefault(0));
            var streamId = uint.TryParse(message.GetNextAddressPartOf("file"), out uint outValue) ? (uint?)outValue : null;

            StreamFrameRateChanged?.Invoke(this, new StreamFramerateEventArgs(fps, streamId.GetValueOrDefault(0), message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipFrameRateChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var fps = (float)(message.ElementAtOrDefault(0));

            PlaybackClipFrameRateChanged?.Invoke(this, new PlaybackClipFrameRateEventArgs(fps, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipWidthChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var width = Convert.ToInt32(message.ElementAtOrDefault(0));

            PlaybackClipWidthChanged?.Invoke(this, new PlaybackClipWidthEventArgs((uint)width, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipFieldChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var isProgresive = ProgressiveValue.Equals(message.FirstOrDefault()?.ToString(), StringComparison.OrdinalIgnoreCase);

            PlaybackClipFieldChanged?.Invoke(this, new PlaybackClipFieldEventArg(isProgresive, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipVideoCodecChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var codec = message.FirstOrDefault()?.ToString();

            PlaybackClipVideoCodecChanged?.Invoke(this, new PlaybackClipCodecEventArg(codec, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }
        protected virtual void OnPlaybackClipAudioFrameRateChanged(OscMessage message)
        {
            var channelLayer = message.GetChannelAndLayer();

            if (channelLayer.Item1 == null || channelLayer.Item2 == null)
            {
                return;
            }

            var sampleRate = Convert.ToInt32(message.ElementAtOrDefault(0));

            PlaybackClipAudioSampleRateChanged?.Invoke(this, new PlaybackClipAudioSampleRateEventArg((uint)sampleRate, message.IsBackground(), channelLayer.Item1.Value, channelLayer.Item2.Value));
        }