1

Trying to use libvlcsharp.forms in xamarinForms project.
Need to play resource video files.

Installed libVLCsharp.Forms, VideoLan.LibVLC.Android, VideoLan.LibVLC.IOS

Copied an mp4 file to iosProject/Resources; marked as BundleResource.
Copied same file to androidProject/Resources/raw; marked as AndroidResource

  • iOS can play from internet
  • Anroid can play same online address as iOS
  • ios can play resource file
  • android can not play same resource file

Error > error with media file:////BigBuckBunny.mp4

Thought it did not like my mp4 file format or something like that.
downloaded the file which it could play from url.
tried that one instead.
same results.

Help !!!

While it(android) could play famous BigBuckBuny from url > http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4, it can not play same video downloaded and copied to AndroidProject/Resource/raw

XAML part:

<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ParkinsonMobileApp.Pages.PhysicalActivitiesVideoDetail"
Padding="0"
Title="HomePage"
FlowDirection="LeftToRight"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="False"
NavigationPage.HasNavigationBar="False"
xmlns:customViews="clr-namespace:ParkinsonMobileApp.Views"
BackgroundColor="White"
xmlns:vlc="clr-namespace:LibVLCSharp.Forms.Shared;assembly=LibVLCSharp.Forms"
Appearing="ContentPage_OnAppearing"
Disappearing="ContentPage_Disappearing">
<AbsoluteLayout
    Padding="0"
    Margin="0"
    HorizontalOptions="Fill"
    VerticalOptions="Fill">
    <Image
        x:Name="imgViewBackground"
        Source="viewBackgroundBlurred.png"
        Aspect="AspectFill"
        AbsoluteLayout.LayoutFlags="All"
        AbsoluteLayout.LayoutBounds="0,0,1,1" />
    <vlc:MediaPlayerElement
        x:Name="vlcPlayer"
        MediaPlayer="{Binding MediaPlayer}"
        LibVLC="{Binding LibVLC}"
        EnableRendererDiscovery="True"
        Padding="0"
        Margin="0"
        AbsoluteLayout.LayoutFlags="All"
        AbsoluteLayout.LayoutBounds="0,0,1,1" />
    <customViews:CustomNavigationBar
        HorizontalOptions="Fill"
        VerticalOptions="Start"
        Padding="0"
        Margin="0"
        AbsoluteLayout.LayoutFlags="All"
        AbsoluteLayout.LayoutBounds="0,0,1,1"
        Theme="White"
        ImgBackgroundIsVisible="False"
        ButBackDisplayed="True"
        ButsOnRightDisplayed="False"
        TitleText="Egzersiz 001"
        TitleIsDisplayed="True"
        BackgroundColor="Transparent"
        backClicked="CustomNavigationBar_backClicked" />
</AbsoluteLayout>

CodeBehind dataBinding:

void ContentPage_OnAppearing(object sender, System.EventArgs e)
    {
        base.OnAppearing();
        //pageViewModel = new VieoDetailViewModel("file://android_asset/024_1.mp4");
        //pageViewModel = new VieoDetailViewModel("024_1.mp4");
        pageViewModel = new VieoDetailViewModel("BigBuckBunny.mp4");
        BindingContext = pageViewModel;
        //MessagingCenter.Send(this, "AllowLandscape");
    }

DataBinding Model:

public class VieoDetailViewModel : ViewModelBase
{
    /// <summary>
    /// Initialize LibVLC and playback when page appears
    /// </summary>
    public VieoDetailViewModel(String filePath)
    {
        Core.Initialize();

        LibVLC = new LibVLC();

        var media = new Media(LibVLC,
            //"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
            filePath,
            //FromType.FromLocation
            FromType.FromPath
            );

        MediaPlayer = new MediaPlayer(media) { EnableHardwareDecoding = true };
        //MediaPlayer = new MediaPlayer(media);
        MediaPlayer.Play(media);
    }

