mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-02 14:56:31 +01:00
improve direct play of live streams
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.Session;
|
||||
using System;
|
||||
@@ -11,13 +12,16 @@ namespace MediaBrowser.Model.Dlna
|
||||
public class StreamBuilder
|
||||
{
|
||||
private readonly ILocalPlayer _localPlayer;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public StreamBuilder(ILocalPlayer localPlayer)
|
||||
public StreamBuilder(ILocalPlayer localPlayer, ILogger logger)
|
||||
{
|
||||
_localPlayer = localPlayer;
|
||||
_logger = logger;
|
||||
}
|
||||
public StreamBuilder()
|
||||
: this(new NullLocalPlayer())
|
||||
|
||||
public StreamBuilder(ILogger logger)
|
||||
: this(new NullLocalPlayer(), logger)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -353,6 +357,12 @@ namespace MediaBrowser.Model.Dlna
|
||||
bool isEligibleForDirectPlay = IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options);
|
||||
bool isEligibleForDirectStream = IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options);
|
||||
|
||||
_logger.Debug("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
||||
options.Profile.Name ?? "Unknown Profile",
|
||||
item.Path ?? "Unknown path",
|
||||
isEligibleForDirectPlay,
|
||||
isEligibleForDirectStream);
|
||||
|
||||
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
||||
{
|
||||
// See if it can be direct played
|
||||
@@ -504,6 +514,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (directPlay == null)
|
||||
{
|
||||
_logger.Debug("Profile: {0}, No direct play profiles found for Path: {1}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -550,6 +564,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames, numVideoStreams, numAudioStreams))
|
||||
{
|
||||
_logger.Debug("Profile: {0}, DirectPlay=false. Reason=VideoContainerProfile.{1} Path: {2}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
i.Property,
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -558,6 +577,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (string.IsNullOrEmpty(videoCodec))
|
||||
{
|
||||
_logger.Debug("Profile: {0}, DirectPlay=false. Reason=Unknown video codec. Path: {1}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -577,6 +600,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames, numVideoStreams, numAudioStreams))
|
||||
{
|
||||
_logger.Debug("Profile: {0}, DirectPlay=false. Reason=VideoCodecProfile.{1} Path: {2}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
i.Property,
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -587,6 +615,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (string.IsNullOrEmpty(audioCodec))
|
||||
{
|
||||
_logger.Debug("Profile: {0}, DirectPlay=false. Reason=Unknown audio codec. Path: {1}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -607,6 +639,11 @@ namespace MediaBrowser.Model.Dlna
|
||||
bool? isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream);
|
||||
if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile, isSecondaryAudio))
|
||||
{
|
||||
_logger.Debug("Profile: {0}, DirectPlay=false. Reason=VideoAudioCodecProfile.{1} Path: {2}",
|
||||
profile.Name ?? "Unknown Profile",
|
||||
i.Property,
|
||||
mediaSource.Path ?? "Unknown path");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
public string SubtitleFormat { get; set; }
|
||||
|
||||
public string PlaySessionId { get; set; }
|
||||
public List<MediaSourceInfo> AllMediaSources { get; set; }
|
||||
|
||||
public string MediaSourceId
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.ComponentModel;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
|
||||
namespace MediaBrowser.Model.Dto
|
||||
{
|
||||
|
||||
@@ -1,26 +1,65 @@
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Model.Entities
|
||||
{
|
||||
public class MediaInfo
|
||||
public class MediaInfo : MediaSourceInfo, IHasProviderIds
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the media streams.
|
||||
/// </summary>
|
||||
/// <value>The media streams.</value>
|
||||
public List<MediaStream> MediaStreams { get; set; }
|
||||
public List<ChapterInfo> Chapters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the format.
|
||||
/// Gets or sets the title.
|
||||
/// </summary>
|
||||
/// <value>The format.</value>
|
||||
public string Format { get; set; }
|
||||
|
||||
public int? TotalBitrate { get; set; }
|
||||
/// <value>The title.</value>
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the album.
|
||||
/// </summary>
|
||||
/// <value>The album.</value>
|
||||
public string Album { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the artists.
|
||||
/// </summary>
|
||||
/// <value>The artists.</value>
|
||||
public List<string> Artists { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the album artists.
|
||||
/// </summary>
|
||||
/// <value>The album artists.</value>
|
||||
public List<string> AlbumArtists { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the studios.
|
||||
/// </summary>
|
||||
/// <value>The studios.</value>
|
||||
public List<string> Studios { get; set; }
|
||||
public List<string> Genres { get; set; }
|
||||
public int? IndexNumber { get; set; }
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
public int? ProductionYear { get; set; }
|
||||
public DateTime? PremiereDate { get; set; }
|
||||
public List<BaseItemPerson> People { get; set; }
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the official rating.
|
||||
/// </summary>
|
||||
/// <value>The official rating.</value>
|
||||
public string OfficialRating { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the overview.
|
||||
/// </summary>
|
||||
/// <value>The overview.</value>
|
||||
public string Overview { get; set; }
|
||||
|
||||
public MediaInfo()
|
||||
{
|
||||
MediaStreams = new List<MediaStream>();
|
||||
Chapters = new List<ChapterInfo>();
|
||||
Artists = new List<string>();
|
||||
AlbumArtists = new List<string>();
|
||||
Studios = new List<string>();
|
||||
Genres = new List<string>();
|
||||
People = new List<BaseItemPerson>();
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user