public bool Load(Event aEvent)
        {
            var channel = _casparChannel;

            if (aEvent != null && CheckConnected(channel))
            {
                var eventType = aEvent.EventType;
                if (eventType == TEventType.Live || eventType == TEventType.Movie || eventType == TEventType.StillImage)
                {
                    CasparItem item = _getItem(aEvent);
                    if (item != null)
                    {
                        channel.Load(item);
                        if (eventType == TEventType.Live)
                        {
                            channel.Play(item.VideoLayer);
                        }
                        _visible[aEvent.Layer] = aEvent;
                        Event removed;
                        _loadedNext.TryRemove(aEvent.Layer, out removed);
                        Debug.WriteLine(aEvent, "CasparLoad: ");
                        return(true);
                    }
                }
            }
            Debug.WriteLine(aEvent, "CasparLoad did not load: ");
            return(false);
        }
        private CasparItem _getItem(Event aEvent)
        {
            CasparItem       item  = new CasparItem(string.Empty);
            IPersistentMedia media = (aEvent.Engine.PlayoutChannelPRI == this) ? aEvent.ServerMediaPRI : aEvent.ServerMediaSEC;

            if (aEvent.EventType == TEventType.Live || media != null)
            {
                if (aEvent.EventType == TEventType.Movie || aEvent.EventType == TEventType.StillImage)
                {
                    item.Clipname = string.Format($"\"{Path.GetFileNameWithoutExtension(media.FileName)}\"");
                }
                if (aEvent.EventType == TEventType.Live)
                {
                    item.Clipname = string.IsNullOrWhiteSpace(LiveDevice) ? "BLACK" : LiveDevice;
                }
                if (aEvent.EventType == TEventType.Live || aEvent.EventType == TEventType.Movie)
                {
                    item.ChannelLayout = ChannelLayout.Stereo;
                }
                if (aEvent.EventType == TEventType.Movie)
                {
                    item.FieldOrderInverted = media.FieldOrderInverted;
                }
                item.VideoLayer          = (int)aEvent.Layer;
                item.Loop                = false;
                item.Transition.Type     = (TransitionType)aEvent.TransitionType;
                item.Transition.Duration = (int)((aEvent.TransitionTime.Ticks - aEvent.TransitionPauseTime.Ticks) / aEvent.Engine.FrameTicks);
                item.Transition.Pause    = (int)(aEvent.TransitionPauseTime.Ticks / aEvent.Engine.FrameTicks);
                item.Transition.Easing   = (Easing)aEvent.TransitionEasing;
                item.Seek                = (int)aEvent.MediaSeek;
                return(item);
            }
            return(null);
        }
 private CasparItem _getItem(MediaBase media, VideoLayer videolayer, long seek)
 {
     if (media != null && media.MediaType == TMediaType.Movie)
     {
         CasparItem item = new CasparItem(string.Empty);
         item.Clipname           = $"\"{(media is ServerMedia ? Path.GetFileNameWithoutExtension(media.FileName) : media.FullPath)}\"";
         item.ChannelLayout      = ChannelLayout.Stereo;
         item.VideoLayer         = (int)videolayer;
         item.Seek               = (int)seek;
         item.FieldOrderInverted = media.FieldOrderInverted;
         return(item);
     }
     else
     {
         return(null);
     }
 }
        public bool Load(System.Drawing.Color color, VideoLayer videolayer)
        {
            var channel = _casparChannel;

            if (CheckConnected(channel))
            {
                var        scolor = '#' + color.ToArgb().ToString("X8");
                CasparItem item   = new CasparItem((int)videolayer, scolor);
                channel.Load(item);
                Event removed;
                _visible.TryRemove(videolayer, out removed);
                _loadedNext.TryRemove(videolayer, out removed);
                Debug.WriteLine("CasparLoad color {0} Layer {1}", scolor, videolayer);
                return(true);
            }
            return(false);
        }
        public bool Load(MediaBase media, VideoLayer videolayer, long seek, long duration)
        {
            var channel = _casparChannel;

            if (CheckConnected(channel) &&
                media != null)
            {
                CasparItem item = _getItem(media, videolayer, seek);
                if (item != null)
                {
                    item.Length = (int)duration;
                    channel.Load(item);
                    Event removed;
                    _visible.TryRemove(videolayer, out removed);
                    _loadedNext.TryRemove(videolayer, out removed);
                    Debug.WriteLine("CasparLoad media {0} Layer {1} Seek {2}", media, videolayer, seek);
                    return(true);
                }
            }
            return(false);
        }
        public bool LoadNext(Event aEvent)
        {
            var channel = _casparChannel;

            if (aEvent != null && CheckConnected(channel))
            {
                var eventType = aEvent.EventType;
                if (eventType == TEventType.Live || eventType == TEventType.Movie || eventType == TEventType.StillImage)
                {
                    CasparItem item = _getItem(aEvent);
                    if (item != null)
                    {
                        channel.LoadBG(item);
                        _loadedNext[aEvent.Layer] = aEvent;
                        Debug.WriteLine(aEvent, "CasparLoadNext: ");
                        return(true);
                    }
                }
            }
            Debug.WriteLine(aEvent, "LoadNext did not load: ");
            return(false);
        }
        public void ReStart(Event ev)
        {
            var channel = _casparChannel;

            if (CheckConnected(channel) &&
                ev != null)
            {
                CasparItem item = _getItem(ev);
                if (item != null)
                {
                    if (ev.EventType == TEventType.Movie && ev.Media != null)
                    {
                        item.Seek = (int)ev.Position + (int)((ev.ScheduledTc.Ticks - ev.Media.TcPlay.Ticks) / ev.Engine.FrameTicks);
                    }
                    item.Transition.Duration = 3;
                    item.Transition.Type     = TransitionType.MIX;
                    channel.LoadBG(item);
                    channel.Play(item.VideoLayer);
                    Debug.WriteLine("CasparChanner.ReStart: restarted {0} from frame {1}", item.Clipname, item.Seek);
                }
            }
        }
        public bool Execute(string command)
        {
            var channel = _casparChannel;

            if (string.IsNullOrWhiteSpace(command) || !CheckConnected(channel))
            {
                return(false);
            }
            Match match = RegexMixerFill.Match(command);

            if (match.Success)
            {
                VideoLayer layer    = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                float      x        = float.Parse(match.Groups["x"].Value, CultureInfo.InvariantCulture);
                float      y        = float.Parse(match.Groups["y"].Value, CultureInfo.InvariantCulture);
                float      sx       = float.Parse(match.Groups["sx"].Value, CultureInfo.InvariantCulture);
                float      sy       = float.Parse(match.Groups["sy"].Value, CultureInfo.InvariantCulture);
                int        duration = string.IsNullOrWhiteSpace(match.Groups["duration"].Value)
                    ? 0
                    : int.Parse(match.Groups["duration"].Value);
                TEasing easing = match.Groups["easing"].Success
                    ? (TEasing)Enum.Parse(typeof(TEasing), match.Groups["easing"].Value, true)
                    : TEasing.Linear;
                channel.Fill((int)layer, x, y, sx, sy, duration, (Easing)easing);
                return(true);
            }
            match = RegexMixerClip.Match(command);
            if (match.Success)
            {
                VideoLayer layer    = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                float      x        = float.Parse(match.Groups["x"].Value, CultureInfo.InvariantCulture);
                float      y        = float.Parse(match.Groups["y"].Value, CultureInfo.InvariantCulture);
                float      sx       = float.Parse(match.Groups["sx"].Value, CultureInfo.InvariantCulture);
                float      sy       = float.Parse(match.Groups["sy"].Value, CultureInfo.InvariantCulture);
                int        duration = string.IsNullOrWhiteSpace(match.Groups["duration"].Value)
                    ? 0
                    : int.Parse(match.Groups["duration"].Value);
                TEasing easing = match.Groups["easing"].Success
                    ? (TEasing)Enum.Parse(typeof(TEasing), match.Groups["easing"].Value, true)
                    : TEasing.Linear;
                channel.Clip((int)layer, x, y, sx, sy, duration, (Easing)easing);
                return(true);
            }
            match = RegexMixerClear.Match(command);
            if (match.Success)
            {
                VideoLayer layer = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                channel.ClearMixer((int)layer);
                return(true);
            }
            match = RegexPlay.Match(command);
            if (match.Success)
            {
                VideoLayer layer = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                string     file  = match.Groups["file"].Value;
                CasparItem item  = new CasparItem((int)layer, file);
                Capture    transitionTypeCapture     = match.Groups["transition_type"];
                Capture    transitionDurationCapture = match.Groups["transition_duration"];
                Capture    transitionEasingCapture   = match.Groups["easing"];
                if (int.TryParse(transitionDurationCapture.Value, out var transitionDuration) &&
                    Enum.TryParse(transitionTypeCapture.Value, true, out TransitionType transitionType))
                {
                    item.Transition.Type     = transitionType;
                    item.Transition.Duration = transitionDuration;
                    if (Enum.TryParse(transitionEasingCapture.Value, true, out Easing easing))
                    {
                        item.Transition.Easing = easing;
                    }
                }
                channel.LoadBG(item);
                channel.Play(item.VideoLayer);
                return(true);
            }
            match = RegexCg.Match(command);
            if (match.Success)
            {
                VideoLayer layer = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                if (Enum.TryParse(match.Groups["method"].Value, true, out TemplateMethod methodEnum))
                {
                    if (methodEnum == TemplateMethod.Clear)
                    {
                        channel.CG.Clear((int)layer);
                        return(true);
                    }
                    var matchWithCgLayer = RegexCgWithLayer.Match(command);
                    if (!matchWithCgLayer.Success || !int.TryParse(matchWithCgLayer.Groups["cg_layer"].Value, out var cgLayer))
                    {
                        return(false);
                    }
                    switch (methodEnum)
                    {
                    case TemplateMethod.Play:
                        channel.CG.Play((int)layer, cgLayer);
                        return(true);

                    case TemplateMethod.Next:
                        channel.CG.Next((int)layer, cgLayer);
                        return(true);

                    case TemplateMethod.Stop:
                        channel.CG.Stop((int)layer, cgLayer);
                        return(true);

                    case TemplateMethod.Remove:
                        channel.CG.Remove((int)layer, cgLayer);
                        return(true);

                    case TemplateMethod.Add:
                        var matchAdd = RegexCgAdd.Match(command);
                        if (!matchAdd.Success)
                        {
                            return(false);
                        }
                        var file = matchAdd.Groups["file"].Value;
                        if (string.IsNullOrWhiteSpace(file))
                        {
                            return(false);
                        }
                        int.TryParse(matchAdd.Groups["play_on_load"].Value, out var playOnLoadAsInt);
                        channel.CG.Add((int)layer, cgLayer, file, playOnLoadAsInt == 1,
                                       matchAdd.Groups["data"].Value);
                        return(true);

                    case TemplateMethod.Invoke:
                        var matchInvoke = RegexCgInvoke.Match(command);
                        if (!matchInvoke.Success)
                        {
                            return(false);
                        }
                        var cgMethod = matchInvoke.Groups["cg_method"].Value;
                        if (string.IsNullOrWhiteSpace(cgMethod))
                        {
                            return(false);
                        }
                        channel.CG.Invoke((int)layer, cgLayer, cgMethod);
                        return(true);

                    case TemplateMethod.Update:
                        var matchUpdate = RegexCgUpdate.Match(command);
                        if (!matchUpdate.Success)
                        {
                            return(false);
                        }
                        var data = matchUpdate.Groups["data"].Value;
                        if (string.IsNullOrWhiteSpace(data))
                        {
                            return(false);
                        }
                        channel.CG.Update((int)layer, cgLayer, data);
                        return(true);
                    }
                }
            }
            return(false);
        }
        public bool Execute(string command)
        {
            var channel = _casparChannel;

            if (string.IsNullOrWhiteSpace(command) || !CheckConnected(channel))
            {
                return(false);
            }
            Match match = EventExtensions.RegexMixerFill.Match(command);

            if (match.Success)
            {
                VideoLayer layer    = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                float      x        = float.Parse(match.Groups["x"].Value, CultureInfo.InvariantCulture);
                float      y        = float.Parse(match.Groups["y"].Value, CultureInfo.InvariantCulture);
                float      sx       = float.Parse(match.Groups["sx"].Value, CultureInfo.InvariantCulture);
                float      sy       = float.Parse(match.Groups["sy"].Value, CultureInfo.InvariantCulture);
                int        duration = string.IsNullOrWhiteSpace(match.Groups["duration"].Value) ? 0 : int.Parse(match.Groups["duration"].Value);
                TEasing    easing   = match.Groups["easing"].Success ? (TEasing)Enum.Parse(typeof(TEasing), match.Groups["easing"].Value, true) : TEasing.Linear;
                channel.Fill((int)layer, x, y, sx, sy, duration, (Easing)easing);
                return(true);
            }
            match = EventExtensions.RegexMixerClip.Match(command);
            if (match.Success)
            {
                VideoLayer layer    = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                float      x        = float.Parse(match.Groups["x"].Value, CultureInfo.InvariantCulture);
                float      y        = float.Parse(match.Groups["y"].Value, CultureInfo.InvariantCulture);
                float      sx       = float.Parse(match.Groups["sx"].Value, CultureInfo.InvariantCulture);
                float      sy       = float.Parse(match.Groups["sy"].Value, CultureInfo.InvariantCulture);
                int        duration = string.IsNullOrWhiteSpace(match.Groups["duration"].Value) ? 0 : int.Parse(match.Groups["duration"].Value);
                TEasing    easing   = match.Groups["easing"].Success ? (TEasing)Enum.Parse(typeof(TEasing), match.Groups["easing"].Value, true) : TEasing.Linear;
                channel.Clip((int)layer, x, y, sx, sy, duration, (Easing)easing);
                return(true);
            }
            match = EventExtensions.RegexClearMixer.Match(command);
            if (match.Success)
            {
                VideoLayer layer = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                channel.ClearMixer((int)layer);
                return(true);
            }
            match = EventExtensions.RegexPlay.Match(command);
            if (match.Success)
            {
                VideoLayer     layer = (VideoLayer)Enum.Parse(typeof(VideoLayer), match.Groups["layer"].Value, true);
                string         file  = match.Groups["file"].Value;
                CasparItem     item  = new CasparItem((int)layer, file);
                Capture        transitionTypeCapture     = match.Groups["transition_type"];
                Capture        transitionDurationCapture = match.Groups["transition_duration"];
                Capture        transitionEasingCapture   = match.Groups["easing"];
                int            transitionDuration;
                TransitionType transitionType;
                if (int.TryParse(transitionDurationCapture.Value, out transitionDuration) && Enum.TryParse(transitionTypeCapture.Value, true, out transitionType))
                {
                    item.Transition.Type     = transitionType;
                    item.Transition.Duration = transitionDuration;
                    Easing easing;
                    if (Enum.TryParse(transitionEasingCapture.Value, true, out easing))
                    {
                        item.Transition.Easing = easing;
                    }
                }
                channel.LoadBG(item);
                channel.Play(item.VideoLayer);
                return(true);
            }
            return(false);
        }