    /// <summary>
    /// Gets the <see cref="LibVLCSharp.Shared.LibVLC"/> instance.
    /// </summary>
    public LibVLC _LibVLC;
    public LibVLC LibVLC
    {
        get
        {
            return _LibVLC;
        }
        set
        {
            _LibVLC = value;
            OnPropertyChanged("LibVLC");
        }
    }

    /// <summary>
    /// Gets the <see cref="LibVLCSharp.Shared.MediaPlayer"/> instance.
    /// </summary>
    public MediaPlayer _MediaPlayer;
    public MediaPlayer MediaPlayer
    {
        get
        {
            return _MediaPlayer;
        }
        set
        {
            _MediaPlayer = value;
            OnPropertyChanged("MediaPlayer");
        }
    }
}
Add080bbA
  • 1,818
  • 1
  • 18
  • 25
  • What's the path to your mp4 file inside the APK? – mfkl Mar 07 '20 at 10:44
  • mp4 file is located @ AndroidPoject/Resources/raw/BigBuckBunny.mp4 and marked as AndroidResourse. I am refering to that as "BigBuckBunny.mp4". This works in iOS. Not in Android. – Add080bbA Mar 08 '20 at 21:25

2 Answers2

0

I have check the path of the MP4 stored in Assets folder of Resource. It always thrown the exception like below.

VLC is unable to open the MRL

You could put the mp4 file in Assets folder and then copy to the device to play.

LibVLCSharp.Platforms.Android.VideoView _videoView;
    LibVLC _libVLC;
    MediaPlayer _mediaPlayer;
    private const string fileName = "BigBuckBunny.mp4";
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.layout1);
    }

    protected async override void OnResume()
    {
        base.OnResume();

        Core.Initialize();

        _libVLC = new LibVLC();
        _mediaPlayer = new MediaPlayer(_libVLC)
        {
            EnableHardwareDecoding = true
        };

        //_videoView = new LibVLCSharp.Platforms.Android.VideoView(this) { MediaPlayer = _mediaPlayer };

        _videoView = FindViewById<LibVLCSharp.Platforms.Android.VideoView>(Resource.Id.videoPlayer);
        _videoView.MediaPlayer = _mediaPlayer;

        // Android application default folder.
        var dbFile = GetDefaultFolderPath();

        // Check if the file already exists.
        if (!File.Exists(dbFile))
        {
            using (FileStream writeStream = new FileStream(dbFile, FileMode.OpenOrCreate, FileAccess.Write))
            {
                // Assets is comming from the current context.
                await Assets.Open(fileName).CopyToAsync(writeStream);
            }
        }


        //AddContentView(_videoView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
        var media = new Media(_libVLC, dbFile, FromType.FromPath);//"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
        if (File.Exists(dbFile))
        {
            _videoView.MediaPlayer.Play(media);
        }


    }
    private string GetDefaultFolderPath()
    {
        var appFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        var dbFile = Path.Combine(appFolder, fileName);

        return dbFile;
    }

enter image description here

Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17
  • This looks like a xamarin.Android solution. Any possibility to fix this from forms. The code i have entered is directly from shared code. – Add080bbA Mar 06 '20 at 13:34
  • Use Dependency service to call this with android implementation. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction – Wendy Zang - MSFT Mar 09 '20 at 09:21
0

The Media constructor has an overload that takes a StreamMediaInput so you can add the video file to the main project as an embedded resource, read it into a Stream and create the StreamMediaInput from it. If you do it this way it will work for iOS as well so you only need the video files in the main project, remove them from Android and iOS.

using System.IO;
using System.Reflection;
...

Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = assembly.GetName().Name;
Stream stream = assembly.GetManifestResourceStream(assemblyName + ".BigBuckBunny.mp4");
StreamMediaInput mediaStream = new StreamMediaInput(stream);
Media media = new Media(_libVLC, mediaStream, new string[] { });
MediaPlayer player = new MediaPlayer(media) { EnableHardwareDecoding = true };
player.Play();

This assumes the mp4 file is in the root of the main project. Also note that I haven't wrapped the Stream in a using() because you need to hang onto it until you're done with the video and dispose of it then, so you need to sort that out - you could create a class to handle that.

oldcoder
  • 36
  • 3