I have an UWP app that has to play .avi files. The default media player doesn't play .avi files as far as I could find (?), so I decided to use the VLC.MediaElement. Unfortunately the code hasn't been updated for a year and issues are not getting addressed, so I hope stackoverflow can help me!
The UWP app contains a gallery of images and videos (using GridView). Once an item is clicked, it opens a section to play the video or show the image. The new section is an overlay, using z-index to make sure it is on top.
Inside GalleryView.xaml.cs
is the code to open the Media Box and play the video:
private const string FILE_TOKEN = "{1BBC4B94-BE33-4D79-A0CB-E5C6CDB9D107}"; // GUID in registry format
public async Task OpenMediaBox(MediaAssetModel item)
{
try
{
if (item != null)
{
ViewModel.SelectedAsset = item;
ViewModel.ShowMediaOverlay = true;
ViewModel.SelectedAssetIndex = IncrementalItems.IndexOf(item);
if (ViewModel.SelectedAssetIndex == 0)
{
btnLeft.IsEnabled = false;//left button in the media box to play the previous video
}
if (ViewModel.SelectedAssetIndex >= IncrementalItems.Count)
{
btnRight.IsEnabled = false;//right button in the mediabox to play the next video
}
if (item.FileType == FileTypeEnum.Video)
{
//first check for local file
if (!string.IsNullOrWhiteSpace(item.LocalFilePath) && !string.IsNullOrWhiteSpace(item.LocalFileName))
{
StorageFile file = await WindowsCredentialsService.GetMediaStorageFile(item);
if (file != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace(FILE_TOKEN, file);
VlcMediaPlayer.Source = null;
VlcMediaPlayer.Source = $"winrt://{FILE_TOKEN}";
//VlcMediaPlayer.MediaSource = VLC.MediaSource.CreateFromUri(file.Path);
VlcMediaPlayer.Visibility = Visibility.Visible;
}
else
{
//todo show error
}
}
else if (item.MediaAssetId != 0 && !string.IsNullOrWhiteSpace(item.StreamSmoothStreamingUrl))
{
//plays a file that is already uploaded and deleted locally, that is a .mp4 file so it uses the default media player.
MediaPlayer.Source = Windows.Media.Core.MediaSource.CreateFromUri(new Uri(item.StreamSmoothStreamingUrl));
MediaPlayer.Visibility = Visibility.Visible;
}
}
else if (item.FileType == FileTypeEnum.Image)
{
//not interesting for this issue
}
}
}
catch (Exception ex)
{
await _logService.WriteAsync(Core.Models.LogModel.LogLevelEnum.CRITICAL_ERROR, "GalleryView", "OpenMediaBox", ex);
}
}
So that all works well, on the first time...
When a user closes the media box and opens another video or clicks on the left or right button the play the previous/next video, this code is called:
private async void BtnRight_Click(object sender, RoutedEventArgs e)
{
var index = ViewModel.SelectedAssetIndex + 1;
if (index >= IncrementalItems.Count)
{
return;
}
try
{
var item = IncrementalItems[index];//IncrementalItems is a extended ObservableCollection
CloseMediaBox();
await OpenMediaBox(item);
}
catch (Exception)
{
return;
}
}
public void CloseMediaBox()
{
try
{
if (MediaPlayer != null && MediaPlayer.MediaPlayer != null && MediaPlayer.Source != null && MediaPlayer.MediaPlayer.PlaybackSession.CanPause)
{
MediaPlayer.MediaPlayer.Pause();
}
if (VlcMediaPlayer != null && VlcMediaPlayer.MediaPlayer != null && VlcMediaPlayer.MediaSource != null && VlcMediaPlayer.MediaPlayer.canPause())
{
VlcMediaPlayer.Pause();
//VlcMediaPlayer.Stop();
}
MediaPlayer.Source = null;
VlcMediaPlayer.Source = null;
//VlcMediaPlayer.MediaSource = null;
}
catch (Exception ex)
{
//throw;
}
MediaPlayer.Visibility = Visibility.Collapsed;
VlcMediaPlayer.Visibility = Visibility.Collapsed;
imgOverlay.Source = null;
ViewModel.ShowMediaOverlay = false;
ViewModel.SelectedAsset = null;
}
In the CloseMediaBox
I have a few things commented out, because they make the app crash, I've been doing my best to make sure there is no memory leak or whatever, it was quite a annoying debugging session for that to properly close it. I think this is part of the problem...
Problem: When the user now clicks on next/previous to play another video, the video is not being played while the timeline is moving forward. So a frozen image is shown while the video-player shows it is playing:
Pay attention to the numbers in the right-bottom corner, first this is increasing as it should, after clicking the button and playing again it is not. I've already disabled autoplay to perhaps help the buffer process.
There is some logging in the output that can give me info on why it is failing, it simply isn't done buffering, I have indicated the differences in the short version, the long version is available below where you can see it is loading all the symbols and such (but also initializes the VLC Media Player.
Good scenario:
main input debug: Buffering 75%
main input debug: Buffering 83%
main input debug: Buffering 91%
main input debug: Buffering 100%
main input debug: Stream buffering done (325 ms in 35 ms)
main vout display debug: VoutDisplayEvent 'resize' 840x540
direct3d11 vout display debug: Direct3D11 resources created
direct3d11 vout display debug: Direct3D11 device adapter successfully initialized
direct3d11 vout display debug: Direct3D11 Open Succeeded
main vout display debug: using vout display module "direct3d11"
Second video / bad scenario:
main input debug: Buffering 41%
main input debug: Buffering 50%
main input debug: Buffering 58%
main input debug: Buffering 66%
main vout display debug: VoutDisplayEvent 'resize' 840x540
direct3d11 vout display error: Failed to resize the backbuffer. (hr=0x887A0001)
direct3d11 vout display error: Could not update the backbuffer. (hr=0x887A0001)
direct3d11 vout display error: Failed to allocate resources
direct3d11 vout display debug: Direct3D11 resources destroyed
direct3d11 vout display error: Direct3D11 could not be opened
direct3d11 vout display debug: Direct3D11 resources destroyed
direct3d11 vout display debug: Direct3D11 device adapter closed
main vout display debug: no vout display modules matched
main video output error: video output creation failed
The thread 0x313c has exited with code 0 (0x0).
So how do I solve this issue?
Long log files can be found here:
User contributions licensed under CC BY-SA 3.0