Browse Source

add kodiprop to channels.m3u (#1448)

pull/1450/head
Jason Dove 2 years ago committed by GitHub
parent
commit
547db5fb51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs
  3. 1
      ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs
  4. 24
      ErsatzTV.Core/Iptv/ChannelPlaylist.cs
  5. 1
      ErsatzTV/Controllers/IptvController.cs
  6. 12
      ErsatzTV/Shared/MainLayout.razor

1
CHANGELOG.md

@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -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

2
ErsatzTV.Application/Channels/Queries/GetChannelPlaylist.cs

@ -3,4 +3,4 @@ using ErsatzTV.Core.Iptv; @@ -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<ChannelPlaylist>;
(string Scheme, string Host, string BaseUrl, string Mode, string UserAgent, string AccessToken) : IRequest<ChannelPlaylist>;

1
ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs

@ -20,6 +20,7 @@ public class GetChannelPlaylistHandler : IRequestHandler<GetChannelPlaylist, Cha @@ -20,6 +20,7 @@ public class GetChannelPlaylistHandler : IRequestHandler<GetChannelPlaylist, Cha
request.Host,
request.BaseUrl,
channels,
request.UserAgent,
request.AccessToken));
private static List<Channel> EnsureMode(IEnumerable<Channel> channels, string mode)

24
ErsatzTV.Core/Iptv/ChannelPlaylist.cs

@ -9,15 +9,23 @@ public class ChannelPlaylist @@ -9,15 +9,23 @@ public class ChannelPlaylist
private readonly string _accessToken;
private readonly string _baseUrl;
private readonly List<Channel> _channels;
private readonly string _userAgent;
private readonly string _host;
private readonly string _scheme;
public ChannelPlaylist(string scheme, string host, string baseUrl, List<Channel> channels, string accessToken)
public ChannelPlaylist(
string scheme,
string host,
string baseUrl,
List<Channel> channels,
string userAgent,
string accessToken)
{
_scheme = scheme;
_host = host;
_baseUrl = baseUrl;
_channels = channels;
_userAgent = userAgent;
_accessToken = accessToken;
}
@ -37,6 +45,20 @@ public class ChannelPlaylist @@ -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()

1
ErsatzTV/Controllers/IptvController.cs

@ -45,6 +45,7 @@ public class IptvController : ControllerBase @@ -45,6 +45,7 @@ public class IptvController : ControllerBase
Request.Host.ToString(),
Request.PathBase,
mode,
Request.Headers.UserAgent,
Request.Query["access_token"]))
.Map<ChannelPlaylist, IActionResult>(Ok);

12
ErsatzTV/Shared/MainLayout.razor

@ -204,7 +204,17 @@ @@ -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()
{

Loading…
Cancel
Save