Do better to make sure hls files are cleaned up
This commit is contained in:
parent
06a11c27d9
commit
1a323767be
|
@ -71,8 +71,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
private void DeleteEncodedMediaCache()
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(_appPaths.TranscodingTempPath)
|
||||
.Where(i => EntityResolutionHelper.VideoFileExtensions.Contains(Path.GetExtension(i)))
|
||||
foreach (var file in Directory.EnumerateFiles(_appPaths.TranscodingTempPath, "*", SearchOption.AllDirectories)
|
||||
.ToList())
|
||||
{
|
||||
File.Delete(file);
|
||||
|
@ -116,11 +115,10 @@ namespace MediaBrowser.Api
|
|||
/// <param name="path">The path.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="process">The process.</param>
|
||||
/// <param name="isVideo">if set to <c>true</c> [is video].</param>
|
||||
/// <param name="startTimeTicks">The start time ticks.</param>
|
||||
/// <param name="sourcePath">The source path.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process, bool isVideo, long? startTimeTicks, string sourcePath, string deviceId)
|
||||
public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process, long? startTimeTicks, string sourcePath, string deviceId)
|
||||
{
|
||||
lock (_activeTranscodingJobs)
|
||||
{
|
||||
|
@ -130,7 +128,6 @@ namespace MediaBrowser.Api
|
|||
Path = path,
|
||||
Process = process,
|
||||
ActiveRequestCount = 1,
|
||||
IsVideo = isVideo,
|
||||
StartTimeTicks = startTimeTicks,
|
||||
SourcePath = sourcePath,
|
||||
DeviceId = deviceId
|
||||
|
@ -261,7 +258,7 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
// This is really only needed for HLS.
|
||||
// Progressive streams can stop on their own reliably
|
||||
jobs.AddRange(_activeTranscodingJobs.Where(i => isVideo == i.IsVideo && string.Equals(deviceId, i.DeviceId, StringComparison.OrdinalIgnoreCase)));
|
||||
jobs.AddRange(_activeTranscodingJobs.Where(i => string.Equals(deviceId, i.DeviceId, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
foreach (var job in jobs)
|
||||
|
@ -325,37 +322,15 @@ namespace MediaBrowser.Api
|
|||
}
|
||||
}
|
||||
|
||||
// Determine if it exited successfully
|
||||
var hasExitedSuccessfully = false;
|
||||
|
||||
try
|
||||
{
|
||||
hasExitedSuccessfully = process.ExitCode == 0;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Dispose the process
|
||||
process.Dispose();
|
||||
|
||||
// If it didn't complete successfully cleanup the partial files
|
||||
// Also don't cache output from resume points
|
||||
// Also don't cache video
|
||||
if (!hasExitedSuccessfully || job.StartTimeTicks.HasValue || job.IsVideo)
|
||||
{
|
||||
DeletePartialStreamFiles(job.Path, job.Type, 0, 1500);
|
||||
}
|
||||
DeletePartialStreamFiles(job.Path, job.Type, 0, 1500);
|
||||
}
|
||||
|
||||
private async void DeletePartialStreamFiles(string path, TranscodingJobType jobType, int retryCount, int delayMs)
|
||||
{
|
||||
if (retryCount >= 5)
|
||||
if (retryCount >= 10)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -455,7 +430,6 @@ namespace MediaBrowser.Api
|
|||
/// <value>The kill timer.</value>
|
||||
public Timer KillTimer { get; set; }
|
||||
|
||||
public bool IsVideo { get; set; }
|
||||
public long? StartTimeTicks { get; set; }
|
||||
public string SourcePath { get; set; }
|
||||
public string DeviceId { get; set; }
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
|
||||
[ApiMember(Name = "RecentlyPlayedGamesLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public int RecentlyPlayedGamesLimit { get; set; }
|
||||
|
||||
public string ParentId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/MBT/DefaultTheme/TV", "GET")]
|
||||
|
@ -49,6 +51,8 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
|
||||
[ApiMember(Name = "LatestEpisodeLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public int LatestEpisodeLimit { get; set; }
|
||||
|
||||
public string ParentId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/MBT/DefaultTheme/Movies", "GET")]
|
||||
|
@ -71,6 +75,8 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
|
||||
[ApiMember(Name = "LatestTrailersLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
|
||||
public int LatestTrailersLimit { get; set; }
|
||||
|
||||
public string ParentId { get; set; }
|
||||
}
|
||||
|
||||
[Route("/MBT/DefaultTheme/Favorites", "GET")]
|
||||
|
@ -224,7 +230,7 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var items = user.RootFolder.GetRecursiveChildren(user, i => i is Game || i is GameSystem)
|
||||
var items = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId).Where(i => i is Game || i is GameSystem)
|
||||
.ToList();
|
||||
|
||||
var gamesWithImages = items.OfType<Game>().Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)).ToList();
|
||||
|
@ -280,7 +286,7 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var series = user.RootFolder.GetRecursiveChildren(user)
|
||||
var series = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId)
|
||||
.OfType<Series>()
|
||||
.ToList();
|
||||
|
||||
|
@ -403,7 +409,8 @@ namespace MediaBrowser.Api.DefaultTheme
|
|||
{
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var items = user.RootFolder.GetRecursiveChildren(user, i => i is Movie || i is Trailer || i is BoxSet)
|
||||
var items = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId)
|
||||
.Where(i => i is Movie || i is Trailer || i is BoxSet)
|
||||
.ToList();
|
||||
|
||||
var view = new MoviesView();
|
||||
|
|
|
@ -903,7 +903,7 @@ namespace MediaBrowser.Api.Playback
|
|||
EnableRaisingEvents = true
|
||||
};
|
||||
|
||||
ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process, state.IsInputVideo, state.Request.StartTimeTicks, state.MediaPath, state.Request.DeviceId);
|
||||
ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process, state.Request.StartTimeTicks, state.MediaPath, state.Request.DeviceId);
|
||||
|
||||
var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments;
|
||||
Logger.Info(commandLineLogMessage);
|
||||
|
|
|
@ -273,9 +273,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
|
||||
const string keyFrameArg = " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
|
||||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
|
||||
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
|
||||
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
|
||||
|
||||
|
|
|
@ -168,9 +168,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
|||
" -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+1))" :
|
||||
" -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
|
||||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
|
||||
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
|
||||
|
||||
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;
|
||||
|
||||
|
|
|
@ -146,9 +146,7 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
|
||||
args += keyFrameArg;
|
||||
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
|
||||
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
|
||||
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
|
||||
|
||||
var request = state.VideoRequest;
|
||||
|
||||
|
|
|
@ -305,13 +305,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
|||
|
||||
if (!ParentIndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||
{
|
||||
ParentIndexNumber = TVUtils.GetSeasonNumberFromPath(Path);
|
||||
|
||||
// If a change was made record it
|
||||
if (ParentIndexNumber.HasValue)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
ParentIndexNumber = TVUtils.GetSeasonNumberFromEpisodeFile(Path);
|
||||
}
|
||||
|
||||
// If a change was made record it
|
||||
|
|
|
@ -52,14 +52,30 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public int GetLimit(ImageType type)
|
||||
{
|
||||
ImageOption option = ImageOptions.FirstOrDefault(i => i.Type == type);
|
||||
ImageOption option = null;
|
||||
foreach (ImageOption i in ImageOptions)
|
||||
{
|
||||
if (i.Type == type)
|
||||
{
|
||||
option = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return option == null ? 1 : option.Limit;
|
||||
}
|
||||
|
||||
public int GetMinWidth(ImageType type)
|
||||
{
|
||||
ImageOption option = ImageOptions.FirstOrDefault(i => i.Type == type);
|
||||
ImageOption option = null;
|
||||
foreach (ImageOption i in ImageOptions)
|
||||
{
|
||||
if (i.Type == type)
|
||||
{
|
||||
option = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return option == null ? 0 : option.MinWidth;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,11 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public NotificationOption GetOptions(string type)
|
||||
{
|
||||
return Options.FirstOrDefault(i => string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase));
|
||||
foreach (NotificationOption i in Options)
|
||||
{
|
||||
if (string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase)) return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsEnabled(string type)
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
PluginUpdateInstalled,
|
||||
PluginUninstalled,
|
||||
NewLibraryContent,
|
||||
NewLibraryContentMultiple,
|
||||
ServerRestartRequired,
|
||||
TaskFailed,
|
||||
VideoPlayback
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using MediaBrowser.Model.MediaInfo;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
{
|
||||
|
@ -158,11 +157,21 @@ namespace MediaBrowser.Model.Dlna
|
|||
|
||||
if (string.IsNullOrEmpty(orgPn))
|
||||
{
|
||||
orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)
|
||||
.FirstOrDefault();
|
||||
foreach (string s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp))
|
||||
{
|
||||
orgPn = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(orgPn))
|
||||
{
|
||||
// TODO: Support multiple values and return multiple headers?
|
||||
orgPn = (orgPn ?? string.Empty).Split(',').FirstOrDefault();
|
||||
foreach (string s in (orgPn ?? string.Empty).Split(','))
|
||||
{
|
||||
orgPn = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
|
||||
|
@ -191,16 +200,12 @@ namespace MediaBrowser.Model.Dlna
|
|||
return format.HasValue ? format.Value.ToString() : null;
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
|
||||
private List<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
|
||||
{
|
||||
return new MediaFormatProfileResolver()
|
||||
.ResolveVideoFormat(container,
|
||||
videoCodec,
|
||||
audioCodec,
|
||||
width,
|
||||
height,
|
||||
timestamp)
|
||||
.Select(i => i.ToString());
|
||||
List<string> list = new List<string>();
|
||||
foreach (MediaFormatProfile i in new MediaFormatProfileResolver().ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp))
|
||||
list.Add(i.ToString());
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
_all = string.Equals(filter, "*", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
_fields = (filter ?? string.Empty)
|
||||
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.ToList();
|
||||
List<string> list = new List<string>();
|
||||
foreach (string s in (filter ?? string.Empty).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
|
||||
list.Add(s);
|
||||
_fields = list;
|
||||
}
|
||||
|
||||
public bool Contains(string field)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MediaBrowser.Model.Dlna
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace MediaBrowser.Model.Entities
|
||||
{
|
||||
|
@ -128,6 +130,20 @@ namespace MediaBrowser.Model.Entities
|
|||
/// <value><c>true</c> if this instance is external; otherwise, <c>false</c>.</value>
|
||||
public bool IsExternal { get; set; }
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool IsGraphicalSubtitleStream
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsExternal) return false;
|
||||
|
||||
var codec = Codec ?? string.Empty;
|
||||
|
||||
return codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the filename.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Model.Web
|
||||
|
@ -24,7 +25,7 @@ namespace MediaBrowser.Model.Web
|
|||
/// <param name="value">The value.</param>
|
||||
public void Add(string name, int value)
|
||||
{
|
||||
Add(name, value.ToString());
|
||||
Add(name, value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -34,7 +35,7 @@ namespace MediaBrowser.Model.Web
|
|||
/// <param name="value">The value.</param>
|
||||
public void Add(string name, long value)
|
||||
{
|
||||
Add(name, value.ToString());
|
||||
Add(name, value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -44,7 +45,7 @@ namespace MediaBrowser.Model.Web
|
|||
/// <param name="value">The value.</param>
|
||||
public void Add(string name, double value)
|
||||
{
|
||||
Add(name, value.ToString());
|
||||
Add(name, value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -135,7 +136,7 @@ namespace MediaBrowser.Model.Web
|
|||
throw new ArgumentNullException("value");
|
||||
}
|
||||
|
||||
Add(name, string.Join(",", value.Select(v => v.ToString()).ToArray()));
|
||||
Add(name, string.Join(",", value.Select(v => v.ToString(CultureInfo.InvariantCulture)).ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -188,7 +189,7 @@ namespace MediaBrowser.Model.Web
|
|||
/// <param name="name">The name.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="delimiter">The delimiter.</param>
|
||||
/// <exception cref="System.ArgumentNullException">value</exception>
|
||||
/// <exception cref="ArgumentNullException">value</exception>
|
||||
public void Add(string name, IEnumerable<string> value, string delimiter)
|
||||
{
|
||||
if (value == null)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Events;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Common.ScheduledTasks;
|
||||
using MediaBrowser.Common.Updates;
|
||||
|
@ -247,10 +248,10 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
|
|||
DisposeLibraryUpdateTimer();
|
||||
}
|
||||
|
||||
var item = items.FirstOrDefault();
|
||||
|
||||
if (item != null)
|
||||
if (items.Count == 1)
|
||||
{
|
||||
var item = items.First();
|
||||
|
||||
var notification = new NotificationRequest
|
||||
{
|
||||
NotificationType = NotificationType.NewLibraryContent.ToString()
|
||||
|
@ -258,10 +259,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
|
|||
|
||||
notification.Variables["Name"] = item.Name;
|
||||
|
||||
if (items.Count > 1)
|
||||
await SendNotification(notification).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var notification = new NotificationRequest
|
||||
{
|
||||
notification.Name = items.Count + " new library items.";
|
||||
}
|
||||
NotificationType = NotificationType.NewLibraryContentMultiple.ToString()
|
||||
};
|
||||
|
||||
notification.Variables["ItemCount"] = items.Count.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
await SendNotification(notification).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -568,6 +568,7 @@
|
|||
"NotificationOptionTaskFailed": "Scheduled task failure",
|
||||
"NotificationOptionInstallationFailed": "Installation failure",
|
||||
"NotificationOptionNewLibraryContent": "New content added",
|
||||
"NotificationOptionNewLibraryContentMultiple": "New content added (multiple)",
|
||||
"SendNotificationHelp": "By default, notifications are delivered to the dashboard inbox. Browse the plugin catalog to install additional notification options.",
|
||||
"NotificationOptionServerRestartRequired": "Server restart required",
|
||||
"LabelNotificationEnabled": "Enable this notification",
|
||||
|
@ -716,5 +717,9 @@
|
|||
"LabelDownloadLanguages": "Download languages:",
|
||||
"ButtonRegister": "Register",
|
||||
"LabelSkipIfAudioTrackPresent": "Skip if the default audio track matches the download language",
|
||||
"LabelSkipIfAudioTrackPresentHelp": "Uncheck this to ensure all videos have subtitles, regardless of audio language."
|
||||
"LabelSkipIfAudioTrackPresentHelp": "Uncheck this to ensure all videos have subtitles, regardless of audio language.",
|
||||
"HeaderSendMessage": "Send Message",
|
||||
"ButtonSend": "Send",
|
||||
"LabelMessageText": "Message text:",
|
||||
"LabelMessageTitle": "Message title:"
|
||||
}
|
|
@ -90,6 +90,13 @@ namespace MediaBrowser.Server.Implementations.Notifications
|
|||
Variables = new List<string>{"Name"}
|
||||
},
|
||||
|
||||
new NotificationTypeInfo
|
||||
{
|
||||
Type = NotificationType.NewLibraryContentMultiple.ToString(),
|
||||
DefaultTitle = "{ItemCount} new items have been added to your media library.",
|
||||
Variables = new List<string>{"ItemCount"}
|
||||
},
|
||||
|
||||
new NotificationTypeInfo
|
||||
{
|
||||
Type = NotificationType.AudioPlayback.ToString(),
|
||||
|
|
|
@ -440,6 +440,187 @@ namespace OpenSubtitlesHandler
|
|||
}
|
||||
return new MethodResponseError("Fail", "Search Subtitles call failed !");
|
||||
}
|
||||
|
||||
public static async Task<IMethodResponse> SearchSubtitlesAsync(SubtitleSearchParameters[] parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
if (TOKEN == "")
|
||||
{
|
||||
OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
|
||||
return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
|
||||
}
|
||||
if (parameters == null)
|
||||
{
|
||||
OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
|
||||
return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
|
||||
}
|
||||
if (parameters.Length == 0)
|
||||
{
|
||||
OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
|
||||
return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
|
||||
}
|
||||
// Method call ..
|
||||
List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
|
||||
// Add token param
|
||||
parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
|
||||
// Add subtitle search parameters. Each one will be like 'array' of structs.
|
||||
XmlRpcValueArray array = new XmlRpcValueArray();
|
||||
foreach (SubtitleSearchParameters param in parameters)
|
||||
{
|
||||
XmlRpcValueStruct strct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
|
||||
// sublanguageid member
|
||||
XmlRpcStructMember member = new XmlRpcStructMember("sublanguageid",
|
||||
new XmlRpcValueBasic(param.SubLangaugeID, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
// moviehash member
|
||||
if (param.MovieHash.Length > 0 && param.MovieByteSize > 0)
|
||||
{
|
||||
member = new XmlRpcStructMember("moviehash",
|
||||
new XmlRpcValueBasic(param.MovieHash, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
// moviehash member
|
||||
member = new XmlRpcStructMember("moviebytesize",
|
||||
new XmlRpcValueBasic(param.MovieByteSize, XmlRpcBasicValueType.Int));
|
||||
strct.Members.Add(member);
|
||||
}
|
||||
if (param.Query.Length > 0)
|
||||
{
|
||||
member = new XmlRpcStructMember("query",
|
||||
new XmlRpcValueBasic(param.Query, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
}
|
||||
|
||||
if (param.Episode.Length > 0 && param.Season.Length > 0)
|
||||
{
|
||||
member = new XmlRpcStructMember("season",
|
||||
new XmlRpcValueBasic(param.Season, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
member = new XmlRpcStructMember("episode",
|
||||
new XmlRpcValueBasic(param.Episode, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
}
|
||||
|
||||
// imdbid member
|
||||
if (param.IMDbID.Length > 0)
|
||||
{
|
||||
member = new XmlRpcStructMember("imdbid",
|
||||
new XmlRpcValueBasic(param.IMDbID, XmlRpcBasicValueType.String));
|
||||
strct.Members.Add(member);
|
||||
}
|
||||
// Add the struct to the array
|
||||
array.Values.Add(strct);
|
||||
}
|
||||
// Add the array to the parameters
|
||||
parms.Add(array);
|
||||
// Call !
|
||||
XmlRpcMethodCall call = new XmlRpcMethodCall("SearchSubtitles", parms);
|
||||
OSHConsole.WriteLine("Sending SearchSubtitles request to the server ...", DebugCode.Good);
|
||||
// Send the request to the server
|
||||
string response = Utilities.GetStreamString(await Utilities.SendRequestAsync(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT, cancellationToken).ConfigureAwait(false));
|
||||
|
||||
if (!response.Contains("ERROR:"))
|
||||
{
|
||||
// No error occur, get and decode the response.
|
||||
XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
|
||||
if (calls.Length > 0)
|
||||
{
|
||||
if (calls[0].Parameters.Count > 0)
|
||||
{
|
||||
// We expect Struct of 3 members:
|
||||
//* the first is status
|
||||
//* the second is [array of structs, each one includes subtitle file].
|
||||
//* the third is [double basic value] represent seconds token by server.
|
||||
XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
|
||||
// Create the response, we'll need it later
|
||||
MethodResponseSubtitleSearch R = new MethodResponseSubtitleSearch();
|
||||
// To make sure response is not currepted by server, do it in loop
|
||||
foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
|
||||
{
|
||||
if (MEMBER.Name == "status")
|
||||
{
|
||||
R.Status = (string)MEMBER.Data.Data;
|
||||
OSHConsole.WriteLine("Status= " + R.Status);
|
||||
}
|
||||
else if (MEMBER.Name == "seconds")
|
||||
{
|
||||
R.Seconds = (double)MEMBER.Data.Data;
|
||||
OSHConsole.WriteLine("Seconds= " + R.Seconds);
|
||||
}
|
||||
else if (MEMBER.Name == "data")
|
||||
{
|
||||
if (MEMBER.Data is XmlRpcValueArray)
|
||||
{
|
||||
OSHConsole.WriteLine("Search results: ");
|
||||
|
||||
XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
|
||||
foreach (IXmlRpcValue subStruct in rarray.Values)
|
||||
{
|
||||
if (subStruct == null) continue;
|
||||
if (!(subStruct is XmlRpcValueStruct)) continue;
|
||||
|
||||
SubtitleSearchResult result = new SubtitleSearchResult();
|
||||
foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
|
||||
{
|
||||
// To avoid errors of arranged info or missing ones, let's do it with switch..
|
||||
switch (submember.Name)
|
||||
{
|
||||
case "IDMovie": result.IDMovie = submember.Data.Data.ToString(); break;
|
||||
case "IDMovieImdb": result.IDMovieImdb = submember.Data.Data.ToString(); break;
|
||||
case "IDSubMovieFile": result.IDSubMovieFile = submember.Data.Data.ToString(); break;
|
||||
case "IDSubtitle": result.IDSubtitle = submember.Data.Data.ToString(); break;
|
||||
case "IDSubtitleFile": result.IDSubtitleFile = submember.Data.Data.ToString(); break;
|
||||
case "ISO639": result.ISO639 = submember.Data.Data.ToString(); break;
|
||||
case "LanguageName": result.LanguageName = submember.Data.Data.ToString(); break;
|
||||
case "MovieByteSize": result.MovieByteSize = submember.Data.Data.ToString(); break;
|
||||
case "MovieHash": result.MovieHash = submember.Data.Data.ToString(); break;
|
||||
case "MovieImdbRating": result.MovieImdbRating = submember.Data.Data.ToString(); break;
|
||||
case "MovieName": result.MovieName = submember.Data.Data.ToString(); break;
|
||||
case "MovieNameEng": result.MovieNameEng = submember.Data.Data.ToString(); break;
|
||||
case "MovieReleaseName": result.MovieReleaseName = submember.Data.Data.ToString(); break;
|
||||
case "MovieTimeMS": result.MovieTimeMS = submember.Data.Data.ToString(); break;
|
||||
case "MovieYear": result.MovieYear = submember.Data.Data.ToString(); break;
|
||||
case "SubActualCD": result.SubActualCD = submember.Data.Data.ToString(); break;
|
||||
case "SubAddDate": result.SubAddDate = submember.Data.Data.ToString(); break;
|
||||
case "SubAuthorComment": result.SubAuthorComment = submember.Data.Data.ToString(); break;
|
||||
case "SubBad": result.SubBad = submember.Data.Data.ToString(); break;
|
||||
case "SubDownloadLink": result.SubDownloadLink = submember.Data.Data.ToString(); break;
|
||||
case "SubDownloadsCnt": result.SubDownloadsCnt = submember.Data.Data.ToString(); break;
|
||||
case "SeriesEpisode": result.SeriesEpisode = submember.Data.Data.ToString(); break;
|
||||
case "SeriesSeason": result.SeriesSeason = submember.Data.Data.ToString(); break;
|
||||
case "SubFileName": result.SubFileName = submember.Data.Data.ToString(); break;
|
||||
case "SubFormat": result.SubFormat = submember.Data.Data.ToString(); break;
|
||||
case "SubHash": result.SubHash = submember.Data.Data.ToString(); break;
|
||||
case "SubLanguageID": result.SubLanguageID = submember.Data.Data.ToString(); break;
|
||||
case "SubRating": result.SubRating = submember.Data.Data.ToString(); break;
|
||||
case "SubSize": result.SubSize = submember.Data.Data.ToString(); break;
|
||||
case "SubSumCD": result.SubSumCD = submember.Data.Data.ToString(); break;
|
||||
case "UserID": result.UserID = submember.Data.Data.ToString(); break;
|
||||
case "UserNickName": result.UserNickName = submember.Data.Data.ToString(); break;
|
||||
case "ZipDownloadLink": result.ZipDownloadLink = submember.Data.Data.ToString(); break;
|
||||
}
|
||||
}
|
||||
R.Results.Add(result);
|
||||
OSHConsole.WriteLine(">" + result.ToString());
|
||||
}
|
||||
}
|
||||
else// Unknown data ?
|
||||
{
|
||||
OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return the response to user !!
|
||||
return R;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OSHConsole.WriteLine(response, DebugCode.Error);
|
||||
return new MethodResponseError("Fail", response);
|
||||
}
|
||||
return new MethodResponseError("Fail", "Search Subtitles call failed !");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download subtitle file(s)
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in New Issue
Block a user