Delivering Rich Media Experiences with the Xamarin.Forms Video Player

Guest Blogger

This is a guest post from Adam Fisher. Adam is the founder of Octane Software, focused on the creation of consumer Internet products. You can find Adam on Twitter at @adamgfisher and on Github at @adamfisher. Today we’ll take a look at Adam’s Xamarin.Forms Video Player component.

play

Delivering an interactive and engaging experience is critical to standing out in today’s massive app marketplace. Using video in your mobile apps offers an excellent way to engage your users and keep them in your app longer.

The Xamarin.Forms Video Player minimizes the complexity of video playback across Android, iOS, and Windows environments. The player accomplishes this by unifying several operations (Play, Stop, Seek, etc.) as well as events (playing, paused, completed, etc.) through a standard XAML control appropriately named, VideoPlayer, with the ability to play local files and embedded resources or HTTP(S)-based streamed files from the web.

The goal of any Xamarin Forms UI control is to provide a cross-platform unified interface to a platform’s native controls. As such, the Xamarin.Forms Video Player manages the AVPlayer on iOS, the MediaPlayer on Android, and the MediaElement on Windows platforms. This approach ensures your users will have a familiar experience with video playback since it makes use of the video player they have probably already been using.

Getting Started

You can incorporate the Xamarin.Forms Video Player into your Xamarin.Forms project by installing the trial version of the package from NuGet, or by using the NuGet Package Manager within your chosen IDE. We’ll be using Visual Studio 2017 and the Xamarin.Forms .NET Standard template for this example. You’ll need to install the package in every platform-specific project (iOS and Android for example), as well as the project containing your Xamarin.Forms pages.

Insert the following initialization call after the Xamarin.Forms initialization call, depending on the platform(s) you are targeting, as shown below:

Android (MainActivity.cs)

using Octane.Xamarin.Forms.VideoPlayer.Android;
...
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            FormsVideoPlayer.Init();
            LoadApplication(new App());
        }
    }

iOS (AppDelegate.cs)

using Octane.Xamarin.Forms.VideoPlayer.iOS;
...
public class AppDelegate : FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            FormsVideoPlayer.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }

UWP (App.xaml.cs)

using Octane.Xamarin.Forms.VideoPlayer.UWP;
...
protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
    ...
        Xamarin.Forms.Forms.Init(e);
        FormsVideoPlayer.Init(); // 

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }		
         ...
        }
    }

You can optionally pass the license key, if you purchased one, as a string into the initialization method. Passing a license key into this method unlocks the full capability of the component and turns off trial mode, which limits you to 15 seconds of video playback.

That’s it! You should be able to create a XAML content page and pass the path to a remote media resource or a local file path, as shown below:




    

You also have the ability to play media files embedded in your application assembly, but the player needs a little help differentiating it from a local file path. The file can be in any project referenced in your solution, as long as the build action of the video is marked as an embedded resource.

You can either assign it in XAML by including and using the VideoResource markup extension (not included in the plugin), or in code like this:

myPlayer.Source = VideoSource.FromResource("MyEmbeddedFile.mp4");

Understanding Video State

Invoking myPlayer.Play(); won’t work if you try to invoke it directly. The native video player of each platform each has its own unique behavior. In general, you can’t play a video file until its data stream has been opened for playback. By default, the plugin is set to automatically play the media file as soon as it is passed to the Source property. You can change this behavior by setting the AutoPlay property to false.

If you want fine grained control during various parts of the lifecycle, you can hook into the various playback events exposed by the player. Although you have access to individual playback events, you can also hook into the PlayerStateChanged event if you wish to handle multiple events inside a single event handler.

using Octane.Xamarin.Forms.VideoPlayer.Constants;
...
public partial class MyContentPage : ContentPage
    {
        public MyContentPage()
        {
            InitializeComponent();

            videoPlayer.PlayerStateChanged += (sender, args) =>
            {
                switch (args.CurrentState)
                {
                    case PlayerState.Prepared:
                        videoPlayer.Play(); // The video source is now ready for playback so you can call sender.Play() manually if you wish.
                        break;
                    case PlayerState.Completed:
                        Navigation.PopAsync(); // Go back to the previous page once the video completes.
                        break;
                    case PlayerState.Error:
                        DisplayAlert("Error Playing Video", "We're sorry but something is wrong with this video.", "OK");
                        break;
                }
            };
        }
    }

Setting the TimeElapsedInterval to a non-zero value will fire at the specified number of seconds during playback, allowing you to perform operations during various points in the playback timeline.

videoPlayer.TimeElapsedInterval = 1;
videoPlayer.TimeElapsed += (sender, args) =>
{
var halfTime = (int) args.Duration.TotalSeconds / 2;
var currentTime = (int) args.CurrentTime.TotalSeconds;

if (currentTime == halfTime) {
	videoPlayer.Pause();
	// Do something useful at half time… a snack perhaps?
}
};

Here we are setting the TimeElapsed event to fire every second. The video is paused halfway through the movie, but you could do anything you want at predefined intervals such as this.

Customizing the Player Controls

There are currently 10 configurable properties and 6 playback events on the video player. If you don’t like the native platform controls and wish to roll your own, you can set myPlayer.DisplayControls= false; and create your own Xamarin.Forms buttons or images and bind them to any of the properties or events on the video player. The Chill Player example app’s video player queue page shows an example of how to accomplish this, as shown below.

Here, we’re displaying the player’s state, the playback time updated in real-time, and custom XAML images with TapGestureRecognizer for the Pause and Seek buttons.

Common Video Playback Questions

This component has been a high-volume success on the Xamarin Component Store, and there are several frequently recurring questions that crop up during the course of development:

  • Can I play video from streaming sources like RTSP/RTCP/RTP? Yes, but it depends on the platforms you plan to target. Each platform has a predefined set of supported codecs, so you’ll want to refer to the native platform video player documentation mentioned in the opening section of this article (iOS’s AVPlayer, Android’s MediaPlayer, and the Windows MediaElement) to determine what codecs are supported.
  • Can I stream YouTube/Vimeo/(Other Video Site) Videos? Yes, as long as you have the direct URL to a video file (typically ending with a file extension like .mp4). There are several XAML markup extensions available for retrieving the raw video URLs from services like YouTube and Vimeo. Just note that the only officially supported of retrieving video URLs is through each provider’s API.
  • Can I play multiple videos on a single page? This is highly discouraged, as some platforms (looking at you Android emulator) are resource constrained and consistently crash when more than one video player is loaded per page. With such a small screen, the user’s attention is already limited in what they can see. It’s best to keep a reference to a single instance and then move it around the page as necessary, swapping out image thumbnails for the player (it’s just another Xamarin.Forms.View, after all).

Summary

Cross-platform video can be a powerful addition to your mobile application. The Xamarin.Forms Video Player NuGet package is ready to go with a single line of drop-in code, as we detailed in the first section. You can get a more in-depth overview of the available customizations and configuration options in the Getting Started guide, or by watching a video tutorial to set up your project, starting from an empty Xamarin.Forms solution template to playing a video. The Chill Player example application on GitHub is also a great example, showing off full-screen video pages, custom video controls, playlist queues, and playing YouTube or Vimeo videos.

Happy coding!

0 comments

Discussion is closed.

Feedback usabilla icon