/// <summary>
        /// Стандартный конструктор
        /// </summary>
        /// <param name="parDepth">Глубина</param>
        /// <param name="parX">Координата X</param>
        /// <param name="parY">Координата Y</param>
        /// <param name="parStringToRender">Текстовая строка</param>
        /// <param name="parFont">Шрифт</param>
        /// <param name="parColor">Цвет</param>
        /// <param name="parScaleX">Масштабирование по X</param>
        /// <param name="parScaleY">Масштабирование по Y</param>
        /// <param name="parHAlign">Горизонтальное выравнивание</param>
        /// <param name="parVAlign">Вертикальное выравнивание</param>
        public RenderingString(double parDepth, double parX, double parY, string parStringToRender, SubassetDataFont parFont,
                               Color parColor, double parScaleX = 1.0, double parScaleY = 1.0, EHorizontalAlign parHAlign = EHorizontalAlign.Left,
                               EVerticalAlign parVAlign         = EVerticalAlign.Top)
        {
            LinkedList <SubassetDataSprite> usedSprites = parFont.GetSymbolsSprites(parStringToRender);

            SpritesToRender = new LinkedList <RenderingSprite>();

            double totalWidth  = 0;
            double totalHeight = 0;

            foreach (var usedSprite in usedSprites)
            {
                totalWidth += usedSprite.Width;
                if (usedSprite.Height > totalHeight)
                {
                    totalHeight = usedSprite.Height;
                }
            }

            X = OpenGlUtil.GetLeftXCoordBasedOnHorizontalAlign(parX, totalWidth, parHAlign, parScaleX);
            Y = OpenGlUtil.GetTopYCoordBasedOnVerticalAlign(parY, totalHeight, parVAlign, parScaleY);

            totalWidth = 0;
            //totalHeight = 0;
            foreach (var usedSprite in usedSprites)
            {
                SpritesToRender.AddLast(new RenderingSprite(usedSprite, X + totalWidth, Y, 0, parColor,
                                                            parDepth, parScaleX, parScaleY, EHorizontalAlign.Left, EVerticalAlign.Top));

                totalWidth += usedSprite.Width * parScaleX;
            }

            Depth = parDepth;
        }
        /// <summary>
        /// Стандартный конструктор
        /// </summary>
        /// <param name="parSprite">Производный ассет спрайта</param>
        /// <param name="parX">Координата X</param>
        /// <param name="parY">Координата Y</param>
        /// <param name="parRotationDegrees">Поворот в градусах</param>
        /// <param name="parBlendColor">Цвет</param>
        /// <param name="parDepth">Глубина</param>
        /// <param name="parScaleX">Масштабирование по X</param>
        /// <param name="parScaleY">Масштабирование по Y</param>
        /// <param name="parHAlign">Горизонтальное выравнивание</param>
        /// <param name="parVAlign">Вертикальное выравнивание</param>
        /// <param name="parRotationPivotX">Точка опоры для поворота, координата X</param>
        /// <param name="parRotationPivotY">Точка опоры для поворота, координата Y</param>
        public RenderingSprite(SubassetDataSprite parSprite, double parX, double parY, double parRotationDegrees, Color parBlendColor,
                               double parDepth,
                               double parScaleX         = 1.0, double parScaleY = 1.0, EHorizontalAlign parHAlign = EHorizontalAlign.Left,
                               EVerticalAlign parVAlign = EVerticalAlign.Top, double parRotationPivotX = 0, double parRotationPivotY = 0)
        {
            Sprite = parSprite;

            X = OpenGlUtil.GetLeftXCoordBasedOnHorizontalAlign(parX, parSprite.Width, parHAlign, parScaleX);
            Y = OpenGlUtil.GetTopYCoordBasedOnVerticalAlign(parY, parSprite.Height, parVAlign, parScaleY);

            Depth           = parDepth;
            RotationDegrees = parRotationDegrees;
            BlendColor      = parBlendColor;
            ScaleX          = parScaleX;
            ScaleY          = parScaleY;
            PivotX          = parRotationPivotX;
            PivotY          = parRotationPivotY;
        }
