JackM
Topic Author
Posts: 15
Joined: 18 Feb 2022, 11:46

Unity - Issues with Android devices playing videos

21 Jan 2025, 17:30

Hey All,

We've recently implemented some demonstration videos for various troops and research items in our game (think clash of clans barracks etc.) and have now got the time to try and improve the performance. We weren't entirely sure where the issue is but wanted to check the implementation is correct. The videos are working flawlessly both in editor and on iOS but on some Android devices (specifically lower end ones) videos appear to be stuttering or not playing at all until the game is closed and then re-opened once. Which whilst is fairly minor is undesirable, especially as a first impression.

The way it has been implemented is to have a Control style that when passed a specific string will set the visibility of that specific MediaElement with the video to visible and hide the remainder. However the ideally preferred solution would be able to dynamically swap the source of a single media element for both code simplicity and performance that will (hopefully) allow the videos to work at run time regardless of device. Ideally these videos would autoplay and loop without user intervention.
<Style
    x:Key="TroopVideoDemo"
    TargetType="{x:Type Control}">
    <Setter
        Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <MediaElement
                        x:Name="PeasantVideoDemo"
                        Visibility="Collapsed"
                        IsMuted="True"
                        Source="/Assets/GUI/Videos/Troop Demos/Peasant.mp4"
                        Margin="8,5,10,10"
                        Stretch="Fill"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        LoadedBehavior="Manual">
                        <MediaElement.OpacityMask>
                            <ImageBrush
                                ImageSource="{StaticResource Misc Elements/Masks/video-mask-rounded-corners}" />
                        </MediaElement.OpacityMask>
                        <b:Interaction.Triggers>
                            <b:EventTrigger
                                EventName="Loaded">
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                            <b:EventTrigger
                                EventName="MediaEnded">
                                <noesis:StopMediaAction />
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                        </b:Interaction.Triggers>
                    </MediaElement>
                    <MediaElement
                        x:Name="ArcherVideoDemo"
                        Visibility="Collapsed"
                        IsMuted="True"
                        Source="/Assets/GUI/Videos/Troop Demos/Archer.mp4"
                        Margin="8,5,10,10"
                        Stretch="Fill"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        LoadedBehavior="Manual">
                        <MediaElement.OpacityMask>
                            <ImageBrush
                                ImageSource="{StaticResource Misc Elements/Masks/video-mask-rounded-corners}" />
                        </MediaElement.OpacityMask>
                        <b:Interaction.Triggers>
                            <b:EventTrigger
                                EventName="Loaded">
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                            <b:EventTrigger
                                EventName="MediaEnded">
                                <noesis:StopMediaAction />
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                        </b:Interaction.Triggers>
                    </MediaElement>
                    
                <ControlTemplate.Triggers>
                    <Trigger
                        Property="local:PropEx.VideoPath"
                        Value="TroopType_Peasant">
                        <Setter
                            TargetName="PeasantVideoDemo"
                            Property="Visibility"
                            Value="Visible"/>
                        <Setter
                            TargetName="ArcherVideoDemo"
                            Property="Visibility"
                            Value="Hidden" />
                    </Trigger>
                    <Trigger
                        Property="local:PropEx.VideoPath"
                        Value="TroopType_Archer">
                        <Setter
                            TargetName="PeasantVideoDemo"
                            Property="Visibility"
                            Value="Hidden" />
                        <Setter
                            TargetName="ArcherVideoDemo"
                            Property="Visibility"
                            Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Above is a small snippet, as you can imagine will become a maintenance nightmare so keen to have a different solution! Ideally the videos should be loaded on demand when a user selects a unit rather than having them all loaded at once and just showing/hiding as needed.

Here is an example of the implementation of the style, as you can see it's simply passed a bound string which then is handled by the style to make visible the correct video at run time using the above style.
<Grid
    x:Name="TroopVideoDemo"
    Grid.RowSpan="3"
    Grid.Column="4">
    <Control
        Style="{StaticResource TroopVideoDemo}"
        local:PropEx.VideoPath="{Binding BarracksContext.SelectedSquad.DisplayTroop.VideoPath}">
    </Control>
</Grid>
What we want to know is what is the better way of implementing MediaElements that can dynamically load videos on request at runtime in Noesis 3.2.5/tips to improve this current implementation?

Many thanks in advance,

Jack
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Unity - Issues with Android devices playing videos

