mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-23 23:20:51 +01:00
Merge 72eb47c881 into fd71adfba9
This commit is contained in:
commit
6bacffb14b
5 changed files with 51 additions and 4 deletions
|
|
@ -1399,6 +1399,18 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
TranscodingJobType,
|
||||
cancellationTokenSource.Token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// Calculate the starting segment index from current transcoding state
|
||||
var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".m3u8");
|
||||
var segmentExtension = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer);
|
||||
var startSegmentIndex = 0;
|
||||
|
||||
var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
|
||||
if (currentTranscodingIndex.HasValue)
|
||||
{
|
||||
startSegmentIndex = currentTranscodingIndex.Value;
|
||||
}
|
||||
|
||||
var mediaSourceId = state.BaseRequest.MediaSourceId;
|
||||
var request = new CreateMainPlaylistRequest(
|
||||
mediaSourceId is null ? null : Guid.Parse(mediaSourceId),
|
||||
|
|
@ -1408,7 +1420,8 @@ public class DynamicHlsController : BaseJellyfinApiController
|
|||
state.Request.SegmentContainer ?? string.Empty,
|
||||
"hls1/main/",
|
||||
Request.QueryString.ToString(),
|
||||
EncodingHelper.IsCopyCodec(state.OutputVideoCodec));
|
||||
EncodingHelper.IsCopyCodec(state.OutputVideoCodec),
|
||||
startSegmentIndex);
|
||||
var playlist = _dynamicHlsPlaylistGenerator.CreateMainPlaylist(request);
|
||||
|
||||
return new FileContentResult(Encoding.UTF8.GetBytes(playlist), MimeTypes.GetMimeType("playlist.m3u8"));
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ public class CreateMainPlaylistRequest
|
|||
/// <param name="endpointPrefix">The URI prefix for the relative URL in the playlist.</param>
|
||||
/// <param name="queryString">The desired query string to append (must start with ?).</param>
|
||||
/// <param name="isRemuxingVideo">Whether the video is being remuxed.</param>
|
||||
public CreateMainPlaylistRequest(Guid? mediaSourceId, string filePath, int desiredSegmentLengthMs, long totalRuntimeTicks, string segmentContainer, string endpointPrefix, string queryString, bool isRemuxingVideo)
|
||||
/// <param name="startSegmentIndex">The starting segment index for the playlist.</param>
|
||||
public CreateMainPlaylistRequest(Guid? mediaSourceId, string filePath, int desiredSegmentLengthMs, long totalRuntimeTicks, string segmentContainer, string endpointPrefix, string queryString, bool isRemuxingVideo, int startSegmentIndex = 0)
|
||||
{
|
||||
MediaSourceId = mediaSourceId;
|
||||
FilePath = filePath;
|
||||
|
|
@ -28,6 +29,7 @@ public class CreateMainPlaylistRequest
|
|||
EndpointPrefix = endpointPrefix;
|
||||
QueryString = queryString;
|
||||
IsRemuxingVideo = isRemuxingVideo;
|
||||
StartSegmentIndex = startSegmentIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -69,4 +71,9 @@ public class CreateMainPlaylistRequest
|
|||
/// Gets a value indicating whether the video is being remuxed.
|
||||
/// </summary>
|
||||
public bool IsRemuxingVideo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the starting segment index for the playlist.
|
||||
/// </summary>
|
||||
public int StartSegmentIndex { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
|
|||
.Append("#EXT-X-TARGETDURATION:")
|
||||
.Append(Math.Ceiling(segments.Count > 0 ? segments.Max() : request.DesiredSegmentLengthMs))
|
||||
.AppendLine()
|
||||
.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");
|
||||
.AppendLine(CultureInfo.InvariantCulture, $"#EXT-X-MEDIA-SEQUENCE:{request.StartSegmentIndex}");
|
||||
|
||||
var index = 0;
|
||||
var index = request.StartSegmentIndex;
|
||||
|
||||
if (isHlsInFmp4)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using Jellyfin.MediaEncoding.Hls.Extractors;
|
||||
using Jellyfin.MediaEncoding.Hls.Playlist;
|
||||
using Jellyfin.MediaEncoding.Keyframes;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
|
||||
|
|
@ -96,6 +99,29 @@ namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
|
|||
return data;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateMainPlaylist_WithStartSegmentIndex_GeneratesCorrectSequence()
|
||||
{
|
||||
var configManager = new Mock<IServerConfigurationManager>();
|
||||
var generator = new DynamicHlsPlaylistGenerator(configManager.Object, Array.Empty<IKeyframeExtractor>());
|
||||
var request = new CreateMainPlaylistRequest(
|
||||
null,
|
||||
"/path/to/file.mp4",
|
||||
6000,
|
||||
600000000000,
|
||||
"mp4",
|
||||
"hls1/main/",
|
||||
"?params=1",
|
||||
false,
|
||||
startSegmentIndex: 1187);
|
||||
|
||||
var playlist = generator.CreateMainPlaylist(request);
|
||||
|
||||
Assert.Contains("#EXT-X-MEDIA-SEQUENCE:1187", playlist, StringComparison.Ordinal);
|
||||
Assert.Contains("hls1/main/1187.mp4", playlist, StringComparison.Ordinal);
|
||||
Assert.Contains("hls1/main/1188.mp4", playlist, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static long MsToTicks(int value) => TimeSpan.FromMilliseconds(value).Ticks;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue