From 547db5fb515fb9527c00173b811f246ac00b20cb Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:47:55 -0500 Subject: [PATCH] add kodiprop to channels.m3u (#1448) --- CHANGELOG.md | 1 + .../Channels/Queries/GetChannelPlaylist.cs | 2 +- .../Queries/GetChannelPlaylistHandler.cs | 1 + ErsatzTV.Core/Iptv/ChannelPlaylist.cs | 24 ++++++++++++++++++- ErsatzTV/Controllers/IptvController.cs | 1 + ErsatzTV/Shared/MainLayout.razor | 12 +++++++++- 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60211187b..f35c5570a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `Crop`: a new mode that will scale beyond the desired resolution (maintaining aspect ratio), and crop to desired resolution - **This mode does NOT detect black and intelligently crop** - The goal is to fill the canvas by over-scaling and cropping, instead of minimally scaling and padding +- Include `inputstream.ffmpegdirect` properties in channels.m3u when requested by Kodi ### Changed - Upgrade ffmpeg to 6.1, which is now *required* for all installs diff --git a/ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs b/ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs index 2c6b21565..faece3960 100644 --- a/ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs +++ b/ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs @@ -3,4 +3,4 @@ using ErsatzTV.Core.Iptv; namespace ErsatzTV.Application.Channels; public record GetChannelPlaylist - (string Scheme, string Host, string BaseUrl, string Mode, string AccessToken) : IRequest; + (string Scheme, string Host, string BaseUrl, string Mode, string UserAgent, string AccessToken) : IRequest; diff --git a/ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs b/ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs index 3fd6b2f28..a0ccc8393 100644 --- a/ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs +++ b/ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs @@ -20,6 +20,7 @@ public class GetChannelPlaylistHandler : IRequestHandler EnsureMode(IEnumerable channels, string mode) diff --git a/ErsatzTV.Core/Iptv/ChannelPlaylist.cs b/ErsatzTV.Core/Iptv/ChannelPlaylist.cs index 8585e706c..91221d17a 100644 --- a/ErsatzTV.Core/Iptv/ChannelPlaylist.cs +++ b/ErsatzTV.Core/Iptv/ChannelPlaylist.cs @@ -9,15 +9,23 @@ public class ChannelPlaylist private readonly string _accessToken; private readonly string _baseUrl; private readonly List _channels; + private readonly string _userAgent; private readonly string _host; private readonly string _scheme; - public ChannelPlaylist(string scheme, string host, string baseUrl, List channels, string accessToken) + public ChannelPlaylist( + string scheme, + string host, + string baseUrl, + List channels, + string userAgent, + string accessToken) { _scheme = scheme; _host = host; _baseUrl = baseUrl; _channels = channels; + _userAgent = userAgent; _accessToken = accessToken; } @@ -37,6 +45,20 @@ public class ChannelPlaylist sb.AppendLine(CultureInfo.InvariantCulture, $"#EXTM3U url-tvg=\"{xmltv}\" x-tvg-url=\"{xmltv}\""); foreach (Channel channel in _channels.OrderBy(c => decimal.Parse(c.Number, CultureInfo.InvariantCulture))) { + if ((_userAgent ?? string.Empty).StartsWith("kodi", StringComparison.OrdinalIgnoreCase)) + { + sb.AppendLine("#KODIPROP:inputstream=inputstream.ffmpegdirect"); + + string mimeType = channel.StreamingMode switch + { + StreamingMode.TransportStream or StreamingMode.TransportStreamHybrid => "video/mp2t", + _ => "application/x-mpegURL" + }; + sb.AppendLine(CultureInfo.InvariantCulture, $"#KODIPROP:mimetype={mimeType}"); + + sb.AppendLine("#KODIPROP:inputstream.ffmpegdirect.open_mode=ffmpeg"); + } + string logo = Optional(channel.Artwork).Flatten() .Filter(a => a.ArtworkKind == ArtworkKind.Logo) .HeadOrNone() diff --git a/ErsatzTV/Controllers/IptvController.cs b/ErsatzTV/Controllers/IptvController.cs index 05f4f14b3..6118c9203 100644 --- a/ErsatzTV/Controllers/IptvController.cs +++ b/ErsatzTV/Controllers/IptvController.cs @@ -45,6 +45,7 @@ public class IptvController : ControllerBase Request.Host.ToString(), Request.PathBase, mode, + Request.Headers.UserAgent, Request.Query["access_token"])) .Map(Ok); diff --git a/ErsatzTV/Shared/MainLayout.razor b/ErsatzTV/Shared/MainLayout.razor index 78e711943..016ef9650 100644 --- a/ErsatzTV/Shared/MainLayout.razor +++ b/ErsatzTV/Shared/MainLayout.razor @@ -204,7 +204,17 @@ } } - private async void OnStartupProgress(object sender, EventArgs e) => await InvokeAsync(StateHasChanged); + private async void OnStartupProgress(object sender, EventArgs e) + { + try + { + await InvokeAsync(StateHasChanged); + } + catch + { + // do nothing + } + } protected override async Task OnParametersSetAsync() {