dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WPF MediaElement Source fails to load because of percent encoding

vsfeedback opened this issue · comments

This issue has been moved from a ticket on Developer Community.


[severity:Other]
Consider the following snippet;
var file1 = @"\192.168.0.1\videos\alarm 10 %.mp4";
var file2 = @"\192.168.0.1\videos\alarm 10 pct.mp4";
MediaElement.Source = new Uri(file1); // fails
MediaElement.Source = new Uri(file2); // works

With VS22 & .NET 4.8, file1 fails because the URI does not (cannot) escape the string properly. ie: the MediaElement reports the error as a file not found exception. Both, file1 and file2, naming patterns work if the files are located on a mapped drive. Having said that, this leads me to believe that this must be a bug since Windows media player does not share this problem. My understanding is that the MediaElement is a derivative control of the windows media player ... or vice versa.

Nothing i can do to the string has worked. i cannot even disable the percent encoding and perform the escaping myself. Furthermore, downloading the file before playing is not practical for many reasons. Nor is;

  • renaming the file remotely.
  • asking end users to rename all offending their files.
  • mapping network drives before use wrt their hives.

In the end, I wouldn't even know how to logically explain this issue at all.

Thank you
[Redacted]@[Redacted]

PS: do not hesitate to contact me if greater detail is required.


Original Comments

Feedback Bot on 4/19/2024, 11:04 AM:

(private comment, text removed)


Original Solutions

(no solutions)

Well one way to get this work is to use the Uri constructor with dontEscape: true.

Otherwise this is going into WMP SDK which seems unlikely to get fixed.

IFC(IsSupportedWmpReturn(m_pIWMPPlayer->put_URL(bstrUrl)));

/cc @MihaZupan Is there a non-deprecated way to create Uri without encoding the path? I am not quite sure how DangerousDisablePathAndQueryCanonicalization is safer than dontEscape, but it also disables canonicalization which would be undesirable (and breaks Uri.GetComponents() down the path).

// Uri-toString does 3 things over the standard .toString()
//
// 1) We don't unescape special control characters. The default Uri.ToString()
// will unescape a character like ctrl-g, or ctrl-h so the actual char is emitted.
// However it's considered safer to emit the escaped version.
//
// 2) We truncate urls so that they are always <= MAX_URL_LENGTH
//
// This method should be called whenever you are taking a Uri
// and performing a p-invoke on it.
//
internal static string UriToString(Uri uri)
{
ArgumentNullException.ThrowIfNull(uri);
return new StringBuilder(
uri.GetComponents(
uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString,
UriFormat.SafeUnescaped),
MAX_URL_LENGTH).ToString();
}

The low hanging fruit has all been picked clean. Please find attached project player which can be used to further investigate the issue. Thanx for assist in advance.
Player.zip

Thanks @Anonymous-X2. I was able to reproduce the issue originally. Unfortunately, WMP is considered legacy and won't get any fixes.

i cannot help but wonder if the URI object is at fault and the MediaElement is just exposing the issue.

I don't think so. The URI is encoded as it should, and returns unencoded local path as it should when appropriate (which is not in the repro case). It is passed as a string to the WMP SDK and whoever is resolving it into a file path should decode it.

i agree ... i see it now. ie: i reconfigured the Player project to use an Image control; attached as Photo.zip. In this case IM.Source = new BitmapImage(new Uri(Path)) is executed successfully.