Skip to content

Commit

Permalink
fix: MediaPlayerElement does not play a local source
Browse files Browse the repository at this point in the history
  • Loading branch information
agneszitte committed Jun 27, 2023
1 parent 36c4145 commit 25e3d33
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 20 deletions.
76 changes: 64 additions & 12 deletions src/AddIns/Uno.UI.MediaPlayer.Skia.Gtk/GTKMediaPlayer.events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Uno.Helpers;
using System.IO;

namespace Uno.UI.Media;

Expand All @@ -30,6 +32,9 @@ public partial class GtkMediaPlayer
public event EventHandler<object?>? OnVideoRatioChanged;

private bool _updateVideoSizeOnFirstTimeStamp = true;
private bool _isParsedLocalFile;

const string MsAppXScheme = "ms-appx";

private async Task Initialize()
{
Expand Down Expand Up @@ -289,31 +294,78 @@ private static void OnSourceChanged(DependencyObject source, DependencyPropertyC
{
if (source is GtkMediaPlayer player && args.NewValue is string encodedSource)
{
player._updateVideoSizeOnFirstTimeStamp = true;

if (typeof(GtkMediaPlayer).Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
player.SetSource(encodedSource);
}
else
{
if (typeof(GtkMediaPlayer).Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error))
{
typeof(GtkMediaPlayer).Log().Debug($"Using source {encodedSource}");
typeof(GtkMediaPlayer).Log().Error($"Invalid source [{args.NewValue}]");
}
}
}

private void SetSource(string encodedSource)
{
_updateVideoSizeOnFirstTimeStamp = true;
_isParsedLocalFile = false;

if (typeof(GtkMediaPlayer).Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
typeof(GtkMediaPlayer).Log().Debug($"Using source {encodedSource}");
}

if (Uri.TryCreate(encodedSource, UriKind.RelativeOrAbsolute, out var sourceUri))
if (Uri.TryCreate(encodedSource, UriKind.RelativeOrAbsolute, out var sourceUri))
{
if (!sourceUri.IsAbsoluteUri || sourceUri.Scheme == "")
{
player._mediaPath = sourceUri;
player.UpdateMedia();
sourceUri = new Uri(MsAppXScheme + ":///" + sourceUri.OriginalString.TrimStart(new char[] { '/' }));
}
else

if (sourceUri.IsLocalResource())
{
if (typeof(GtkMediaPlayer).Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error))
var filePath = sourceUri.PathAndQuery;

if (sourceUri.Host is { Length: > 0 } host)
{
typeof(GtkMediaPlayer).Log().Error($"Unable to parse source [{args.NewValue}]");
filePath = host + "/" + filePath.TrimStart('/');
}

var originalLocalPath =
Path.Combine(Windows.ApplicationModel.Package.Current.InstalledPath,
filePath.TrimStart('/').Replace('/', global::System.IO.Path.DirectorySeparatorChar)
);
_isParsedLocalFile = true;
_mediaPath = new Uri(originalLocalPath);
UpdateMedia();
return;
}

if (sourceUri.IsAppData())
{
var filePath = AppDataUriEvaluator.ToPath(sourceUri);
_mediaPath = new Uri(filePath);
_isParsedLocalFile = true;
UpdateMedia();
return;
}

if (sourceUri.IsFile)
{
_mediaPath = sourceUri;
_isParsedLocalFile = true;
UpdateMedia();
return;
}

_mediaPath = sourceUri;
UpdateMedia();
}
else
{
if (typeof(GtkMediaPlayer).Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error))
{
typeof(GtkMediaPlayer).Log().Error($"Invalid source [{args.NewValue}]");
typeof(GtkMediaPlayer).Log().Error($"Unable to parse source [{encodedSource}]");
}
}
}
Expand All @@ -325,7 +377,7 @@ private void UpdateMedia()
string[] options = new string[1];
var media = new LibVLCSharp.Shared.Media(_libvlc, _mediaPath, options);