Esempio n. 3
0
            public string Save(string videoName, string overlayTextMarking, EHorizontalAlign markingHorizontalAlign, EVerticalAlign markingVerticalAlign, double?durationMini = null)
            {
                this.TraceDebug($"Saving video \"{videoName}\" in buffer");

                var videoFileName = $"{videoName}.mpeg";

                var exeFilePath = Path.Combine(
                    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                    @"Video\",
                    Environment.Is64BitOperatingSystem ? "videosplitter-64.exe" : "videosplitter-32.exe");
                var fontFilePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                                                @"Video\", "arial.ttf");
                var textFilePath = Path.GetTempFileName();

                if (!string.IsNullOrWhiteSpace(overlayTextMarking))
                {
                    using (var stream = File.OpenWrite(textFilePath))
                        using (var writer = new StreamWriter(stream, new UTF8Encoding(false)))
                        {
                            writer.Write(overlayTextMarking.Replace(@"\", @"\\"));
                        }
                }

                string markingAlignment = string.Empty;

                switch (markingHorizontalAlign)
                {
                case EHorizontalAlign.Center:
                    markingAlignment = $"x=(w-tw)/2";
                    break;

                case EHorizontalAlign.Left:
                    markingAlignment = $"x={_MARKING_PADDING}";
                    break;

                case EHorizontalAlign.Right:
                    markingAlignment = $"x=w-tw-{_MARKING_PADDING}";
                    break;
                }

                switch (markingVerticalAlign)
                {
                case EVerticalAlign.Bottom:
                    markingAlignment += $":y=h-th-{_MARKING_PADDING}";
                    break;

                case EVerticalAlign.Center:
                    markingAlignment += $":y=(h-th)/2";
                    break;

                case EVerticalAlign.Top:
                    markingAlignment += $":y={_MARKING_PADDING}";
                    break;
                }

                double speed      = 1;
                bool   slowMotion = false;

                if (durationMini != null && Duration.TotalSeconds < durationMini)
                {
                    slowMotion = true;
                    speed      = Duration.TotalMilliseconds / (durationMini.Value * 1000);
                }
                List <string> filters = new List <string>();

                if (slowMotion)
                {
                    filters.Add($"setpts=(1/{speed.ToString().Replace(',', '.')})*PTS");
                }
                if (!string.IsNullOrWhiteSpace(overlayTextMarking))
                {
                    string formattedFontFilePath = fontFilePath.Replace(@"\", @"\\").Replace(":", @"\:");
                    string formattedtextFilePath = textFilePath.Replace(@"\", @"\\").Replace(":", @"\:");
                    filters.Add($"drawtext=fontfile='{formattedFontFilePath}':textfile='{formattedtextFilePath}':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:{markingAlignment}");
                }

                var processArgumentsBuilder = new StringBuilder("-y -nostdin");

                processArgumentsBuilder.Append($" -ss {From.ToString(@"hh\:mm\:ss")}.{From.Milliseconds}");
                processArgumentsBuilder.Append($" -t {Duration.ToString(@"hh\:mm\:ss")}.{Math.Max(Duration.Milliseconds, 200)}");
                processArgumentsBuilder.Append($" -i \"{_input}\"");
                if (filters.Count > 0)
                {
                    if (slowMotion)
                    {
                        processArgumentsBuilder.Append(" -an");
                    }
                    processArgumentsBuilder.Append($" -vf \"{string.Join(",", filters)}\"");
                }
                processArgumentsBuilder.Append($" -vcodec mpeg1video -b:v 4000k \"{videoFileName}\"");

                using (var process = new Process())
                {
                    process.StartInfo.FileName               = exeFilePath;
                    process.StartInfo.Arguments              = processArgumentsBuilder.ToString();
                    process.StartInfo.CreateNoWindow         = true;
                    process.StartInfo.UseShellExecute        = false;
                    process.StartInfo.RedirectStandardError  = true;
                    process.StartInfo.RedirectStandardOutput = true;

                    this.TraceDebug($"{exeFilePath} {processArgumentsBuilder}");

                    try
                    {
                        string errorOutput    = null;
                        string standardOutput = null;

                        process.Start();

                        var outputStreamTasks = new[]
                        {
                            Task.Factory.StartNew(() => errorOutput    = process.StandardError.ReadToEnd()),
                            Task.Factory.StartNew(() => standardOutput = process.StandardOutput.ReadToEnd())
                        };

                        var timeout = TimeSpan.FromMinutes(3); // TODO add to configuration
                        process.WaitForExit((int)timeout.TotalMilliseconds);
                        Task.WaitAll(outputStreamTasks, (int)timeout.TotalMilliseconds, KprocessExportWindow.CancellationToken);

                        this.TraceDebug(standardOutput);
                        Debug.WriteLine(standardOutput);

                        if (!string.IsNullOrWhiteSpace(errorOutput))
                        {
                            this.TraceError("Des erreurs ont été levées par le processus permettant de splitter les videos:");
                            this.TraceError(errorOutput);
                            Debug.WriteLine(errorOutput);
                        }
                    }
                    catch (Win32Exception e)
                    {
                        this.TraceError(e, "Le splitter de video n'a pas été trouvé");
                        throw new Exception("An issue has occured during video packaging. It seems that some components are missing.", e);
                    }
                    catch (OperationCanceledException e)
                    {
                        this.TraceError(e, "L'export a été annulé lors du split des vidéos");
                        throw;
                    }
                    catch (Exception e)
                    {
                        this.TraceError(e, "Une erreur non prévue s'est produite lors du split de la video");
                        throw;
                    }
                    finally
                    {
                        try
                        {
                            File.Delete(textFilePath);
                        }
                        catch { }
                    }
                }

                return(videoName);
            }
Esempio n. 4
0
        /// <summary>
        /// Получить координату Y в пространстве OpenGL с учетом выбранного вертикального выравнивания
        /// </summary>
        /// <param name="parY">Y в обычной системе координат</param>
        /// <param name="parHeight">Высота</param>
        /// <param name="parVAlign">Выбранное вертикальное выравнивание</param>
        /// <param name="parScale">Величина масштабирования</param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException">Неподдерживаемый формат выравнивания</exception>
        public static double GetTopYCoordBasedOnVerticalAlign(double parY, double parHeight, EVerticalAlign parVAlign,
                                                              double parScale)
        {
            switch (parVAlign)
            {
            case EVerticalAlign.Top:
                return(parY);

                break;

            case EVerticalAlign.Middle:
                return(parY - (parHeight * parScale / 2));

                break;

            case EVerticalAlign.Bottom:
                return(parY - (parHeight * parScale));

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(parVAlign), parVAlign, null);
            }
        }
Esempio n. 5
0
                public static void VerticalOrganizer(Transform transform, float spacing = .1f, EVerticalAlign align = EVerticalAlign.Center, bool countInactive = true, List <Transform> ignoreds = null)
                {
                    var count     = transform.childCount;
                    var totalSize = 0f;
                    var realCount = 0;

                    while (count > _sizesCache.Count)
                    {
                        _sizesCache.Add(0);
                    }
                    while (count > _offsetCache.Count)
                    {
                        _offsetCache.Add(0);
                    }

                    var scale = transform.lossyScale.y;

                    spacing *= scale;

                    for (int i = 0; i < count; i++)
                    {
                        var child = transform.GetChild(i);
                        if (!countInactive && !child.gameObject.activeInHierarchy)
                        {
                            continue;
                        }

                        realCount++;

                        var  min     = float.MaxValue;
                        var  max     = float.MinValue;
                        bool visible = false;

                        foreach (var rend in child.GetComponentsInChildren <Renderer>())
                        {
                            if (ChildOfSomeTransform(rend, ignoreds))
                            {
                                continue;
                            }

                            var bounds = rend.bounds;
                            min     = Mathf.Min(min, bounds.min.y);
                            max     = Mathf.Max(max, bounds.max.y);
                            visible = true;
                        }

                        var size = visible ? (max - min) : 0f;

                        _sizesCache[i]  = size;
                        _offsetCache[i] = visible ? (child.position.y - min) : 0;

                        totalSize += size;
                    }

                    for (int i = 0; i < count; i++)
                    {
                        var child = transform.GetChild(i);
                        if (!countInactive && !child.gameObject.activeInHierarchy)
                        {
                            continue;
                        }
                        var pos = child.localPosition;
                        pos.x = 0;
                        child.localPosition = pos;
                    }

                    totalSize += (realCount - 1) * spacing;
                    var hs = totalSize / 2;
                    var it = -hs;

                    switch (align)
                    {
                    case EVerticalAlign.Top: it = -totalSize; break;

                    case EVerticalAlign.Center: it = -hs; break;

                    case EVerticalAlign.Bottom: it = 0; break;
                    }

                    for (int i = count - 1; i >= 0; i--)
                    {
                        var child = transform.GetChild(i);

                        if (!countInactive && !child.gameObject.activeInHierarchy)
                        {
                            continue;
                        }

                        var pos = child.localPosition;
                        pos.y = (it + _offsetCache[i]) / scale;
                        child.localPosition = pos;
                        it += _sizesCache[i] + spacing;
                    }
                }