question

SmilingMoon avatar image
0 Votes"
SmilingMoon asked SmilingMoon commented

Uwp MediaPlayerElement - How to release video file played from NAS to avoid "..being used by another process." error for the next update job?

Hello,
In UWP app, I want to play video and update the video file's property (Tags).
The following code works well for the C:\ local video file.
But, it throws error for video file from NAS (Network drive, I use synology): \\MyNAS\video\Test\20201125_032706.mp4

 MainPage.xaml
    
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="auto"></RowDefinition>
             <RowDefinition></RowDefinition>
         </Grid.RowDefinitions>
         <StackPanel Orientation="Horizontal" Grid.Row="0">
             <Button Content="Open" Click="OpenButton_Click"></Button>
             <Button Content="Close and Update" Click="CloseUpdateButton_Click"></Button>
         </StackPanel>
         <MediaPlayerElement x:Name="mpPlayer"                    
                     AutoPlay="False" 
                     AreTransportControlsEnabled="True"
                     Grid.Row="1"        
                             Stretch="Uniform"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Stretch"
                             >
         </MediaPlayerElement>
     </Grid>
    
    
     public sealed partial class MainPage : Page
     {
         public MainPage()
         {
             this.InitializeComponent();
    
             mpPlayer.MediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
             mpPlayer.MediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
             mpPlayer.MediaPlayer.CurrentStateChanged += MediaPlayer_CurrentStateChanged;
         }
         async void Log(string msg)
         {
             System.Diagnostics.Debug.WriteLine(msg);
         }
         async private void MediaPlayer_CurrentStateChanged(Windows.Media.Playback.MediaPlayer sender, object args)
         {
              Log($"\n{DateTime.Now} - Media StateChanged - {sender.PlaybackSession.PlaybackState.ToString()}");
             //=> Only paused called twice when closed.
         }
    
         async private void MediaPlayer_MediaOpened(Windows.Media.Playback.MediaPlayer sender, object args)
         {
             Log($"\n{DateTime.Now} - Media Opened");
         }
    
         async private void MediaPlayer_MediaEnded(Windows.Media.Playback.MediaPlayer sender, object args)
         {
             Log($"\n{DateTime.Now} - Media Ended");
         }
    
         StorageFile file;
         async private void OpenButton_Click(object sender, RoutedEventArgs e)
         {
             var picker = new Windows.Storage.Pickers.FileOpenPicker();
             picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
             picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
             picker.FileTypeFilter.Add(".mp4");
             file = await picker.PickSingleFileAsync();
             if (file != null)
             {
                 // Application now has read/write access to the picked file
                 mpPlayer.Source = MediaSource.CreateFromStorageFile(file);
                 mpPlayer.MediaPlayer.Play();
             }
         }
    
         async private void CloseUpdateButton_Click(object sender, RoutedEventArgs e)
         {
             try
             {
                 mpPlayer.MediaPlayer.Pause();
                 mpPlayer.MediaPlayer.Source = null;
                 //mpPlayer.Source = EmptyVideo; //Sometimes work.
                 await Task.Delay(500);
    
                 VideoProperties vdPt = await file.Properties.GetVideoPropertiesAsync();
    
                 string[] keywords = new string[] { "Test", "Video", "Tags", "Update" };
                 vdPt.Keywords.Clear();
                 foreach (var tag in keywords) //Tags
                 {
                     vdPt.Keywords.Add(tag);
                 }
                 await vdPt.SavePropertiesAsync();
             }
             catch (Exception ex)
             {
                 Log($"\n{DateTime.Now}\n {ex.Message}");
             }
         }
     }


The code works well if I copy the video file into local drive (under C:\Temp) and tested. But it doesn't work from the video file from NAS drive, such as my Synology network drive over home wifi, \\MyNAS\video\Test\20201125_032706.mp4.
And, it throws error:
"3/27/2021 4:52:35 PM - Media StateChanged - None
Exception thrown: 'System.IO.FileLoadException' in System.Private.CoreLib.dll
3/27/2021 4:52:36 PM
The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)"

Try to force to release the file played, I put extra code
await Task.Delay(500), but it doesn't work. Even I put 10 seconds or 1 minutes, it doesn't work well.

Also, I try to bind emptyVideo to release previous video, it sometimes work, but not always. Mostly no.



  1. Is there a way to force to release the video file from NAS?

  2. If NOT, is there a way to know or get notified via event when the file is released?

  3. If 1 and 2 is not possible, is there a way to check if the file is being used by another process programmatically?

Or, am I using wrong control? Or, is the code opening video is wrong?

Any comment helps,
Thank you!

windows-uwp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

NicoZhu-MSFT avatar image
0 Votes"
NicoZhu-MSFT answered SmilingMoon commented

Hello, Welcome to Micorosoft Q&A,


How to release video file played from NAS to avoid "..being used by another process."

The problem is looks , the file has not been released by previous media, For this scenario, we suggest your call Dispose to release MediaSourece manually.

  private MediaSource _mediaSourece;
  async private void OpenButton_Click(object sender, RoutedEventArgs e)
  {
      var picker = new Windows.Storage.Pickers.FileOpenPicker();
      picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
      picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
      picker.FileTypeFilter.Add(".mp4");
      file = await picker.PickSingleFileAsync();
      if (file != null)
      {
          // Application now has read/write access to the picked file
    
          _mediaSourece = MediaSource.CreateFromStorageFile(file);
          mpPlayer.Source = _mediaSourece;
          mpPlayer.MediaPlayer.Play();
      }
  }
    
  async private void CloseUpdateButton_Click(object sender, RoutedEventArgs e)
  {
      try
      {
          mpPlayer.MediaPlayer.Pause();                   
          mpPlayer.MediaPlayer.Source = null;
          _mediaSourece.Dispose();
      }
 }


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It works!! Thank you sooo... much!!

0 Votes 0 ·