How to record an HLS stream with LibVLCSharp and .NET Core

In this post, I will show you how to record an HTTP Live Streaming (HLS) stream using LibVLCSharp in a .NET Core CLI app on Windows.

HLS is a streaming protocol originally developped by Apple which is supported in most internet browser and streaming media servers. Wikipedia has some info about it:

HLS resembles MPEG-DASH in that it works by breaking the overall stream into a sequence of small HTTP-based file downloads, each download loading one short chunk of an overall potentially unbounded transport stream. A list of available streams, encoded at different bit rates, is sent to the client using an extended M3U playlist.

So, to get started we need to pull 2 packages from the VideoLAN NuGet

<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>  
  <ItemGroup>
    <PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.4" />
    <PackageReference Include="LibVLCSharp" Version="0.0.3" />
   </ItemGroup>
</Project>

VideoLAN.LibVLC.Windows is the libvlc (C/C++) library compiled for the Windows platform. More info at here.

LibVLCSharp are the .NET bindings that use the native libvlc library and expose a .NET friendly API. This readme has additional details.

Now onto the actual code

static void Main(string[] args)
{
    // Record in a file "record.ts" located in the bin folder next to the app
    var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
    var destination = Path.Combine(currentDirectory, "record.ts");

    // Load native libvlc library
    Core.Initialize();

    using (var libvlc = new LibVLC())
    using (var mediaPlayer = new MediaPlayer(libvlc))
    {
        // Redirect log output to the console
        libvlc.Log += (sender, e) 
            => Console.WriteLine($"[{e.Level}] {e.Module}:{e.Message}");

        // Create new media with HLS link
        var media = new Media(libvlc, 
                    "http://hls1.addictradio.net/addictrock_aac_hls/playlist.m3u8", 
                    Media.FromType.FromLocation);

        // Define stream output options. 
        // In this case stream to a file with the given path
        // and play locally the stream while streaming it.
        media.AddOption(":sout=#file{dst=" + destination + "}");
        media.AddOption(":sout-keep");

        // Start recording
        mediaPlayer.Play(media);

        Console.WriteLine($"Recording in {destination}");
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
  1. First we load the libvlc dlls (included in the VideoLAN.LibVLC.Windows nuget package).
  2. Then we create 3 LibVLCSharp objects: a LibVLC, a MediaPlayer and a Media (containing the URL of the HLS stream).
  3. To get a better understanding of what is going on, we hook up the libvlc log output with the console.
  4. We add libvlc CLI options to the media, such as an output path destination (more info)
  5. At last, we start the process by calling Play on the MediaPlayer.
  6. After a while, you will find a record.ts file located at RecordHLS\bin\Debug\netcoreapp2.1.

This sample is available on the VideoLAN GitLab