Merge pull request #2381 from MediaBrowser/dev

Dev
pull/1154/head
Luke 8 years ago committed by GitHub
commit 0a202a58f8

@ -176,6 +176,18 @@ namespace Emby.Dlna.Didl
return new NullLogger();
}
private string GetMimeType(string input)
{
var mime = MimeTypes.GetMimeType(input);
if (string.Equals(mime, "video/mp2t", StringComparison.OrdinalIgnoreCase))
{
mime = "video/mpeg";
}
return mime;
}
private void AddVideoResource(DlnaOptions options, XmlWriter writer, IHasMediaSources video, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
if (streamInfo == null)
@ -360,7 +372,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
? MimeTypes.GetMimeType(filename)
? GetMimeType(filename)
: mediaProfile.MimeType;
writer.WriteAttributeString("protocolInfo", String.Format(
@ -481,7 +493,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
? MimeTypes.GetMimeType(filename)
? GetMimeType(filename)
: mediaProfile.MimeType;
var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container,
@ -760,7 +772,7 @@ namespace Emby.Dlna.Didl
// Seeing some LG models locking up due content with large lists of people
// The actual issue might just be due to processing a more metadata than it can handle
var limit = 10;
var limit = 6;
foreach (var actor in people)
{
@ -1007,7 +1019,7 @@ namespace Emby.Dlna.Didl
writer.WriteAttributeString("protocolInfo", String.Format(
"http-get:*:{0}:{1}",
MimeTypes.GetMimeType("file." + format),
GetMimeType("file." + format),
contentFeatures
));

@ -23,7 +23,7 @@ namespace Emby.Dlna.Profiles
{
Match = HeaderMatchType.Substring,
Name = "User-Agent",
Value ="XiP"
Value ="Zip_"
}
}
};
@ -63,22 +63,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
Container = "mp3",
AudioCodec = "mp3",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "alac",
AudioCodec = "alac",
Type = DlnaProfileType.Audio
},
new DirectPlayProfile
{
Container = "flac",
AudioCodec = "flac",
Container = "mp3,alac,flac",
Type = DlnaProfileType.Audio
},

@ -86,7 +86,9 @@ namespace Emby.Dlna.Profiles
{
Container = "mp3",
AudioCodec = "mp3",
Type = DlnaProfileType.Audio
Type = DlnaProfileType.Audio,
// Transcoded audio won't be playable at all without this
TranscodeSeekInfo = TranscodeSeekInfo.Bytes
},
new TranscodingProfile
{

@ -5,7 +5,7 @@
<Manufacturer>Echostar Technologies LLC</Manufacturer>
<ManufacturerUrl>http://www.echostar.com</ManufacturerUrl>
<Headers>
<HttpHeaderInfo name="User-Agent" value="XiP" match="Substring" />
<HttpHeaderInfo name="User-Agent" value="Zip_" match="Substring" />
</Headers>
</Identification>
<Manufacturer>Emby</Manufacturer>
@ -37,9 +37,7 @@
<XmlRootAttributes />
<DirectPlayProfiles>
<DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" />
<DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
<DirectPlayProfile container="alac" audioCodec="alac" type="Audio" />
<DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
<DirectPlayProfile container="mp3,alac,flac" type="Audio" />
<DirectPlayProfile container="jpeg" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>

@ -45,7 +45,7 @@
<DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
</DirectPlayProfiles>
<TranscodingProfiles>
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
<TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
<TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
<TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
</TranscodingProfiles>

@ -106,6 +106,11 @@ namespace Emby.Server.Core.EntryPoints
private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e)
{
if (_disposed)
{
return;
}
var info = e.Argument;
string usn;
@ -169,6 +174,11 @@ namespace Emby.Server.Core.EntryPoints
return;
}
if (_disposed)
{
return;
}
_logger.Debug("Calling Nat.Handle on " + identifier);
NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp);
}
@ -185,6 +195,11 @@ namespace Emby.Server.Core.EntryPoints
void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
{
if (_disposed)
{
return;
}
try
{
var device = e.Device;
@ -210,6 +225,11 @@ namespace Emby.Server.Core.EntryPoints
private List<string> _usnsHandled = new List<string>();
private void CreateRules(INatDevice device)
{
if (_disposed)
{
throw new ObjectDisposedException("PortMapper");
}
// On some systems the device discovered event seems to fire repeatedly
// This check will help ensure we're not trying to port map the same device over and over
@ -249,8 +269,10 @@ namespace Emby.Server.Core.EntryPoints
_logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString());
}
private bool _disposed = false;
public void Dispose()
{
_disposed = true;
DisposeNat();
}

@ -288,6 +288,13 @@ namespace Emby.Server.Core.IO
{
try
{
if (!_fileSystem.DirectoryExists(path))
{
// Seeing a crash in the mono runtime due to an exception being thrown on a different thread
Logger.Info("Skipping realtime monitor for {0} because the path does not exist", path);
return;
}
var newWatcher = new FileSystemWatcher(path, "*")
{
IncludeSubdirectories = true

@ -9,6 +9,7 @@ using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Threading;
@ -26,8 +27,9 @@ namespace Emby.Server.Implementations.Connect
private readonly IApplicationHost _appHost;
private readonly IFileSystem _fileSystem;
private readonly ITimerFactory _timerFactory;
private readonly IEncryptionManager _encryption;
public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost, IFileSystem fileSystem, ITimerFactory timerFactory)
public ConnectEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager, IConnectManager connectManager, IApplicationHost appHost, IFileSystem fileSystem, ITimerFactory timerFactory, IEncryptionManager encryption)
{
_httpClient = httpClient;
_appPaths = appPaths;
@ -37,6 +39,7 @@ namespace Emby.Server.Implementations.Connect
_appHost = appHost;
_fileSystem = fileSystem;
_timerFactory = timerFactory;
_encryption = encryption;
}
public void Run()
@ -143,7 +146,7 @@ namespace Emby.Server.Implementations.Connect
private string CacheFilePath
{
get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
get { return Path.Combine(_appPaths.DataPath, "wan.dat"); }
}
private void CacheAddress(IpAddressInfo address)
@ -153,7 +156,14 @@ namespace Emby.Server.Implementations.Connect
try
{
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
_fileSystem.WriteAllText(path, address.ToString(), Encoding.UTF8);
}
catch (Exception ex)
{
}
try
{
_fileSystem.WriteAllText(path, _encryption.EncryptString(address.ToString()), Encoding.UTF8);
}
catch (Exception ex)
{
@ -169,7 +179,7 @@ namespace Emby.Server.Implementations.Connect
try
{
var endpoint = _fileSystem.ReadAllText(path, Encoding.UTF8);
var endpoint = _encryption.DecryptString(_fileSystem.ReadAllText(path, Encoding.UTF8));
IpAddressInfo ipAddress;
if (_networkManager.TryParseIpAddress(endpoint, out ipAddress))

@ -2548,57 +2548,53 @@ namespace Emby.Server.Implementations.Data
{
using (var connection = CreateConnection(true))
{
return connection.RunInTransaction(db =>
{
var list = new List<BaseItem>();
var list = new List<BaseItem>();
using (var statement = PrepareStatementSafe(db, commandText))
using (var statement = PrepareStatementSafe(connection, commandText))
{
if (EnableJoinUserData(query))
{
if (EnableJoinUserData(query))
{
statement.TryBind("@UserId", query.User.Id);
}
statement.TryBind("@UserId", query.User.Id);
}
BindSimilarParams(query, statement);
BindSimilarParams(query, statement);
// Running this again will bind the params
GetWhereClauses(query, statement);
// Running this again will bind the params
GetWhereClauses(query, statement);
foreach (var row in statement.ExecuteQuery())
foreach (var row in statement.ExecuteQuery())
{
var item = GetItem(row, query);
if (item != null)
{
var item = GetItem(row, query);
if (item != null)
{
list.Add(item);
}
list.Add(item);
}
}
}
// Hack for right now since we currently don't support filtering out these duplicates within a query
if (query.EnableGroupByMetadataKey)
// Hack for right now since we currently don't support filtering out these duplicates within a query
if (query.EnableGroupByMetadataKey)
{
var limit = query.Limit ?? int.MaxValue;
limit -= 4;
var newList = new List<BaseItem>();
foreach (var item in list)
{
var limit = query.Limit ?? int.MaxValue;
limit -= 4;
var newList = new List<BaseItem>();
AddItem(newList, item);
foreach (var item in list)
if (newList.Count >= limit)
{
AddItem(newList, item);
if (newList.Count >= limit)
{
break;
}
break;
}
list = newList;
}
LogQueryTime("GetItemList", commandText, now);
list = newList;
}
return list;
LogQueryTime("GetItemList", commandText, now);
}, ReadTransactionMode);
return list;
}
}
}

@ -182,7 +182,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
programsInfo.Add(GetProgram(channelNumber, schedule, programDict[schedule.programID]));
}
_logger.Info("Finished with EPGData");
}
}
@ -322,8 +321,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
using (var response = await Get(httpOptions, true, info).ConfigureAwait(false))
{
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
_logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
_logger.Info("Mapping Stations to Channel");
foreach (ScheduleDirect.Map map in root.map)
{
var channelNumber = map.logicalChannelNumber;
@ -353,7 +351,6 @@ namespace Emby.Server.Implementations.LiveTv.Listings
});
}
}
_logger.Info("Added " + GetChannelPairCacheCount(listingsId) + " channels to the dictionary");
foreach (ChannelInfo channel in channels)
{

@ -103,7 +103,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
TunerHostId = info.Id,
IsHD = i.HD == 1,
AudioCodec = i.AudioCodec,
VideoCodec = i.VideoCodec
VideoCodec = i.VideoCodec,
ChannelType = ChannelType.TV
});
}

