LottieSharp icon indicating copy to clipboard operation
LottieSharp copied to clipboard

Enable Animation over RDP

Open FG-rgb opened this issue 3 years ago • 16 comments

I have a short question: Is it possible to enable animation in case of Remote Desktop Connection is used? Actually I see animations only in case of native Windows Session, but not over a RDP Session.

FG-rgb avatar May 19 '21 07:05 FG-rgb

Hello, @FG-rgb Already solved this bug. Are you sure that you using the latest version? If yes can you please describe your bug more? And do you see some error or log?

OmidID avatar May 19 '21 11:05 OmidID

Hello @OmidID . I'm using LottieSharp NuGet Package V1.1.3 (latest).

My code looks like follow:

<lottieSharp:LottieAnimationView DefaultCacheStrategy="None"
                                         FileName="Gears.json"
                                         AutoPlay="True"
                                         FrameRate="30"
                                         VerticalAlignment="Center"
                                         HorizontalAlignment="Center" />

When I run my .NET Core 3.1 Application on my Windows 10 X64 Developer PC via Remote Desktop, I only see a static image (I think it is the first frame of the animation).

When I run it on another Windows 10 X64 PC (native) the animation runs as expected.

FG-rgb avatar May 19 '21 16:05 FG-rgb

The Console output looks like follow:

'LottieWpf.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Private.CoreLib.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\LottieWpf.dll'. Symbols loaded. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\PresentationFramework.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\WindowsBase.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Runtime.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\System.Xaml.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Remote Debugger\x64\Runtime\Microsoft.VisualStudio.Debugger.Runtime.NetCoreApp.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Runtime.InteropServices.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Threading.ThreadPool.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\System.IO.Packaging.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Collections.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Diagnostics.TraceSource.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\netstandard.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Private.Uri.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Text.RegularExpressions.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\PresentationCore.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\mscorlib.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Runtime.Extensions.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Threading.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\DirectWriteForwarder.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Runtime.CompilerServices.VisualC.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Buffers.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Diagnostics.Debug.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\Microsoft.Win32.Primitives.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Collections.NonGeneric.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Linq.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\Microsoft.Win32.Registry.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Collections.Specialized.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.ComponentModel.Primitives.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Diagnostics.Process.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Threading.Thread.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\System.Configuration.ConfigurationManager.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Xml.ReaderWriter.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Private.Xml.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.IO.FileSystem.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Net.WebClient.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Memory.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Security.Cryptography.Algorithms.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Text.Encoding.Extensions.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Threading.Tasks.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.ComponentModel.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Resources.ResourceManager.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.ComponentModel.TypeConverter.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\System.Windows.Extensions.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Collections.Concurrent.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.ObjectModel.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\UIAutomationTypes.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\LottieSharp.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.Mathematics.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.Direct2D1.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Reflection.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\DotNetZip.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\Newtonsoft.Json.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.IO.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Globalization.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.15\System.Threading.Timer.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\PresentationFramework.Aero2.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.15\UIAutomationProvider.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.Direct3D11.dll'. 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.DXGI.dll'. Exception thrown: 'SharpDX.SharpDXException' in SharpDX.dll Exception thrown: 'SharpDX.SharpDXException' in SharpDX.dll Exception thrown: 'SharpDX.SharpDXException' in SharpDX.dll Exception thrown: 'SharpDX.SharpDXException' in SharpDX.dll Exception thrown: 'SharpDX.SharpDXException' in SharpDX.dll 'LottieWpf.exe' (CoreCLR: clrhost): Loaded 'C:\Work\LottieWpf\LottieWpf\bin\Debug\netcoreapp3.1\SharpDX.Direct3D9.dll'.

FG-rgb avatar May 19 '21 16:05 FG-rgb

Any news on that? Do you need any additional info?

FG-rgb avatar May 27 '21 09:05 FG-rgb

What is the detailed problem here, I would try to fix it, but I have no Idea how to do that. In D2dControl I see that TryCreateDevice fails with DriverType.Software and is success with DriverType.Hardware. I also get an event OnIsFrontBufferAvailableChanged where d3DSurface.IsFrontBufferAvailable == false.

due to https://stackoverflow.com/questions/56849171/direct2d-with-wpf-over-rdp I tried to NOT call StopRendering() but this doesn't help.

Any suggestions here?

FG-rgb avatar Jul 13 '21 10:07 FG-rgb

Ahhh, I found a solution for case of Remote Desktop.

In D2dControl I changed code:

private void OnIsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (d3DSurface.IsFrontBufferAvailable)
            {
                StartD3D();
                StartRendering();
            }
            else
            {
                EndD3D();
                StopRendering();

                StartD3D();
                StartRendering();
            }
        }

This solves my problem!