media.Parse(MediaParseOptions.ParseNetwork);
media.Parse(_isParsedLocalFile ? MediaParseOptions.ParseLocal : MediaParseOptions.ParseNetwork);
_mediaPlayer.Media = media;
AddMediaEvents();
Duration = (double)(_videoView?.MediaPlayer?.Media?.Duration / 1000 ?? 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Uno.Media.Playback;
using Windows.Foundation;
using Windows.Media.Playback;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
Expand All @@ -19,6 +18,8 @@

#if HAS_UNO_WINUI
using Microsoft.UI;
#else
using Windows.UI;
#endif

[assembly: ApiExtension(typeof(IMediaPlayerPresenterExtension), typeof(Uno.UI.Media.MediaPlayerPresenterExtension))]
Expand Down
31 changes: 31 additions & 0 deletions src/AddIns/Uno.UI.MediaPlayer.WebAssembly/MediaPlayerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using Uno.Foundation.Extensibility;
using Uno.Foundation.Logging;
using Uno.Media.Playback;
using Windows.Foundation;
using Windows.Media.Core;
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.Helpers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Uno.Extensions;
using Uno.Helpers;

[assembly: ApiExtension(typeof(IMediaPlayerExtension), typeof(Uno.UI.Media.MediaPlayerExtension))]

Expand All @@ -32,6 +37,8 @@ public partial class MediaPlayerExtension : IMediaPlayerExtension
private Uri? _uri;
private bool _anonymousCors = FeatureConfiguration.AnonymousCorsDefault;

const string MsAppXScheme = "ms-appx";

public MediaPlayerExtension(object owner)
{
if (owner is MediaPlayer player)
Expand Down Expand Up @@ -322,6 +329,30 @@ private void ApplyVideoSource()

if (_player is not null && _uri is not null)
{
if (!_uri.IsAbsoluteUri || _uri.Scheme == "")
{
_uri = new Uri(MsAppXScheme + ":///" + _uri.OriginalString.TrimStart(new char[] { '/' }));
}

if (_uri.IsLocalResource())
{
_player.Source = AssetsPathBuilder.BuildAssetUri(_uri?.PathAndQuery);
return;
}

if (_uri.IsAppData())
{
var filePath = AppDataUriEvaluator.ToPath(_uri);
_player.Source = filePath;
return;
}

if (_uri.IsFile)
{
_player.Source = _uri.OriginalString;
return;
}

_player.Source = _uri.OriginalString;
}
else
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
20 changes: 19 additions & 1 deletion src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -3310,6 +3310,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\MediaPlayerElement\MediaPlayerElement_Original_MsAppxSource.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\MediaPlayerElement\MediaPlayerElement_Original_MsAppdataSource.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Popup\MessageDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -5462,7 +5470,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_Devices\LightSensorTests.xaml.cs">
<DependentUpon>LightSensorTests.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_Devices\ProximitySensorTests.xaml.cs">
<Compile Include="$(MSBuildThisFileDirectory)Windows_Devices\ProximitySensorTests.xaml.cs">
<DependentUpon>ProximitySensorTests.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_Devices\MagnetometerTests.xaml.cs">
Expand Down Expand Up @@ -7166,6 +7174,12 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\MediaPlayerElement\MediaPlayerElement_Original.xaml.cs">
<DependentUpon>MediaPlayerElement_Original.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\MediaPlayerElement\MediaPlayerElement_Original_MsAppxSource.xaml.cs">
<DependentUpon>MediaPlayerElement_Original_MsAppxSource.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\MediaPlayerElement\MediaPlayerElement_Original_MsAppdataSource.xaml.cs">
<DependentUpon>MediaPlayerElement_Original_MsAppdataSource.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\DatePicker\Models\DatePickerViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Models\DateTimePickerViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Models\ListViewWithFlipViewViewModel.cs" />
Expand Down Expand Up @@ -8992,8 +9006,12 @@
<Content Include="$(MSBuildThisFileDirectory)Assets\test_image_200_200.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\theme-dark\ThemeTestImage.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\theme-light\ThemeTestImage.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\Thumbnails\Getting_Started_with_Uno_Platform_for_Figma.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\UnoGalleryLogo_Dark.scale-100.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\UnoGalleryLogo_Light.scale-100.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\Videos\Getting_Started_with_Uno_Platform_for_Figma.mp4">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Asset_GetFileFromApplicationUriAsync.xml" />
<Content Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Media_Animation\BeginTime_MultipleAnimations_Expected.gif" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)EmbeddedResources\LockScreen.png" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<UserControl x:Class="UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Original_MsAppdataSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<Button x:Name="SelectVideoButton"
Click="SelectVideoButton_Click"
Content="Pick another video file"
Margin="0,0,0,10" />

<MediaPlayerElement x:Name="SelectedVideo"
Grid.Row="1"
AreTransportControlsEnabled="True"
AutoPlay="True"
Visibility="Collapsed" />
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.Graph;
using Uno.UI.Samples.Controls;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Core;
using Windows.Media.Playback;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement
{
[SampleControlInfo("MediaPlayerElement", "Original using a local ms-appdata source", ignoreInSnapshotTests: true, description: "Video using a local ms-appdata source for video and poster. At the moment media element cannot read content from the in-browser file system, so keep this test aside for WASM.", IsManualTest = true)]
public sealed partial class MediaPlayerElement_Original_MsAppdataSource : UserControl
{
public MediaPlayerElement_Original_MsAppdataSource()
{
this.InitializeComponent();
}

private async void SelectVideoButton_Click(object sender, RoutedEventArgs e)
{
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
var extension = Path.GetExtension(file.Name);
var fileName = Guid.NewGuid() + extension;
await file.CopyAsync(ApplicationData.Current.LocalFolder, fileName);
var uri = new Uri($"ms-appdata:///Local/{fileName}");
SelectedVideo.Source = MediaSource.CreateFromUri(uri);
SelectedVideo.Visibility = Visibility.Visible;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<UserControl x:Class="UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement.MediaPlayerElement_Original_MsAppxSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

<MediaPlayerElement Source="ms-appx:///Assets/Videos/Getting_Started_with_Uno_Platform_for_Figma.mp4"
PosterSource="ms-appx:///Assets/Thumbnails/Getting_Started_with_Uno_Platform_for_Figma.png"
AreTransportControlsEnabled="True"
AutoPlay="True" />
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Uno.UI.Samples.Controls;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace UITests.Shared.Windows_UI_Xaml_Controls.MediaPlayerElement
{
[SampleControlInfo("MediaPlayerElement", "Original using a local ms-appx source", ignoreInSnapshotTests: true, description: "Video using a local ms-appx source for video and poster")]
public sealed partial class MediaPlayerElement_Original_MsAppxSource : UserControl
{
public MediaPlayerElement_Original_MsAppxSource()
{
this.InitializeComponent();
}
}
}
2 changes: 1 addition & 1 deletion src/Uno.Foundation/Extensions/UriExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static string GetExtension(this Uri uri)
return String.Empty;
}

internal static bool IsAppData(this Uri uri)
public static bool IsAppData(this Uri uri)
{
if (uri is null)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Uno.UWP/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
[assembly: InternalsVisibleTo("Uno.UI.Composition")]
[assembly: InternalsVisibleTo("Uno.UI.Lottie")]
[assembly: InternalsVisibleTo("Uno.UI.Svg")]
[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.Skia.Gtk")]
[assembly: InternalsVisibleTo("Uno.UI.MediaPlayer.WebAssembly")]

[assembly: InternalsVisibleTo("SamplesApp")]
[assembly: InternalsVisibleTo("SamplesApp.Droid")]
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UWP/Media/Playback/MediaPlayer.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private void SetVideoSource(Uri uri)

if (uri.IsLocalResource())
{
var filename = global::System.IO.Path.GetFileName(uri.LocalPath);
var filename = uri.PathAndQuery.TrimStart(new[] { '/' });
var afd = Application.Context.Assets.OpenFd(filename);
_player.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length);
return;
Expand Down
8 changes: 4 additions & 4 deletions src/Uno.UWP/Media/Playback/MediaPlayer.iOSmacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,10 @@ private static NSUrl DecodeUri(Uri uri)

if (uri.IsLocalResource())
{
var file = uri.PathAndQuery.TrimStart(new[] { '/' });
var fileName = Path.GetFileNameWithoutExtension(file);
var fileExtension = Path.GetExtension(file)?.Replace(".", "");
return NSBundle.MainBundle.GetUrlForResource(fileName, fileExtension);
var filePath = uri.PathAndQuery.TrimStart(new[] { '/' })
// UWP supports backward slash in path for directory separators
.Replace("\\", "/");
return NSUrl.CreateFileUrl(filePath, relativeToUrl: null);
}

if (uri.IsAppData())
Expand Down

0 comments on commit 25e3d33

Please sign in to comment.