@ -4,7 +4,7 @@ namespace Emby.Server.Implementations.Sync
{
public class SyncHelper
{
public static int? AdjustBitrate(int? profileBitrate, string quality)
public static long? AdjustBitrate(long? profileBitrate, string quality)
{
if (profileBitrate.HasValue)
{

@ -59,15 +59,8 @@ namespace Emby.Server.Implementations.Sync
_mediaSourceManager = mediaSourceManager;
}
public async Task EnsureJobItems(SyncJob job)
public async Task EnsureJobItems(SyncJob job, User user)
{
var user = _userManager.GetUserById(job.UserId);
if (user == null)
{
throw new InvalidOperationException("Cannot proceed with sync because user no longer exists.");
}
var items = (await GetItemsForSync(job.Category, job.ParentId, job.RequestedItemIds, user, job.UnwatchedOnly).ConfigureAwait(false))
.ToList();
@ -385,7 +378,16 @@ namespace Emby.Server.Implementations.Sync
if (job.SyncNewContent)
{
await EnsureJobItems(job).ConfigureAwait(false);
var user = _userManager.GetUserById(job.UserId);
if (user == null)
{
await _syncManager.CancelJob(job.Id).ConfigureAwait(false);
}
else
{
await EnsureJobItems(job, user).ConfigureAwait(false);
}
}
}
}

@ -181,7 +181,7 @@ namespace Emby.Server.Implementations.Sync
await _repo.Create(job).ConfigureAwait(false);
await processor.EnsureJobItems(job).ConfigureAwait(false);
await processor.EnsureJobItems(job, user).ConfigureAwait(false);
// If it already has a converting status then is must have been aborted during conversion
var jobItemsResult = GetJobItems(new SyncJobItemQuery

@ -205,7 +205,8 @@ namespace MediaBrowser.Api.Playback
}
else
{
args += "-map -0:v";
// No known video stream
args += "-vn";
}
if (state.AudioStream != null)
@ -395,8 +396,6 @@ namespace MediaBrowser.Api.Playback
{
param += " -crf 23";
}
param += " -tune zerolatency";
}
else if (string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase))
@ -536,6 +535,11 @@ namespace MediaBrowser.Api.Playback
}
}
if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase))
{
param += " -x264opts:0 subme=0:rc_lookahead=10:me_range=4:me=dia:no_chroma_me:8x8dct=0:partitions=none";
}
if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase))
@ -1492,8 +1496,16 @@ namespace MediaBrowser.Api.Playback
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
}
if (string.Equals(videoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
// h264
return string.Format(" -maxrate {0} -bufsize {1}",
bitrate.Value.ToString(UsCulture),
(bitrate.Value * 2).ToString(UsCulture));
}
// h264
return string.Format(" -maxrate {0} -bufsize {1}",
return string.Format(" -b:v {0} -maxrate {0} -bufsize {1}",
bitrate.Value.ToString(UsCulture),
(bitrate.Value * 2).ToString(UsCulture));
}

@ -103,7 +103,7 @@ namespace MediaBrowser.Api.Playback.Hls
throw;
}
var waitForSegments = state.SegmentLength >= 10 ? 2 : (state.SegmentLength > 3 || !isLive ? 3 : 3);
var waitForSegments = state.SegmentLength >= 10 ? 2 : 3;
await WaitForMinimumSegmentCount(playlist, waitForSegments, cancellationTokenSource.Token).ConfigureAwait(false);
}
}