FG-rgb avatar Jul 13 '21 10:07 FG-rgb

Ok, this leads to a MemoryLeak....

because this event is called many times...

FG-rgb avatar Jul 13 '21 10:07 FG-rgb

This Library seem to be dead...

FG-rgb avatar Jul 19 '21 08:07 FG-rgb

I managed to use LottieSkia with WPF, in combination with WritableBitmap as Source of an Image Control. This works like a sharm.

FG-rgb avatar Aug 03 '21 11:08 FG-rgb

@FG-rgb Hello, can you share an example of LottieSkia?

saklanmazozgur avatar Sep 30 '21 05:09 saklanmazozgur

@saklanmazozgur Here is an example I used in my prototype. It's a WPF project based on .Net Framework 4.7.2. You need the NuGet Package SkiaSharp, and it's dependencies.

My Examle code (MainWindow.xaml): <Window x:Class="SkiaSharpNet.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SkiaSharpNet" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Image x:Name="MyImage" Width="100" Height="100" Stretch="Fill" /> </Grid> </Window>

And the code behind (MainWindow.xaml.cs):

`using LottieSharp; using SkiaSharp; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging;

namespace SkiaSharpNet { public partial class MainWindow : Window { LottieDrawable _lottieDrawable; WriteableBitmap _writeableBitmap; SKSurface _surface;

    private Int32Rect _int32Rect;

    public MainWindow()
    {
        InitializeComponent();

        var width = (int)MyImage.Width;
        var height = (int)MyImage.Height;

        _int32Rect = new Int32Rect(0, 0, width, height);

        _writeableBitmap = new WriteableBitmap(width, height, 96.0, 96.0, PixelFormats.Bgra32, BitmapPalettes.Halftone256Transparent);
        _surface = SKSurface.Create(new SKImageInfo(width, height, SKColorType.Bgra8888, SKAlphaType.Premul), pixels: _writeableBitmap.BackBuffer, rowBytes: width * 4);


        InitLottie();

        MyImage.Source = _writeableBitmap;

        Unloaded += MainWindow_Unloaded;
    }

    private void MainWindow_Unloaded(object sender, RoutedEventArgs e)
    {
        _lottieDrawable.Stop();
        _lottieDrawable.Dispose();
    }

    private void InitLottie()
    {
        _lottieDrawable = new LottieDrawable();
        var result = LottieCompositionFactory.FromAssetSync("gears.json");

        _lottieDrawable.SetComposition(result.Value);
        //_lottieDrawable.FrameRate = 25;
        _lottieDrawable.RepeatCount = -1;
        _lottieDrawable.RecycleBitmaps();
        _lottieDrawable.RepeatMode = RepeatMode.Restart;
        _lottieDrawable.AnimatorUpdate += Drawable_AnimatorUpdate;
        _lottieDrawable.Start();
    }

    private void Drawable_AnimatorUpdate(object sender, ValueAnimator.ValueAnimatorUpdateEventArgs e)
    {
        _writeableBitmap.Dispatcher.Invoke(() =>
        {
            bool isLocked = false;

            try
            {
                _writeableBitmap.Lock();
                isLocked = true;

                // Clear old drawing.
                _surface.Canvas.Clear();

                _lottieDrawable.Draw(_surface);
                _writeableBitmap.AddDirtyRect(_int32Rect);
            }
            finally
            {
                if (isLocked)
                {
                    _writeableBitmap.Unlock();
                }
            }
        });
    }
}

} `

I use a WritableBitmap, to reuse the image, and reduce memory usage. To load your custom lottie, you need to change "gears.json". That is an example lottie file.

FG-rgb avatar Sep 30 '21 08:09 FG-rgb

Ahhh, I have found your Problem: I downloaded the project LottieSkiaSharp and ported it to .NET 4.7.2...

FG-rgb avatar Sep 30 '21 10:09 FG-rgb

I'm new to these issues, can you help me on how to migrate?

saklanmazozgur avatar Sep 30 '21 10:09 saklanmazozgur

Actually I'm using my approach with .NET Core, therefore the NuGet Package is compatible.

If you want to use this example in production I think the best idea is to ask the Author of LottieSkiaSharp to make it compatible, or create a fork of this repository (I've never done that).

For test purpose you can do the following:

You need to go to the Project site: https://github.com/yinyue200/LottieSkiaSharp Then choose the latest Version: image

Then download it: image

Now you can add this project as additional project to your solution and change the "Target framework" in the project properties.

FG-rgb avatar Sep 30 '21 10:09 FG-rgb

Note: You have to respect the license condition of LottieSkiaSharp!

FG-rgb avatar Sep 30 '21 10:09 FG-rgb

Thanks for your help. I wish you good work. :+1:

saklanmazozgur avatar Sep 30 '21 10:09 saklanmazozgur