24 Jan 2025, 10:22

Hello Jack,

Assuming your video assets are referenced in your scene (so they are packed in your game), you can just have a single MediaElement and change its Source property to play different videos.
I just tried this simple xaml, and just by typing the path to the video (like in /Assets/Videos/Dots.mp4) in the TextBox, it loads the referenced video and plays it:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <DockPanel>
    <StackPanel DockPanel.Dock="Top" Background="#222">
      <TextBox x:Name="src" Margin="20,20,20,5" Text="{Binding Source, ElementName=media, UpdateSourceTrigger=LostFocus}"/>
      <Button Content="Button" Margin="20,5,20,20"/>
    </StackPanel>
    <Border Background="Black">
      <MediaElement x:Name="media" Stretch="Uniform"/>
    </Border>
  </DockPanel>
</Grid>
You can have a similar Control template that binds the MediaElement.Source to that PropEx.VideoPath attached property, and then you can just have a single Control to handle all your videos.

Have you tried something like that?
 
JackM
Topic Author
Posts: 15
Joined: 18 Feb 2022, 11:46

Re: Unity - Issues with Android devices playing videos

27 Jan 2025, 11:06

Oh that is an interesting approach, I will certainly take a look into this now and report back with how it goes for us, thanks for the reply!
 
JackM
Topic Author
Posts: 15
Joined: 18 Feb 2022, 11:46

Re: Unity - Issues with Android devices playing videos

27 Jan 2025, 11:43

Okay so with the initial implementation of this it works fine, however we want to avoid any form of user text input, so I decided to (as suggested) bind a value to the media player source and this works initially however it doesn't loop. I decided to extend the example with the existing noesis implementation for a looping video, unfortunately this requires the LoadedBehaviour to be set to manual which then (as expected) does not auto play the video when the UI is first opened.

Below is the code being used, changing the currently displayed troop will also update the path but what we'd prefer is that the video loops when the UI is first opened but we're not sure how to go about listening to the appropriate event to do this. Is there a way to loop videos in this manner or is there a preferred approach for looping video within Noesis UI?
                <Grid
                    x:Name="TroopVideoDemo"
                    Grid.RowSpan="3"
                    Grid.Column="4">
                    <MediaElement
                        x:Name="DemoVideoPlayer"
                        Stretch="Uniform"
                        LoadedBehavior="Manual"
                        Source="{Binding BarracksContext.SelectedSquad.DisplayTroop.VideoPath}">
                        <MediaElement.OpacityMask>
                            <ImageBrush
                                ImageSource="{StaticResource Misc Elements/Masks/video-mask-rounded-corners}" />
                        </MediaElement.OpacityMask>
                        <b:Interaction.Triggers>
                            <b:EventTrigger
                                EventName="Loaded">
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                            <b:EventTrigger
                                EventName="MediaEnded">
                                <noesis:StopMediaAction />
                                <noesis:PlayMediaAction />
                            </b:EventTrigger>
                        </b:Interaction.Triggers>
                    </MediaElement>
                </Grid>
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Unity - Issues with Android devices playing videos

30 Jan 2025, 12:59

Hi, my sample can be changed so instead of playing on load, it reacts to changes of the MediaElement Source property and enables looping:
<MediaElement x:Name="media" Stretch="Uniform" LoadedBehavior="Manual">
  <b:Interaction.Triggers>
    <b:PropertyChangedTrigger Binding="{Binding Source, ElementName=media}">
      <noesis:PlayMediaAction/>
    </b:PropertyChangedTrigger>
    <b:EventTrigger EventName="MediaEnded">
      <noesis:StopMediaAction/>
      <noesis:PlayMediaAction/>
    </b:EventTrigger>
  </b:Interaction.Triggers>
</MediaElement>
Is this what you need?
 
JackM
Topic Author
Posts: 15
Joined: 18 Feb 2022, 11:46

Re: Unity - Issues with Android devices playing videos

31 Jan 2025, 17:41

Hey there,

That works like a charm thanks so much! I must admit my ignorance regarding the property changed trigger but this is certainly a game changer! Works flawlessly in the editor and just need to resolve some file path issues for Android/iOS but this is the perfect solution, thanks again.
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Unity - Issues with Android devices playing videos

04 Feb 2025, 11:27

Glad it worked!

Who is online

Users browsing this forum: No registered users and 6 guests