@ -265,9 +265,15 @@ namespace MediaBrowser.Api.Playback.Hls
double startSeconds = 0;
var lengths = GetSegmentLengths(state);
if (requestedIndex >= lengths.Length)
{
var msg = string.Format("Invalid segment index requested: {0} - Segment count: {1}", requestedIndex, lengths.Length);
throw new ArgumentException(msg);
}
for (var i = 0; i < requestedIndex; i++)
{
startSeconds += lengths[requestedIndex];
startSeconds += lengths[i];
}
var position = TimeSpan.FromSeconds(startSeconds).Ticks;
@ -279,9 +285,15 @@ namespace MediaBrowser.Api.Playback.Hls
double startSeconds = 0;
var lengths = GetSegmentLengths(state);
if (requestedIndex >= lengths.Length)
{
var msg = string.Format("Invalid segment index requested: {0} - Segment count: {1}", requestedIndex, lengths.Length);
throw new ArgumentException(msg);
}
for (var i = 0; i <= requestedIndex; i++)
{
startSeconds += lengths[requestedIndex];
startSeconds += lengths[i];
}
var position = TimeSpan.FromSeconds(startSeconds).Ticks;
@ -348,6 +360,8 @@ namespace MediaBrowser.Api.Playback.Hls
return;
}
Logger.Debug("Deleting partial HLS file {0}", file.FullName);
try
{
FileSystem.DeleteFile(file.FullName);
@ -723,7 +737,7 @@ namespace MediaBrowser.Api.Playback.Hls
foreach (var length in segmentLengths)
{
builder.AppendLine("#EXTINF:" + length.ToString("0.0000", UsCulture) + ",");
builder.AppendLine("#EXTINF:" + length.ToString("0.0000", UsCulture) + ", nodesc");
builder.AppendLine(string.Format("hls1/{0}/{1}{2}{3}",
@ -826,7 +840,7 @@ namespace MediaBrowser.Api.Playback.Hls
args += " -bsf:v h264_mp4toannexb";
}
args += " -flags -global_header";
//args += " -flags -global_header";
}
else
{
@ -851,7 +865,7 @@ namespace MediaBrowser.Api.Playback.Hls
args += GetGraphicalSubtitleParam(state, codec);
}
args += " -flags -global_header";
//args += " -flags -global_header";
}
if (EnableCopyTs(state) && args.IndexOf("-copyts", StringComparison.OrdinalIgnoreCase) == -1)
@ -875,27 +889,25 @@ namespace MediaBrowser.Api.Playback.Hls
var inputModifier = GetInputModifier(state, false);
// If isEncoding is true we're actually starting ffmpeg
var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0";
var toTimeParam = string.Empty;
var timestampOffsetParam = string.Empty;
if (state.IsOutputVideo && !EnableCopyTs(state) && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0)
{
timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0);
}
var startNumber = GetStartNumber(state);
var startNumberParam = isEncoding ? startNumber.ToString(UsCulture) : "0";
var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty;
var enableSplittingOnNonKeyFrames = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && false;
var useGenericSegmenter = true;
// TODO: check libavformat version for 57 50.100 and use -hls_flags split_by_time
var hlsProtocolSupportsSplittingByTime = false;
if (enableSplittingOnNonKeyFrames && !hlsProtocolSupportsSplittingByTime)
if (useGenericSegmenter)
{
var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state);
return string.Format("{0} {10} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -break_non_keyframes 1 -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
var timeDeltaParam = String.Empty;
if (isEncoding && startNumber > 0)
{
var startTime = state.SegmentLength * startNumber;
timeDeltaParam = string.Format("-segment_time_delta -{0}", startTime);
}
return string.Format("{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} {10} -individual_header_trailer 0 -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
inputModifier,
GetInputArgument(state),
threads,
@ -906,27 +918,21 @@ namespace MediaBrowser.Api.Playback.Hls
startNumberParam,
outputPath,
outputTsArg,
toTimeParam
).Trim();
timeDeltaParam
).Trim();
}
var splitByTime = hlsProtocolSupportsSplittingByTime && enableSplittingOnNonKeyFrames;
var splitByTimeArg = splitByTime ? " -hls_flags split_by_time" : "";
return string.Format("{0}{12} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7}{8} -start_number {9} -hls_list_size {10} -y \"{11}\"",
return string.Format("{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {6} -individual_header_trailer 0 -start_number {7} -hls_list_size {8} -y \"{9}\"",
inputModifier,
GetInputArgument(state),
threads,
mapArgs,
GetVideoArguments(state),
timestampOffsetParam,
GetAudioArguments(state),
state.SegmentLength.ToString(UsCulture),
splitByTimeArg,
startNumberParam,
state.HlsListSize.ToString(UsCulture),
outputPath,
toTimeParam
outputPath
).Trim();
}

