mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-15 18:08:53 -07:00
commit
0bf1c10c44
@ -458,10 +458,8 @@ public class VideosController : BaseJellyfinApiController
|
|||||||
return BadRequest($"Input protocol {state.InputProtocol} cannot be streamed statically");
|
return BadRequest($"Input protocol {state.InputProtocol} cannot be streamed statically");
|
||||||
}
|
}
|
||||||
|
|
||||||
var outputPath = state.OutputFilePath;
|
|
||||||
|
|
||||||
// Static stream
|
// Static stream
|
||||||
if (@static.HasValue && @static.Value)
|
if (@static.HasValue && @static.Value && !(state.MediaSource.VideoType == VideoType.BluRay || state.MediaSource.VideoType == VideoType.Dvd))
|
||||||
{
|
{
|
||||||
var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath);
|
var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath);
|
||||||
|
|
||||||
@ -478,7 +476,7 @@ public class VideosController : BaseJellyfinApiController
|
|||||||
|
|
||||||
// Need to start ffmpeg (because media can't be returned directly)
|
// Need to start ffmpeg (because media can't be returned directly)
|
||||||
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
||||||
var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, outputPath, "superfast");
|
var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, "superfast");
|
||||||
return await FileStreamResponseHelpers.GetTranscodedFile(
|
return await FileStreamResponseHelpers.GetTranscodedFile(
|
||||||
state,
|
state,
|
||||||
isHeadRequest,
|
isHeadRequest,
|
||||||
|
@ -225,7 +225,7 @@ public static class StreamingHelpers
|
|||||||
|
|
||||||
var ext = string.IsNullOrWhiteSpace(state.OutputContainer)
|
var ext = string.IsNullOrWhiteSpace(state.OutputContainer)
|
||||||
? GetOutputFileExtension(state, mediaSource)
|
? GetOutputFileExtension(state, mediaSource)
|
||||||
: ("." + state.OutputContainer);
|
: ("." + GetContainerFileExtension(state.OutputContainer));
|
||||||
|
|
||||||
state.OutputFilePath = GetOutputFilePath(state, ext, serverConfigurationManager, streamingRequest.DeviceId, streamingRequest.PlaySessionId);
|
state.OutputFilePath = GetOutputFilePath(state, ext, serverConfigurationManager, streamingRequest.DeviceId, streamingRequest.PlaySessionId);
|
||||||
|
|
||||||
@ -559,4 +559,23 @@ public static class StreamingHelpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses the container into its file extension.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container">The container.</param>
|
||||||
|
private static string? GetContainerFileExtension(string? container)
|
||||||
|
{
|
||||||
|
if (string.Equals(container, "mpegts", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "ts";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(container, "matroska", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return "mkv";
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6541,13 +6541,14 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return " -codec:s:0 " + codec + " -disposition:s:0 default";
|
return " -codec:s:0 " + codec + " -disposition:s:0 default";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetProgressiveVideoFullCommandLine(EncodingJobInfo state, EncodingOptions encodingOptions, string outputPath, string defaultPreset)
|
public string GetProgressiveVideoFullCommandLine(EncodingJobInfo state, EncodingOptions encodingOptions, string defaultPreset)
|
||||||
{
|
{
|
||||||
// Get the output codec name
|
// Get the output codec name
|
||||||
var videoCodec = GetVideoEncoder(state, encodingOptions);
|
var videoCodec = GetVideoEncoder(state, encodingOptions);
|
||||||
|
|
||||||
var format = string.Empty;
|
var format = string.Empty;
|
||||||
var keyFrame = string.Empty;
|
var keyFrame = string.Empty;
|
||||||
|
var outputPath = state.OutputFilePath;
|
||||||
|
|
||||||
if (Path.GetExtension(outputPath.AsSpan()).Equals(".mp4", StringComparison.OrdinalIgnoreCase)
|
if (Path.GetExtension(outputPath.AsSpan()).Equals(".mp4", StringComparison.OrdinalIgnoreCase)
|
||||||
&& state.BaseRequest.Context == EncodingContext.Streaming)
|
&& state.BaseRequest.Context == EncodingContext.Streaming)
|
||||||
|
@ -1111,6 +1111,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
return allVobs
|
return allVobs
|
||||||
.Where(vob => titles.Contains(_fileSystem.GetFileNameWithoutExtension(vob).AsSpan().RightPart('_').ToString()))
|
.Where(vob => titles.Contains(_fileSystem.GetFileNameWithoutExtension(vob).AsSpan().RightPart('_').ToString()))
|
||||||
.Select(i => i.FullName)
|
.Select(i => i.FullName)
|
||||||
|
.Order()
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,6 +1128,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
return directoryFiles
|
return directoryFiles
|
||||||
.Where(f => validPlaybackFiles.Contains(f.Name, StringComparer.OrdinalIgnoreCase))
|
.Where(f => validPlaybackFiles.Contains(f.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
.Select(f => f.FullName)
|
.Select(f => f.FullName)
|
||||||
|
.Order()
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1150,8 +1152,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate concat configuration entries for each file and write to file
|
// Generate concat configuration entries for each file and write to file
|
||||||
using (StreamWriter sw = new StreamWriter(concatFilePath))
|
using StreamWriter sw = new StreamWriter(concatFilePath);
|
||||||
{
|
|
||||||
foreach (var path in files)
|
foreach (var path in files)
|
||||||
{
|
{
|
||||||
var mediaInfoResult = GetMediaInfo(
|
var mediaInfoResult = GetMediaInfo(
|
||||||
@ -1176,7 +1177,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
sw.WriteLine("duration {0}", duration);
|
sw.WriteLine("duration {0}", duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanExtractSubtitles(string codec)
|
public bool CanExtractSubtitles(string codec)
|
||||||
{
|
{
|
||||||
|
@ -405,7 +405,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId);
|
var user = userId.IsEmpty() ? null : _userManager.GetUserById(userId);
|
||||||
if (user is not null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
if (user is not null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
||||||
{
|
{
|
||||||
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
||||||
|
|
||||||
throw new ArgumentException("User does not have access to video transcoding.");
|
throw new ArgumentException("User does not have access to video transcoding.");
|
||||||
}
|
}
|
||||||
@ -417,7 +417,12 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
if (state.SubtitleStream is not null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
|
if (state.SubtitleStream is not null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
|
||||||
{
|
{
|
||||||
var attachmentPath = Path.Combine(_appPaths.CachePath, "attachments", state.MediaSource.Id);
|
var attachmentPath = Path.Combine(_appPaths.CachePath, "attachments", state.MediaSource.Id);
|
||||||
if (state.VideoType != VideoType.Dvd)
|
if (state.MediaSource.VideoType == VideoType.Dvd || state.MediaSource.VideoType == VideoType.BluRay)
|
||||||
|
{
|
||||||
|
var concatPath = Path.Join(_serverConfigurationManager.GetTranscodePath(), state.MediaSource.Id + ".concat");
|
||||||
|
await _attachmentExtractor.ExtractAllAttachments(concatPath, state.MediaSource, attachmentPath, cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, cancellationTokenSource.Token).ConfigureAwait(false);
|
await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@ -432,7 +437,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var process = new Process
|
using var process = new Process
|
||||||
{
|
{
|
||||||
StartInfo = new ProcessStartInfo
|
StartInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
@ -452,7 +457,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
EnableRaisingEvents = true
|
EnableRaisingEvents = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var transcodingJob = this.OnTranscodeBeginning(
|
var transcodingJob = OnTranscodeBeginning(
|
||||||
outputPath,
|
outputPath,
|
||||||
state.Request.PlaySessionId,
|
state.Request.PlaySessionId,
|
||||||
state.MediaSource.LiveStreamId,
|
state.MediaSource.LiveStreamId,
|
||||||
@ -507,7 +512,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error starting FFmpeg");
|
_logger.LogError(ex, "Error starting FFmpeg");
|
||||||
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user