James Crutchley
James Crutchley

Reputation: 91

Higher quality HLS stream from youtube for Media Element in dotnet Maui

I am trying to figure out how to get a higher bitrate video from a youtube stream of a live show in progress. I am playing it back using media element in dotnet maui. Right now it is very low quality video and I have no idea how to improve it. I am using Youtube Explode packgage. The function that I use to get stream is GetHttpLiveStreamUrlAsync(). This is the only way I have been able to get any video to playback in media element for maui.

xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="NerdNewsNavigator2.View.LivePage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    xmlns:viewmodel="clr-namespace:NerdNewsNavigator2.ViewModel"
    Title=""
    x:DataType="viewmodel:LiveViewModel"
    Loaded="ContentPage_Loaded"
    Unloaded="ContentPage_Unloaded"
    Shell.NavBarIsVisible="False">

    <Shell.BackButtonBehavior>
        <BackButtonBehavior IsEnabled="True" IsVisible="False" />
    </Shell.BackButtonBehavior>

    <Grid>
        <toolkit:MediaElement
            x:Name="mediaElement"
            ShouldAutoPlay="True"
            ShouldShowPlaybackControls="True" />
    </Grid>

</ContentPage>

code to display video:

 private void ContentPage_Loaded(object? sender, EventArgs e)
    {
        if (sender is null)
        {
            return;
        }

        _ = LoadVideo();
        SetFullScreen();
    }
    private async Task LoadVideo()
    {
        var youtube = new YoutubeClient();
        mediaElement.Source = await youtube.Videos.Streams.GetHttpLiveStreamUrlAsync("F2NreNEmMy4");
        mediaElement.Play();
    }

This is abbreviated code that shows the methods I use to get it to display. I am looking for either an alternative method or an improvement of current code to get better video.

Upvotes: 1

Views: 1377

Answers (1)

James Crutchley
James Crutchley

Reputation: 91

Figured out the mediaelement source I provided was in fact an m3u8 file that i was getting and saving as a string. I could parse that to give me a list of resolutions that I could then get a url for. The two packages I ended up using were Youtube Explode and M3U8Parser.

    /// <summary>
    /// Method returns 720P URL for <see cref="mediaElement"/> to Play.
    /// </summary>
    /// <param name="m3UString"></param>
    /// <returns></returns>
    public static string ParseM3UPLaylist(string m3UString)
    {
        var masterPlaylist = MasterPlaylist.LoadFromText(m3UString);
        var list = masterPlaylist.Streams.ToList();
        return list.ElementAt(list.FindIndex(x => x.Resolution.Height == 720)).Uri;
    }

    /// <summary>
    /// Method returns the Live stream M3U Url from youtube ID.
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    public static async Task<string> GetM3U_Url(string url)
    {
        var content = string.Empty;
        var client = new HttpClient();
        var youtube = new YoutubeClient();
        var result = await youtube.Videos.Streams.GetHttpLiveStreamUrlAsync(url);
        var response = await client.GetAsync(result);
        if (response.IsSuccessStatusCode)
        {
            content = await response.Content.ReadAsStringAsync();
        }

        return content;
    }
    /// <summary>
    /// Method Starts <see cref="MediaElement"/> Playback.
    /// </summary>
    /// <returns></returns>
    private async Task LoadVideo()
    {
        var m3u = await LivePage.GetM3U_Url("F2NreNEmMy4");
        mediaElement.Source = LivePage.ParseM3UPLaylist(m3u);
        mediaElement.Play();
    }

This code snippet shows how I got the 720P url from a youtube stream using one additional package to parse the m3u8 file.

Upvotes: 2

Related Questions