@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Playback
PlaybackInfoResponse result,
DeviceProfile profile,
AuthorizationInfo auth,
int? maxBitrate,
long? maxBitrate,
long startTimeTicks,
string mediaSourceId,
int? audioStreamIndex,
@ -249,7 +249,7 @@ namespace MediaBrowser.Api.Playback
MediaSourceInfo mediaSource,
DeviceProfile profile,
AuthorizationInfo auth,
int? maxBitrate,
long? maxBitrate,
long startTimeTicks,
string mediaSourceId,
int? audioStreamIndex,
@ -383,7 +383,7 @@ namespace MediaBrowser.Api.Playback
}
}
private int? GetMaxBitrate(int? clientMaxBitrate)
private long? GetMaxBitrate(long? clientMaxBitrate)
{
var maxBitrate = clientMaxBitrate;
var remoteClientMaxBitrate = _config.Configuration.RemoteClientBitrateLimit;
@ -425,7 +425,7 @@ namespace MediaBrowser.Api.Playback
}
}
private void SortMediaSources(PlaybackInfoResponse result, int? maxBitrate)
private void SortMediaSources(PlaybackInfoResponse result, long? maxBitrate)
{
var originalList = result.MediaSources.ToList();

@ -93,13 +93,9 @@ namespace MediaBrowser.Api.Playback
{
return 3;
}
return 6;
}
if (!RunTimeTicks.HasValue)
{
return 3;
}
return 3;
}
}

