aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--Emby.Server.Implementations/Localization/Core/mr.json44
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs15
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs27
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs2
5 files changed, 70 insertions, 19 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 1f0e028c1..f23ecf942 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -155,6 +155,7 @@
- [MBR-0001](https://github.com/MBR-0001)
- [jonas-resch](https://github.com/jonas-resch)
- [vgambier](https://github.com/vgambier)
+ - [MinecraftPlaye](https://github.com/MinecraftPlaye)
# Emby Contributors
diff --git a/Emby.Server.Implementations/Localization/Core/mr.json b/Emby.Server.Implementations/Localization/Core/mr.json
index fdb4171b5..5aad4b0ed 100644
--- a/Emby.Server.Implementations/Localization/Core/mr.json
+++ b/Emby.Server.Implementations/Localization/Core/mr.json
@@ -58,5 +58,47 @@
"Application": "अ‍ॅप्लिकेशन",
"AppDeviceValues": "अ‍ॅप: {0}, यंत्र: {1}",
"Collections": "संग्रह",
- "ChapterNameValue": "धडा {0}"
+ "ChapterNameValue": "धडा {0}",
+ "TaskDownloadMissingSubtitlesDescription": "नसलेल्या उपशिर्षकांचा मेटाडॅटा कॉन्फिग्युरेशनप्रमाणे इन्टरनेटवर शोध घेतो.",
+ "TaskRefreshChannelsDescription": "इन्टरनेट वाहिन्यांची माहिती ताजी करतो.",
+ "TaskUpdatePluginsDescription": "आपोआप अपडेट करण्यासाठी कॉन्फिगर केलेल्या प्लगइनसाठी अपडेट डाउनलोड करून इन्स्टॉल करतो.",
+ "TaskRefreshChannels": "वाहिन्या ताज्या करा",
+ "TaskRefreshPeopleDescription": "आपल्या माध्यम संग्रहातील अभिनेत्यांचा व दिग्दर्शकांचा मेटाडॅटा ताजा करतो.",
+ "TaskRefreshPeople": "लोकांची माहिती ताजी करा",
+ "TaskRefreshLibraryDescription": "माध्यम संग्रह स्कॅन करून नवीन फायली शोधतो व मेटाडॅटा ताजे करतो.",
+ "TaskRefreshLibrary": "माध्यम संग्रह स्कॅन करा",
+ "TaskRefreshChapterImagesDescription": "अध्याय असलेल्या व्हिडियोंसाठी थंबनेल चित्र बनवतो.",
+ "TaskRefreshChapterImages": "अध्याय चित्र काढून घ्या",
+ "TasksMaintenanceCategory": "देखरेख",
+ "ValueHasBeenAddedToLibrary": "{0} हे तुमच्या माध्यम संग्रहात जोडण्यात आले आहे",
+ "UserStoppedPlayingItemWithValues": "{0} यांचं {2} वर {1} पूर्णपणे प्ले करून झालं आहे",
+ "UserStartedPlayingItemWithValues": "{0} हे {2} वर {1} प्ले करत आहे",
+ "UserDownloadingItemWithValues": "{0} हे {1} डाउनलोड करत आहे",
+ "System": "प्रणाली",
+ "Undefined": "अव्याख्यात",
+ "Sync": "सिंक",
+ "ServerNameNeedsToBeRestarted": "{0} याला बंद करून पुन्हा सुरू करायची गरज आहे",
+ "SubtitleDownloadFailureFromForItem": "{0} येथून {1} यासाठी उपशिर्षक डाउनलोड करण्यात अपयश",
+ "ScheduledTaskStartedWithName": "{0} सुरू झाले",
+ "ScheduledTaskFailedWithName": "{0} अपयशी झाले",
+ "ProviderValue": "पुरवणारा: {0}",
+ "PluginUpdatedWithName": "{0} अपडेट केले",
+ "PluginUninstalledWithName": "{0} अनिन्स्टॉल केले",
+ "PluginInstalledWithName": "{0} इन्स्टॉल केले",
+ "NotificationOptionVideoPlaybackStopped": "व्हिडियो प्लेबॅक बंद केले",
+ "NotificationOptionVideoPlayback": "व्हिडियो प्लेबॅक सुरू केले",
+ "NotificationOptionTaskFailed": "अनुसूचित कार्यात अपयश",
+ "NotificationOptionServerRestartRequired": "सर्व्हर बंद करून पुन्हा सुरू करावा लागेल",
+ "NotificationOptionPluginUpdateInstalled": "प्लगइन अपडेट इन्स्टॉल झाले",
+ "NotificationOptionPluginUninstalled": "प्लगइन अनिन्स्टॉल झाले",
+ "NotificationOptionPluginInstalled": "प्लगइन इन्स्टॉल झाले",
+ "NotificationOptionPluginError": "प्लगइनमध्ये अपयश",
+ "NotificationOptionNewLibraryContent": "नवीन सामग्री जोडली गेली",
+ "NotificationOptionInstallationFailed": "इन्स्टॉल करण्यात अपयश",
+ "NotificationOptionAudioPlayback": "ऑडियो प्लेबॅक सुरू झाले",
+ "NotificationOptionAudioPlaybackStopped": "ऑडियो प्लेबॅक बंद झाले",
+ "MixedContent": "मिश्रित सामग्री",
+ "LabelRunningTimeValue": "चालू काल: {0}",
+ "HeaderContinueWatching": "बघणे चालू ठेवा",
+ "Default": "डीफॉल्ट"
}
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index af6916630..f8e8d975c 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -1599,7 +1599,6 @@ namespace Jellyfin.Api.Controllers
state.BaseRequest.BreakOnNonKeyFrames = false;
}
- var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions);
var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty;
var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath));
@@ -1608,12 +1607,15 @@ namespace Jellyfin.Api.Controllers
var outputExtension = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer);
var outputTsArg = outputPrefix + "%d" + outputExtension;
- var segmentFormat = outputExtension.TrimStart('.');
- if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase))
+ var segmentFormat = string.Empty;
+ var segmentContainer = outputExtension.TrimStart('.');
+ var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions, segmentContainer);
+
+ if (string.Equals(segmentContainer, "ts", StringComparison.OrdinalIgnoreCase))
{
segmentFormat = "mpegts";
}
- else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(segmentContainer, "mp4", StringComparison.OrdinalIgnoreCase))
{
var outputFmp4HeaderArg = OperatingSystem.IsWindows() switch
{
@@ -1627,7 +1629,8 @@ namespace Jellyfin.Api.Controllers
}
else
{
- _logger.LogError("Invalid HLS segment container: {SegmentFormat}", segmentFormat);
+ _logger.LogError("Invalid HLS segment container: {SegmentContainer}, default to mpegts", segmentContainer);
+ segmentFormat = "mpegts";
}
var maxMuxingQueueSize = _encodingOptions.MaxMuxingQueueSize > 128
@@ -1647,7 +1650,7 @@ namespace Jellyfin.Api.Controllers
CultureInfo.InvariantCulture,
"{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -max_muxing_queue_size {6} -f hls -max_delay 5000000 -hls_time {7} -hls_segment_type {8} -start_number {9}{10} -hls_segment_filename \"{12}\" -hls_playlist_type {11} -hls_list_size 0 -y \"{13}\"",
inputModifier,
- _encodingHelper.GetInputArgument(state, _encodingOptions),
+ _encodingHelper.GetInputArgument(state, _encodingOptions, segmentContainer),
threads,
mapArgs,
GetVideoArguments(state, startNumber, isEventPlaylist),
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index f4e0ca24a..2e7349f00 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -842,8 +842,9 @@ namespace MediaBrowser.Controller.MediaEncoding
/// </summary>
/// <param name="state">Encoding state.</param>
/// <param name="options">Encoding options.</param>
+ /// <param name="segmentContainer">Segment Container.</param>
/// <returns>Input arguments.</returns>
- public string GetInputArgument(EncodingJobInfo state, EncodingOptions options)
+ public string GetInputArgument(EncodingJobInfo state, EncodingOptions options, string segmentContainer)
{
var arg = new StringBuilder();
var inputVidHwaccelArgs = GetInputVideoHwaccelArgs(state, options);
@@ -880,7 +881,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Also seek the external subtitles stream.
- var seekSubParam = GetFastSeekCommandLineParameter(state, options);
+ var seekSubParam = GetFastSeekCommandLineParameter(state, options, segmentContainer);
if (!string.IsNullOrEmpty(seekSubParam))
{
arg.Append(' ').Append(seekSubParam);
@@ -897,7 +898,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.AudioStream != null && state.AudioStream.IsExternal)
{
// Also seek the external audio stream.
- var seekAudioParam = GetFastSeekCommandLineParameter(state, options);
+ var seekAudioParam = GetFastSeekCommandLineParameter(state, options, segmentContainer);
if (!string.IsNullOrEmpty(seekAudioParam))
{
arg.Append(' ').Append(seekAudioParam);
@@ -2167,9 +2168,10 @@ namespace MediaBrowser.Controller.MediaEncoding
/// </summary>
/// <param name="state">The state.</param>
/// <param name="options">The options.</param>
+ /// <param name="segmentContainer">Segment Container.</param>
/// <returns>System.String.</returns>
/// <value>The fast seek command line parameter.</value>
- public string GetFastSeekCommandLineParameter(EncodingJobInfo state, EncodingOptions options)
+ public string GetFastSeekCommandLineParameter(EncodingJobInfo state, EncodingOptions options, string segmentContainer)
{
var time = state.BaseRequest.StartTimeTicks ?? 0;
var seekParam = string.Empty;
@@ -2181,11 +2183,14 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.IsVideoRequest)
{
var outputVideoCodec = GetVideoEncoder(state, options);
+ var segmentFormat = GetSegmentFileExtension(segmentContainer).TrimStart('.');
// Important: If this is ever re-enabled, make sure not to use it with wtv because it breaks seeking
+ // Disable -noaccurate_seek on mpegts container due to the timestamps issue on some clients,
+ // but it's still required for fMP4 container otherwise the audio can't be synced to the video.
if (!string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase)
+ && !string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)
&& state.TranscodingType != TranscodingJobType.Progressive
- && state.TranscodingType != TranscodingJobType.Hls
&& !state.EnableBreakOnNonKeyFrames(outputVideoCodec)
&& (state.BaseRequest.StartTimeTicks ?? 0) > 0)
{
@@ -4836,7 +4841,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOptions)
+ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOptions, string segmentContainer)
{
var inputModifier = string.Empty;
var probeSizeArgument = string.Empty;
@@ -4872,7 +4877,7 @@ namespace MediaBrowser.Controller.MediaEncoding
inputModifier = inputModifier.Trim();
- inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions);
+ inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions, segmentContainer);
inputModifier = inputModifier.Trim();
if (state.InputProtocol == MediaProtocol.Rtsp)
@@ -5179,13 +5184,13 @@ namespace MediaBrowser.Controller.MediaEncoding
var threads = GetNumberOfThreads(state, encodingOptions, videoCodec);
- var inputModifier = GetInputModifier(state, encodingOptions);
+ var inputModifier = GetInputModifier(state, encodingOptions, null);
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7}{8} -y \"{9}\"",
inputModifier,
- GetInputArgument(state, encodingOptions),
+ GetInputArgument(state, encodingOptions, null),
keyFrame,
GetMapArgs(state),
GetProgressiveVideoArguments(state, encodingOptions, videoCodec, defaultPreset),
@@ -5367,13 +5372,13 @@ namespace MediaBrowser.Controller.MediaEncoding
var threads = GetNumberOfThreads(state, encodingOptions, null);
- var inputModifier = GetInputModifier(state, encodingOptions);
+ var inputModifier = GetInputModifier(state, encodingOptions, null);
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}{7}{8} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1{6} -y \"{5}\"",
inputModifier,
- GetInputArgument(state, encodingOptions),
+ GetInputArgument(state, encodingOptions, null),
threads,
" -vn",
string.Join(' ', audioTranscodeParams),
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 341e4846e..e2616d92a 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -161,7 +161,7 @@ namespace MediaBrowser.Model.Entities
attributes.Add(StringHelper.FirstToUpper(fullLanguage ?? Language));
}
- if (!string.IsNullOrEmpty(Codec) && !string.Equals(Codec, "dca", StringComparison.OrdinalIgnoreCase))
+ if (!string.IsNullOrEmpty(Codec) && !string.Equals(Codec, "dca", StringComparison.OrdinalIgnoreCase) && !string.Equals(Codec, "dts", StringComparison.OrdinalIgnoreCase))
{
attributes.Add(AudioCodec.GetFriendlyName(Codec));
}