Move DynamicHlsService to Jellyfin.Api

This commit is contained in:
crobibero 2020-07-31 15:09:17 -06:00
parent 2cb6eb984b
commit f645e2f884
8 changed files with 2377 additions and 17 deletions

View File

@ -70,7 +70,7 @@ namespace Jellyfin.Api.Auth
return false;
}
var ip = NormalizeIp(_httpContextAccessor.HttpContext.Connection.RemoteIpAddress).ToString();
var ip = RequestHelpers.NormalizeIp(_httpContextAccessor.HttpContext.Connection.RemoteIpAddress).ToString();
var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
// User cannot access remotely and user is remote
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
@ -100,10 +100,5 @@ namespace Jellyfin.Api.Auth
return true;
}
private static IPAddress NormalizeIp(IPAddress ip)
{
return ip.IsIPv4MappedToIPv6 ? ip.MapToIPv4() : ip;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,125 @@
using System;
using System.Globalization;
using System.Text;
namespace Jellyfin.Api.Helpers
{
/// <summary>
/// Hls Codec string helpers.
/// </summary>
public static class HlsCodecStringHelpers
{
/// <summary>
/// Gets a MP3 codec string.
/// </summary>
/// <returns>MP3 codec string.</returns>
public static string GetMP3String()
{
return "mp4a.40.34";
}
/// <summary>
/// Gets an AAC codec string.
/// </summary>
/// <param name="profile">AAC profile.</param>
/// <returns>AAC codec string.</returns>
public static string GetAACString(string profile)
{
StringBuilder result = new StringBuilder("mp4a", 9);
if (string.Equals(profile, "HE", StringComparison.OrdinalIgnoreCase))
{
result.Append(".40.5");
}
else
{
// Default to LC if profile is invalid
result.Append(".40.2");
}
return result.ToString();
}
/// <summary>
/// Gets a H.264 codec string.
/// </summary>
/// <param name="profile">H.264 profile.</param>
/// <param name="level">H.264 level.</param>
/// <returns>H.264 string.</returns>
public static string GetH264String(string profile, int level)
{
StringBuilder result = new StringBuilder("avc1", 11);
if (string.Equals(profile, "high", StringComparison.OrdinalIgnoreCase))
{
result.Append(".6400");
}
else if (string.Equals(profile, "main", StringComparison.OrdinalIgnoreCase))
{
result.Append(".4D40");
}
else if (string.Equals(profile, "baseline", StringComparison.OrdinalIgnoreCase))
{
result.Append(".42E0");
}
else
{
// Default to constrained baseline if profile is invalid
result.Append(".4240");
}
string levelHex = level.ToString("X2", CultureInfo.InvariantCulture);
result.Append(levelHex);
return result.ToString();
}
/// <summary>
/// Gets a H.265 codec string.
/// </summary>
/// <param name="profile">H.265 profile.</param>
/// <param name="level">H.265 level.</param>
/// <returns>H.265 string.</returns>
public static string GetH265String(string profile, int level)
{
// The h265 syntax is a bit of a mystery at the time this comment was written.
// This is what I've found through various sources:
// FORMAT: [codecTag].[profile].[constraint?].L[level * 30].[UNKNOWN]
StringBuilder result = new StringBuilder("hev1", 16);
if (string.Equals(profile, "main10", StringComparison.OrdinalIgnoreCase))
{
result.Append(".2.6");
}
else
{
// Default to main if profile is invalid
result.Append(".1.6");
}
result.Append(".L")
.Append(level * 3)
.Append(".B0");
return result.ToString();
}
/// <summary>
/// Gets an AC-3 codec string.
/// </summary>
/// <returns>AC-3 codec string.</returns>
public static string GetAC3String()
{
return "mp4a.a5";
}
/// <summary>
/// Gets an E-AC-3 codec string.
/// </summary>
/// <returns>E-AC-3 codec string.</returns>
public static string GetEAC3String()
{
return "mp4a.a6";
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
@ -172,5 +173,10 @@ namespace Jellyfin.Api.Helpers
.Select(i => i!.Value)
.ToArray();
}
internal static IPAddress NormalizeIp(IPAddress ip)
{
return ip.IsIPv4MappedToIPv6 ? ip.MapToIPv4() : ip;
}
}
}

View File

@ -219,7 +219,7 @@ namespace Jellyfin.Api.Helpers
/// <param name="playSessionId">The play session identifier.</param>
/// <param name="deleteFiles">The delete files.</param>
/// <returns>Task.</returns>
public Task KillTranscodingJobs(string deviceId, string playSessionId, Func<string, bool> deleteFiles)
public Task KillTranscodingJobs(string deviceId, string? playSessionId, Func<string, bool> deleteFiles)
{
return KillTranscodingJobs(
j => string.IsNullOrWhiteSpace(playSessionId)
@ -503,9 +503,9 @@ namespace Jellyfin.Api.Helpers
}
}
var process = new Process()
var process = new Process
{
StartInfo = new ProcessStartInfo()
StartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,

View File

@ -0,0 +1,13 @@
namespace Jellyfin.Api.Models.StreamingDtos
{
/// <summary>
/// The hls video request dto.
/// </summary>
public class HlsAudioRequestDto : StreamingRequestDto
{
/// <summary>
/// Gets or sets a value indicating whether enable adaptive bitrate streaming.
/// </summary>
public bool EnableAdaptiveBitrateStreaming { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace Jellyfin.Api.Models.StreamingDtos
{
/// <summary>
/// The hls video request dto.
/// </summary>
public class HlsVideoRequestDto : VideoRequestDto
{
/// <summary>
/// Gets or sets a value indicating whether enable adaptive bitrate streaming.
/// </summary>
public bool EnableAdaptiveBitrateStreaming { get; set; }
}
}

View File

@ -27,8 +27,6 @@ namespace MediaBrowser.Api.Playback.Hls
/// <summary>
/// Options is needed for chromecast. Threw Head in there since it's related
/// </summary>
[Route("/Videos/{Id}/master.m3u8", "GET", Summary = "Gets a video stream using HTTP live streaming.")]
[Route("/Videos/{Id}/master.m3u8", "HEAD", Summary = "Gets a video stream using HTTP live streaming.")]
public class GetMasterHlsVideoPlaylist : VideoStreamRequest, IMasterHlsRequest
{
public bool EnableAdaptiveBitrateStreaming { get; set; }
@ -39,8 +37,6 @@ namespace MediaBrowser.Api.Playback.Hls
}
}
[Route("/Audio/{Id}/master.m3u8", "GET", Summary = "Gets an audio stream using HTTP live streaming.")]
[Route("/Audio/{Id}/master.m3u8", "HEAD", Summary = "Gets an audio stream using HTTP live streaming.")]
public class GetMasterHlsAudioPlaylist : StreamRequest, IMasterHlsRequest
{
public bool EnableAdaptiveBitrateStreaming { get; set; }
@ -56,17 +52,14 @@ namespace MediaBrowser.Api.Playback.Hls
bool EnableAdaptiveBitrateStreaming { get; set; }
}
[Route("/Videos/{Id}/main.m3u8", "GET", Summary = "Gets a video stream using HTTP live streaming.")]
public class GetVariantHlsVideoPlaylist : VideoStreamRequest
{
}
[Route("/Audio/{Id}/main.m3u8", "GET", Summary = "Gets an audio stream using HTTP live streaming.")]
public class GetVariantHlsAudioPlaylist : StreamRequest
{
}
[Route("/Videos/{Id}/hls1/{PlaylistId}/{SegmentId}.{SegmentContainer}", "GET")]
public class GetHlsVideoSegment : VideoStreamRequest
{
public string PlaylistId { get; set; }
@ -78,7 +71,6 @@ namespace MediaBrowser.Api.Playback.Hls
public string SegmentId { get; set; }
}
[Route("/Audio/{Id}/hls1/{PlaylistId}/{SegmentId}.{SegmentContainer}", "GET")]
public class GetHlsAudioSegment : StreamRequest
{
public string PlaylistId { get; set; }