@ -243,6 +243,8 @@ namespace MediaBrowser.Api.Session
[ApiMember(Name = "SupportsPersistentIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool SupportsPersistentIdentifier { get; set; }
public bool SupportsContentUploading { get; set; }
public PostCapabilities()
{
SupportsPersistentIdentifier = true;
@ -559,6 +561,8 @@ namespace MediaBrowser.Api.Session
SupportsSync = request.SupportsSync,
SupportsContentUploading = request.SupportsContentUploading,
SupportsPersistentIdentifier = request.SupportsPersistentIdentifier
});
}

@ -827,8 +827,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
}
if (string.Equals(videoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
{
// h264
return string.Format(" -maxrate {0} -bufsize {1}",
bitrate.Value.ToString(UsCulture),
(bitrate.Value * 2).ToString(UsCulture));
}
// h264
return string.Format(" -maxrate {0} -bufsize {1}",
return string.Format(" -b:v {0} -maxrate {0} -bufsize {1}",
bitrate.Value.ToString(UsCulture),
(bitrate.Value * 2).ToString(UsCulture));
}
@ -896,7 +904,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
else
{
args += "-map -0:v";
// No known video stream
args += "-vn";
}
if (state.AudioStream != null)

@ -41,7 +41,7 @@ namespace MediaBrowser.Model.Dlna
/// <summary>
/// The application's configured quality setting
/// </summary>
public int? MaxBitrate { get; set; }
public long? MaxBitrate { get; set; }
/// <summary>
/// Gets or sets the context.
@ -59,7 +59,7 @@ namespace MediaBrowser.Model.Dlna
/// Gets the maximum bitrate.
/// </summary>
/// <returns>System.Nullable&lt;System.Int32&gt;.</returns>
public int? GetMaxBitrate(bool isAudio)
public long? GetMaxBitrate(bool isAudio)
{
if (MaxBitrate.HasValue)
{

@ -51,8 +51,8 @@ namespace MediaBrowser.Model.Dlna
public int? MaxIconWidth { get; set; }
public int? MaxIconHeight { get; set; }
public int? MaxStreamingBitrate { get; set; }
public int? MaxStaticBitrate { get; set; }
public long? MaxStreamingBitrate { get; set; }
public long? MaxStaticBitrate { get; set; }
public int? MusicStreamingTranscodingBitrate { get; set; }
public int? MaxStaticMusicBitrate { get; set; }

@ -93,7 +93,7 @@ namespace MediaBrowser.Model.Dlna
return GetOptimalStream(streams, options.GetMaxBitrate(false));
}
private StreamInfo GetOptimalStream(List<StreamInfo> streams, int? maxBitrate)
private StreamInfo GetOptimalStream(List<StreamInfo> streams, long? maxBitrate)
{
streams = StreamInfoSorter.SortMediaSources(streams, maxBitrate);
@ -277,25 +277,26 @@ namespace MediaBrowser.Model.Dlna
playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue);
}
int transcodingBitrate = options.AudioTranscodingBitrate ??
long transcodingBitrate = options.AudioTranscodingBitrate ??
options.Profile.MusicStreamingTranscodingBitrate ??
128000;
int? configuredBitrate = options.GetMaxBitrate(true);
var configuredBitrate = options.GetMaxBitrate(true);
if (configuredBitrate.HasValue)
{
transcodingBitrate = Math.Min(configuredBitrate.Value, transcodingBitrate);
}
playlistItem.AudioBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
var longBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
playlistItem.AudioBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
}
return playlistItem;
}
private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio)
private long? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio)
{
if (item.Protocol == MediaProtocol.File)
{
@ -583,11 +584,11 @@ namespace MediaBrowser.Model.Dlna
int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream);
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
int? maxBitrateSetting = options.GetMaxBitrate(false);
var maxBitrateSetting = options.GetMaxBitrate(false);
// Honor max rate
if (maxBitrateSetting.HasValue)
{
int videoBitrate = maxBitrateSetting.Value;
var videoBitrate = maxBitrateSetting.Value;
if (playlistItem.AudioBitrate.HasValue)
{
@ -595,15 +596,16 @@ namespace MediaBrowser.Model.Dlna
}
// Make sure the video bitrate is lower than bitrate settings but at least 64k
int currentValue = playlistItem.VideoBitrate ?? videoBitrate;
playlistItem.VideoBitrate = Math.Max(Math.Min(videoBitrate, currentValue), 64000);
long currentValue = playlistItem.VideoBitrate ?? videoBitrate;
var longBitrate = Math.Max(Math.Min(videoBitrate, currentValue), 64000);
playlistItem.VideoBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
}
}
return playlistItem;
}
private int GetAudioBitrate(string subProtocol, int? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
{
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? 192000;
// Reduce the bitrate if we're downmixing
@ -865,7 +867,7 @@ namespace MediaBrowser.Model.Dlna
}
private bool IsEligibleForDirectPlay(MediaSourceInfo item,
int? maxBitrate,
long? maxBitrate,
MediaStream subtitleStream,
VideoOptions options,
PlayMethod playMethod)
@ -960,7 +962,7 @@ namespace MediaBrowser.Model.Dlna
return null;
}
private bool IsAudioEligibleForDirectPlay(MediaSourceInfo item, int? maxBitrate)
private bool IsAudioEligibleForDirectPlay(MediaSourceInfo item, long? maxBitrate)
{
if (!maxBitrate.HasValue)
{

@ -7,7 +7,7 @@ namespace MediaBrowser.Model.Dlna
{
public class StreamInfoSorter
{
public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams, int? maxBitrate)
public static List<StreamInfo> SortMediaSources(List<StreamInfo> streams, long? maxBitrate)
{
return streams.OrderBy(i =>
{

@ -7,7 +7,7 @@ namespace MediaBrowser.Model.MediaInfo
public string OpenToken { get; set; }
public string UserId { get; set; }
public string PlaySessionId { get; set; }
public int? MaxStreamingBitrate { get; set; }
public long? MaxStreamingBitrate { get; set; }
public long? StartTimeTicks { get; set; }
public int? AudioStreamIndex { get; set; }
public int? SubtitleStreamIndex { get; set; }

@ -8,7 +8,7 @@ namespace MediaBrowser.Model.MediaInfo
public string UserId { get; set; }
public int? MaxStreamingBitrate { get; set; }
public long? MaxStreamingBitrate { get; set; }
public long? StartTimeTicks { get; set; }

@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Session
public List<string> SupportedCommands { get; set; }
public bool SupportsMediaControl { get; set; }
public bool SupportsContentUploading { get; set; }
public string MessageCallbackUrl { get; set; }
public bool SupportsPersistentIdentifier { get; set; }

@ -36,6 +36,7 @@
DisplayMessage = 28,
SetRepeatMode = 29,
ChannelUp = 30,
ChannelDown = 31
ChannelDown = 31,
SetMaxStreamingBitrate = 31
}
}

@ -93,6 +93,12 @@ namespace MediaBrowser.Providers.TV
return;
}
// Check this in order to avoid logging an exception due to directory not existing
if (!_fileSystem.DirectoryExists(seriesDataPath))
{
return;
}
var episodeFiles = _fileSystem.GetFilePaths(seriesDataPath)
.Where(i => string.Equals(Path.GetExtension(i), ".xml", StringComparison.OrdinalIgnoreCase))
.Select(Path.GetFileNameWithoutExtension)

@ -143,7 +143,8 @@ namespace MediaBrowser.Providers.TV
Url = ServerTimeUrl,
CancellationToken = cancellationToken,
EnableHttpCompression = true,
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool,
BufferContent = false
}).ConfigureAwait(false))
{
@ -239,7 +240,8 @@ namespace MediaBrowser.Providers.TV
Url = string.Format(UpdatesUrl, lastUpdateTime),
CancellationToken = cancellationToken,
EnableHttpCompression = true,
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool,
BufferContent = false
}).ConfigureAwait(false))
{

@ -237,7 +237,8 @@ namespace MediaBrowser.Providers.TV
{
Url = url,
ResourcePool = TvDbResourcePool,
CancellationToken = cancellationToken
CancellationToken = cancellationToken,
BufferContent = false
}).ConfigureAwait(false))
{
@ -281,7 +282,8 @@ namespace MediaBrowser.Providers.TV
{
Url = url,
ResourcePool = TvDbResourcePool,
CancellationToken = cancellationToken
CancellationToken = cancellationToken,
BufferContent = false
}).ConfigureAwait(false))
{
@ -535,7 +537,8 @@ namespace MediaBrowser.Providers.TV
{
Url = url,
ResourcePool = TvDbResourcePool,
CancellationToken = cancellationToken
CancellationToken = cancellationToken,
BufferContent = false
}).ConfigureAwait(false))
{
@ -1664,7 +1667,8 @@ namespace MediaBrowser.Providers.TV
{
CancellationToken = cancellationToken,
Url = url,
ResourcePool = TvDbResourcePool
ResourcePool = TvDbResourcePool,
BufferContent = false
});
}
}

