Xamarin Forms MediaSource not loading from local file

Viewed 371

I'm trying to use the MediaElement to show a video in a Xamarin Forms app. The first time a specific video get's opened, it will retrieve the video from the internet with MediaSource.FromUri();. Then I'll write the video to the local filesystem, so that I can retrieve the video locally the next time the user tries to open it. When loading the video from the internet it all works correctly, but I can't get it to load correctly from the local filesystem. I tried it both with MediaSource.FromFile() and MediaSource.FromUri(), but there is no video and the page stays black.

This the relevant XAML-code:

<MediaElement Source="{Binding MediaSource}" ShowsPlaybackControls="True" Aspect="AspectFit" />```

The code of my ViewModel (which is the BindingContext of the page):

public class VideoPlayerViewModel : BaseViewModel
    {
        public string VideoUrl { get; set; }

        private MediaSource mediaSource;

        public MediaSource MediaSource
        {
            get => mediaSource;
            set
            {
                mediaSource = value;

                OnPropertyChanged();
            }
        }

        /// <summary>
        /// Initializes this instance.
        /// <para>Sets IsInitialized to true</para>
        /// </summary>
        public override async void Init()
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(VideoUrl))
                {
                    string videoUrl = $"{Constants.VideoBaseUrl}{VideoUrl}";

                    string videoFilename = Path.GetFileName(videoUrl);

                    string videoCacheDirectory = Path.Combine(FileSystem.AppDataDirectory, Constants.VideoCacheDirectory);
                    string videoFilePath = Path.Combine(videoCacheDirectory, videoFilename);

                    if (!File.Exists(videoFilePath))
                    {
                        MediaSource = MediaSource.FromUri(new Uri(videoUrl));

                        await CacheVideoAsync(videoUrl, videoFilePath);
                    }
                    else
                        MediaSource = MediaSource.FromFile(videoFilePath); //   MediaSource = MediaSource.FromUri(new Uri()); // 
                }
            }
            catch
            {

            }

            base.Init();
        }

        private static async Task CacheVideoAsync(string videoUrl, string videoFilePath)
        {
            try
            {
                CreateCacheDirectoryIfNotExists();

                using (HttpResponseMessage response = await Statics.AppHttpClient.GetAsync(videoUrl))
                using (Stream videoStream = await response.Content.ReadAsStreamAsync())
                using (FileStream outputStream = File.Create(videoFilePath))
                {
                    await videoStream.CopyToAsync(outputStream);
                }
            }
            catch (Exception ex)
            {
            }
        }

        private static void CreateCacheDirectoryIfNotExists()
        {
            string videoCacheDirectory = Path.Combine(FileSystem.AppDataDirectory, Constants.VideoCacheDirectory);

            if (!Directory.Exists(videoCacheDirectory))
                Directory.CreateDirectory(videoCacheDirectory);
        }
    }

Could someone tell me what I'm doing wrong?

1 Answers

Try adding the CrossFilePicker and set source as mediaElement.Source = MediaSource.FromUri(filePath);

        FileData fileData = await CrossFilePicker.Current.PickFile();
        if (fileData == null)
            return; // user canceled file picking

        string fileName = fileData.FileName;
        string contents = System.Text.Encoding.UTF8.GetString(fileData.DataArray);

        var Items = GetItems();
        mediaElement.Source = MediaSource.FromFile(fileData.FilePath);//Items[0].FilePath

And also specify the name of the element in xaml

<Grid>
    <xct:MediaElement x:Name="mediaElement"
                      Grid.Row="0"
                      AutoPlay="False"
                      ShowsPlaybackControls="True" />
Related