Merge pull request #10990 from Shadowghost/bdmv-fixes

BDMV fixes
pull/11013/head
Bond-009 8 months ago committed by GitHub
commit 0bf1c10c44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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,31 +1152,29 @@ 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(
{ new MediaInfoRequest
var mediaInfoResult = GetMediaInfo( {
new MediaInfoRequest MediaType = DlnaProfileType.Video,
MediaSource = new MediaSourceInfo
{ {
MediaType = DlnaProfileType.Video, Path = path,
MediaSource = new MediaSourceInfo Protocol = MediaProtocol.File,
{ VideoType = videoType
Path = path, }
Protocol = MediaProtocol.File, },
VideoType = videoType CancellationToken.None).GetAwaiter().GetResult();
}
}, var duration = TimeSpan.FromTicks(mediaInfoResult.RunTimeTicks.Value).TotalSeconds;
CancellationToken.None).GetAwaiter().GetResult();
// Add file path stanza to concat configuration
var duration = TimeSpan.FromTicks(mediaInfoResult.RunTimeTicks.Value).TotalSeconds; sw.WriteLine("file '{0}'", path);
// Add file path stanza to concat configuration // Add duration stanza to concat configuration
sw.WriteLine("file '{0}'", path); sw.WriteLine("duration {0}", duration);
// Add duration stanza to concat configuration
sw.WriteLine("duration {0}", duration);
}
} }
} }

@ -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…
Cancel
Save