mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-17 19:08:53 -07:00
Merge branch 'dev' into beta
This commit is contained in:
commit
3386e8f8f7
@ -289,17 +289,5 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
|
||||
return isLiveStream;
|
||||
}
|
||||
|
||||
protected override bool CanStreamCopyAudio(StreamState state, List<string> supportedAudioCodecs)
|
||||
{
|
||||
var isLiveStream = IsLiveStream(state);
|
||||
|
||||
if (!isLiveStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CanStreamCopyAudio(state, supportedAudioCodecs);
|
||||
}
|
||||
}
|
||||
}
|
@ -500,18 +500,6 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
private bool IsLiveStream(StreamState state)
|
||||
{
|
||||
var isLiveStream = (state.RunTimeTicks ?? 0) == 0;
|
||||
|
||||
if (state.VideoRequest.ForceLiveStream)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return isLiveStream;
|
||||
}
|
||||
|
||||
private string GetMasterPlaylistFileText(StreamState state, int totalBitrate)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
@ -830,11 +818,10 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
{
|
||||
if (state.VideoStream != null && IsH264(state.VideoStream) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Enabling h264_mp4toannexb due to nal_length_size of {0}", state.VideoStream.NalLengthSize);
|
||||
args += " -bsf:v h264_mp4toannexb";
|
||||
}
|
||||
|
||||
args += " -flags -global_header -sc_threshold 0";
|
||||
args += " -flags -global_header";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -859,7 +846,12 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
args += GetGraphicalSubtitleParam(state, codec);
|
||||
}
|
||||
|
||||
args += " -flags -global_header -sc_threshold 0";
|
||||
args += " -flags -global_header";
|
||||
}
|
||||
|
||||
if (EnableCopyTs(state) && args.IndexOf("-copyts", StringComparison.OrdinalIgnoreCase) == -1)
|
||||
{
|
||||
args += " -copyts";
|
||||
}
|
||||
|
||||
return args;
|
||||
@ -867,7 +859,8 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
|
||||
private bool EnableCopyTs(StreamState state)
|
||||
{
|
||||
return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
|
||||
//return state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding)
|
||||
@ -889,24 +882,28 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
|
||||
var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty;
|
||||
|
||||
//var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state);
|
||||
var enableGenericSegmenter = false;
|
||||
|
||||
//return string.Format("{0} {11} {1}{10} -map_metadata -1 -threads {2} {3} {4} {5} -f segment -segment_time {6} -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
|
||||
// inputModifier,
|
||||
// GetInputArgument(state),
|
||||
// threads,
|
||||
// mapArgs,
|
||||
// GetVideoArguments(state),
|
||||
// GetAudioArguments(state),
|
||||
// state.SegmentLength.ToString(UsCulture),
|
||||
// startNumberParam,
|
||||
// outputPath,
|
||||
// outputTsArg,
|
||||
// slowSeekParam,
|
||||
// toTimeParam
|
||||
// ).Trim();
|
||||
if (enableGenericSegmenter)
|
||||
{
|
||||
var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state);
|
||||
|
||||
return string.Format("{0}{11} {1} -map_metadata -1 -threads {2} {3} {4}{5} {6} -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"",
|
||||
return string.Format("{0} {10} {1} -map_metadata -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
|
||||
inputModifier,
|
||||
GetInputArgument(state),
|
||||
threads,
|
||||
mapArgs,
|
||||
GetVideoArguments(state),
|
||||
GetAudioArguments(state),
|
||||
state.SegmentLength.ToString(UsCulture),
|
||||
startNumberParam,
|
||||
outputPath,
|
||||
outputTsArg,
|
||||
toTimeParam
|
||||
).Trim();
|
||||
}
|
||||
|
||||
return string.Format("{0}{11} {1} -map_metadata -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7} -start_number {8} -hls_list_size {9} -y \"{10}\"",
|
||||
inputModifier,
|
||||
GetInputArgument(state),
|
||||
threads,
|
||||
@ -946,10 +943,10 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
{
|
||||
var isLiveStream = IsLiveStream(state);
|
||||
|
||||
if (!isLiveStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//if (!isLiveStream && Request.QueryString["AllowCustomSegmenting"] != "true")
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
|
||||
return base.CanStreamCopyVideo(state);
|
||||
}
|
||||
|
@ -89,7 +89,6 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
// if h264_mp4toannexb is ever added, do not use it for live tv
|
||||
if (state.VideoStream != null && IsH264(state.VideoStream) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Enabling h264_mp4toannexb due to nal_length_size of {0}", state.VideoStream.NalLengthSize);
|
||||
args += " -bsf:v h264_mp4toannexb";
|
||||
}
|
||||
return args;
|
||||
|
@ -141,7 +141,6 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||
{
|
||||
if (state.VideoStream != null && IsH264(state.VideoStream) && string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Enabling h264_mp4toannexb due to nal_length_size of {0}", state.VideoStream.NalLengthSize);
|
||||
args += " -bsf:v h264_mp4toannexb";
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,19 @@ namespace MediaBrowser.Api.Playback
|
||||
|
||||
public List<string> PlayableStreamFileNames { get; set; }
|
||||
|
||||
public int SegmentLength = 3;
|
||||
public int SegmentLength
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
public int HlsListSize
|
||||
{
|
||||
get
|
||||
|
@ -75,7 +75,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||
{
|
||||
if (state.VideoStream != null && IsH264(state.VideoStream) && string.Equals(state.Options.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Debug("Enabling h264_mp4toannexb due to nal_length_size of {0}", state.VideoStream.NalLengthSize);
|
||||
args += " -bsf:v h264_mp4toannexb";
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
[XmlAttribute("protocol")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
|
||||
[XmlAttribute("estimateContentLength")]
|
||||
public bool EstimateContentLength { get; set; }
|
||||
|
||||
|
@ -304,7 +304,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
|
||||
|
||||
if (otherDuplicatePaths.Count > 0)
|
||||
{
|
||||
var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, otherDuplicatePaths);
|
||||
var msg = string.Format("File '{0}' already exists as these:'{1}'. Stopping organization", sourcePath, string.Join("', '", otherDuplicatePaths));
|
||||
_logger.Info(msg);
|
||||
result.Status = FileSortingStatus.SkippedExisting;
|
||||
result.StatusMessage = msg;
|
||||
|
@ -179,6 +179,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
private void OnWebSocketConnecting(WebSocketConnectingEventArgs args)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebSocketConnecting != null)
|
||||
{
|
||||
WebSocketConnecting(this, args);
|
||||
@ -187,6 +192,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
private void OnWebSocketConnected(WebSocketConnectEventArgs args)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebSocketConnected != null)
|
||||
{
|
||||
WebSocketConnected(this, args);
|
||||
@ -331,6 +341,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
var httpRes = httpReq.Response;
|
||||
|
||||
if (_disposed)
|
||||
{
|
||||
httpRes.StatusCode = 503;
|
||||
httpRes.Close();
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
var operationName = httpReq.OperationName;
|
||||
var localPath = url.LocalPath;
|
||||
|
||||
|
@ -224,7 +224,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||
|
||||
var stream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
//await AddMediaInfo(stream, false, resourcePool, cancellationToken).ConfigureAwait(false);
|
||||
if (EnableMediaProbing)
|
||||
{
|
||||
await AddMediaInfo(stream, false, resourcePool, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return new Tuple<MediaSourceInfo, SemaphoreSlim>(stream, resourcePool);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -239,6 +243,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||
throw new LiveTvConflictException();
|
||||
}
|
||||
|
||||
protected virtual bool EnableMediaProbing
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
@ -268,6 +277,25 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||
return _semaphoreLocks.GetOrAdd(url, key => new SemaphoreSlim(1, 1));
|
||||
}
|
||||
|
||||
private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
|
||||
{
|
||||
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
await AddMediaInfoInternal(mediaSource, isAudio, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Leave the resource locked. it will be released upstream
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Release the resource if there's some kind of failure.
|
||||
resourcePool.Release();
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
|
||||
{
|
||||
var originalRuntime = mediaSource.RunTimeTicks;
|
||||
|
@ -71,6 +71,8 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// <value>The web socket listeners.</value>
|
||||
private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>();
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerManager" /> class.
|
||||
/// </summary>
|
||||
@ -143,6 +145,11 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// <param name="e">The <see cref="WebSocketConnectEventArgs" /> instance containing the event data.</param>
|
||||
void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
|
||||
{
|
||||
OnReceive = ProcessWebSocketMessageReceived,
|
||||
@ -164,6 +171,11 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// <param name="result">The result.</param>
|
||||
private async void ProcessWebSocketMessageReceived(WebSocketMessageInfo result)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//_logger.Debug("Websocket message received: {0}", result.MessageType);
|
||||
|
||||
var tasks = _webSocketListeners.Select(i => Task.Run(async () =>
|
||||
@ -244,6 +256,11 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
throw new ArgumentNullException("dataFunction");
|
||||
}
|
||||
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var connectionsList = connections.Where(s => s.State == WebSocketState.Open).ToList();
|
||||
@ -301,6 +318,8 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
@ -555,9 +555,10 @@ namespace MediaBrowser.ServerApplication
|
||||
|
||||
private static void ShutdownWindowsApplication()
|
||||
{
|
||||
_logger.Info("Calling Application.Exit");
|
||||
Application.Exit();
|
||||
//_logger.Info("Calling Application.Exit");
|
||||
//Application.Exit();
|
||||
|
||||
_logger.Info("Calling Environment.Exit");
|
||||
Environment.Exit(0);
|
||||
|
||||
_logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
|
||||
|
Loading…
Reference in New Issue
Block a user