@ -162,9 +162,6 @@
<Content Include="dashboard-ui\components\remotecontrol.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\remotecontrolautoplay.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\tvproviders\xmltv.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -258,6 +255,9 @@
<Content Include="dashboard-ui\css\images\empty.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\videoosd.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\touchicon144.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -420,9 +420,6 @@
<Content Include="dashboard-ui\devices\ios\ios.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\htmlmediarenderer.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\sections.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -648,9 +645,6 @@
<Content Include="dashboard-ui\css\livetv.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\mediaplayer-video.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\nowplaying.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -816,9 +810,6 @@
<Content Include="dashboard-ui\scripts\channelslatest.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\chromecast.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\dashboard\cinemamodeconfiguration.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -903,9 +894,6 @@
<Content Include="dashboard-ui\scripts\mediacontroller.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\mediaplayer-video.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\metadatasubtitles.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -978,6 +966,9 @@
<Content Include="dashboard-ui\userpassword.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\videoosd.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\wizardagreement.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1027,9 +1018,6 @@
<Content Include="dashboard-ui\scripts\notifications.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\remotecontrol.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\moviecollections.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1388,9 +1376,6 @@
<Content Include="dashboard-ui\css\images\clients\dlna.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\mediaplayer.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="dashboard-ui\strings\ar.json">

@ -245,7 +245,7 @@ namespace Rssdp.Infrastructure
return;
}
WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget));
//WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget));
if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint))
{

Loading…
Cancel
Save