0

I have a Blazor Dialog in which I show Videos from a directory on disk. The videos can be selected for upload. After selection the 'Upload' button uploads the videos to a server. After the upload the files need to be moved to an archive. Here's the problem. When I try and move the file it complains it is being used by another process. That is probably the tag holding the video.

Here's the razor code:

<RadzenListBox TValue="FileDto"
               @ref=FileListBox
               Data=@TakesList>
    <Template Context="takeIn">
        <RadzenCard>
            @{
                var take = takeIn as FileDto;
            }
            <div class="row">
                <RadzenCheckBox TValue="bool" @bind-Value=take.IsSelectedForUpload class="col-auto"/>
                <div class="col-auto">
                    <video class="w-25" controls @ref=@take.VideoReference>
                        <source src=@($"{@take.FileName}#t=9.5") type="video/mp4">
                        Your browser does not support the video tag.
                    </video>
                </div>
            </div>
            <RadzenProgressBar Max=100 Value=@take.PercentageFinished Visible=@(take.PercentageFinished > 0) />
        </RadzenCard>
    </Template>
</RadzenListBox>

Is there a way to have the tag release the file and close it?

== EDIT ==

Ok, I thought, what if I created a thumbnail instead and show that. It will not lock the file then. That works fine. Now I've added a new Dialog with the video player in it and play the video there. I hoped that when I would close the Dialog the video would be unlocked but alas that is not the case. After playing the video and closing the Dialog the file stays locked.

Paul Sinnema
  • 2,534
  • 2
  • 20
  • 33

1 Answers1

0

Ok, I found a trick here: How to properly unload/destroy a VIDEO element, it does give warnings in the console but is of minor concern I think.

Place this in your _Layout.cshtml:

<script>
    // We need to do this because the browser locks the files blocking archiving and deleting.
    window.removeMedia = () => {
        console.info('Removing media');
        let videos = document.getElementsByTagName('video');
        for (let vid in videos) {
            if (typeof videos[vid] == 'object') {
                let srcs = videos[vid].getElementsByTagName('source');
                videos[vid].pause();
                for (let xsrc in srcs) {
                    if (srcs[xsrc].src !== undefined) {
                        srcs[xsrc].src = '';
                    }
                }
                videos[vid].load();
                videos[vid].parentNode.removeChild(videos[vid]);
            }
        }
    }
</script>

To be complete, here's the Dialog playing the video.

The razor content:

@inherits PageBase

<div class="col-auto">
    <video class="w-75" controls autoplay>
        <source src=@($"{@VideoPath}") type="video/mp4">
        Your browser does not support the video tag.
    </video>
</div>

The code behind content:

using MetadataEnricher.Core.Dtos;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace MetadataEnricher.Pages.Dialogs
{
    public partial class VideoPlayerDialog : PageBase, IDisposable
    {
        [Inject]
        IJSRuntime JS { get; set; }

        [Parameter]
        public FileDto Take { get; set; }

        public string VideoPath { get; set; }

        protected override void OnInitialized()
        {
            VideoPath = Take.FileName;

            DialogService.OnClose += DialogService_OnClose;

            base.OnInitialized();
        }

        private async void DialogService_OnClose(dynamic obj)
        {
            await JS.InvokeAsync<string>("removeMedia");

            VideoPath = null;
        }

        public void Dispose()
        {
            DialogService.OnClose -= DialogService_OnClose;
        }
    }
}
Paul Sinnema
  • 2,534
  • 2
  • 20
  • 33