Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
e0e2614543
|
@ -290,22 +290,14 @@ namespace MediaBrowser.Api.Playback
|
|||
/// <returns>System.String.</returns>
|
||||
protected string GetTextSubtitleParam(Video video, MediaStream subtitleStream, long? startTimeTicks)
|
||||
{
|
||||
var path = subtitleStream.IsExternal ? GetConvertedAssPath(video, subtitleStream) : GetExtractedAssPath(video, subtitleStream, startTimeTicks);
|
||||
var path = subtitleStream.IsExternal ? GetConvertedAssPath(video, subtitleStream, startTimeTicks) : GetExtractedAssPath(video, subtitleStream, startTimeTicks);
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var param = string.Format(",ass='{0}'", path.Replace('\\', '/').Replace(":/", "\\:/"));
|
||||
|
||||
if (startTimeTicks.HasValue && subtitleStream.IsExternal)
|
||||
{
|
||||
var seconds = Convert.ToInt32(TimeSpan.FromTicks(startTimeTicks.Value).TotalSeconds);
|
||||
param += string.Format(",setpts=PTS-{0}/TB", seconds);
|
||||
}
|
||||
|
||||
return param;
|
||||
return string.Format(",ass='{0}'", path.Replace('\\', '/').Replace(":/", "\\:/"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -347,16 +339,21 @@ namespace MediaBrowser.Api.Playback
|
|||
/// </summary>
|
||||
/// <param name="video">The video.</param>
|
||||
/// <param name="subtitleStream">The subtitle stream.</param>
|
||||
/// <param name="startTimeTicks">The start time ticks.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetConvertedAssPath(Video video, MediaStream subtitleStream)
|
||||
private string GetConvertedAssPath(Video video, MediaStream subtitleStream, long? startTimeTicks)
|
||||
{
|
||||
var path = Kernel.Instance.FFMpegManager.GetSubtitleCachePath(video, subtitleStream.Index, null, ".ass");
|
||||
var offset = startTimeTicks.HasValue
|
||||
? TimeSpan.FromTicks(startTimeTicks.Value)
|
||||
: TimeSpan.FromTicks(0);
|
||||
|
||||
var path = Kernel.Instance.FFMpegManager.GetSubtitleCachePath(video, subtitleStream.Index, offset, ".ass");
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, CancellationToken.None);
|
||||
var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, offset, CancellationToken.None);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
[Route("/Search/Hints", "GET")]
|
||||
[Api(Description = "Gets search hints based on a search term")]
|
||||
public class GetSearchHints : IReturn<List<SearchHintResult>>
|
||||
public class GetSearchHints : IReturn<SearchHintResult>
|
||||
{
|
||||
/// <summary>
|
||||
/// Skips over a given number of items within the results. Use for paging.
|
||||
|
@ -96,7 +96,7 @@ namespace MediaBrowser.Api
|
|||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>Task{IEnumerable{SearchHintResult}}.</returns>
|
||||
private async Task<IEnumerable<SearchHintResult>> GetSearchHintsAsync(GetSearchHints request)
|
||||
private async Task<SearchHintResult> GetSearchHintsAsync(GetSearchHints request)
|
||||
{
|
||||
IEnumerable<BaseItem> inputItems;
|
||||
|
||||
|
@ -113,34 +113,48 @@ namespace MediaBrowser.Api
|
|||
|
||||
var results = await _searchEngine.GetSearchHints(inputItems, request.SearchTerm).ConfigureAwait(false);
|
||||
|
||||
var searchResultArray = results.ToArray();
|
||||
|
||||
IEnumerable<SearchHintInfo> returnResults = searchResultArray;
|
||||
|
||||
if (request.StartIndex.HasValue)
|
||||
{
|
||||
results = results.Skip(request.StartIndex.Value);
|
||||
returnResults = returnResults.Skip(request.StartIndex.Value);
|
||||
}
|
||||
|
||||
if (request.Limit.HasValue)
|
||||
{
|
||||
results = results.Take(request.Limit.Value);
|
||||
returnResults = returnResults.Take(request.Limit.Value);
|
||||
}
|
||||
|
||||
return results.Select(GetSearchHintResult);
|
||||
return new SearchHintResult
|
||||
{
|
||||
TotalRecordCount = searchResultArray.Length,
|
||||
|
||||
SearchHints = returnResults.Select(GetSearchHintResult).ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the search hint result.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="hintInfo">The hint info.</param>
|
||||
/// <returns>SearchHintResult.</returns>
|
||||
private SearchHintResult GetSearchHintResult(BaseItem item)
|
||||
private SearchHint GetSearchHintResult(SearchHintInfo hintInfo)
|
||||
{
|
||||
var result = new SearchHintResult
|
||||
var item = hintInfo.Item;
|
||||
|
||||
var result = new SearchHint
|
||||
{
|
||||
Name = item.Name,
|
||||
IndexNumber = item.IndexNumber,
|
||||
ParentIndexNumber = item.ParentIndexNumber,
|
||||
ItemId = DtoBuilder.GetClientItemId(item),
|
||||
Type = item.GetType().Name,
|
||||
MediaType = item.MediaType
|
||||
MediaType = item.MediaType,
|
||||
MatchedTerm = hintInfo.MatchedTerm,
|
||||
DisplayMediaType = item.DisplayMediaType,
|
||||
RunTimeTicks = item.RunTimeTicks
|
||||
};
|
||||
|
||||
if (item.HasImage(ImageType.Primary))
|
||||
|
@ -160,14 +174,25 @@ namespace MediaBrowser.Api
|
|||
if (season != null)
|
||||
{
|
||||
result.Series = season.Series.Name;
|
||||
|
||||
result.EpisodeCount = season.RecursiveChildren.OfType<Episode>().Count();
|
||||
}
|
||||
|
||||
var series = item as Series;
|
||||
|
||||
if (series != null)
|
||||
{
|
||||
result.EpisodeCount = series.RecursiveChildren.OfType<Episode>().Count();
|
||||
}
|
||||
|
||||
var album = item as MusicAlbum;
|
||||
|
||||
if (album != null)
|
||||
{
|
||||
var songs = album.Children.OfType<Audio>().ToList();
|
||||
var songs = album.RecursiveChildren.OfType<Audio>().ToList();
|
||||
|
||||
result.SongCount = songs.Count;
|
||||
|
||||
result.Artists = songs
|
||||
.Select(i => i.Artist)
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
|
|
|
@ -49,9 +49,10 @@ namespace MediaBrowser.Common.MediaInfo
|
|||
/// </summary>
|
||||
/// <param name="inputPath">The input path.</param>
|
||||
/// <param name="outputPath">The output path.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ConvertTextSubtitleToAss(string inputPath, string outputPath, CancellationToken cancellationToken);
|
||||
Task ConvertTextSubtitleToAss(string inputPath, string outputPath, TimeSpan offset, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media info.
|
||||
|
|
|
@ -431,7 +431,7 @@ namespace MediaBrowser.Controller.Dto
|
|||
|
||||
if (album != null)
|
||||
{
|
||||
var songs = album.Children.OfType<Audio>().ToList();
|
||||
var songs = album.RecursiveChildren.OfType<Audio>().ToList();
|
||||
|
||||
dto.AlbumArtist = songs.Select(i => i.AlbumArtist).FirstOrDefault(i => !string.IsNullOrEmpty(i));
|
||||
|
||||
|
|
|
@ -96,5 +96,17 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
{
|
||||
return string.Equals(Artist, name, StringComparison.OrdinalIgnoreCase) || string.Equals(AlbumArtist, name, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public override string DisplayMediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Song";
|
||||
}
|
||||
set
|
||||
{
|
||||
base.DisplayMediaType = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,33 @@ namespace MediaBrowser.Controller.Entities.Audio
|
|||
/// <returns><c>true</c> if the specified artist has artist; otherwise, <c>false</c>.</returns>
|
||||
public bool HasArtist(string artist)
|
||||
{
|
||||
return Children.OfType<Audio>().Any(i => i.HasArtist(artist));
|
||||
return RecursiveChildren.OfType<Audio>().Any(i => i.HasArtist(artist));
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
var song = RecursiveChildren.OfType<Audio>().FirstOrDefault(i => !string.IsNullOrEmpty(i.Album));
|
||||
|
||||
return song == null ? base.Name : song.Album;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DisplayMediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Album";
|
||||
}
|
||||
set
|
||||
{
|
||||
base.DisplayMediaType = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Library
|
|||
/// </summary>
|
||||
/// <param name="inputItems">The input items.</param>
|
||||
/// <param name="searchTerm">The search term.</param>
|
||||
/// <returns>Task{IEnumerable{BaseItem}}.</returns>
|
||||
Task<IEnumerable<BaseItem>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm);
|
||||
/// <returns>Task{IEnumerable{SearchHintInfo}}.</returns>
|
||||
Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm);
|
||||
}
|
||||
}
|
||||
|
|
22
MediaBrowser.Controller/Library/SearchHintInfo.cs
Normal file
22
MediaBrowser.Controller/Library/SearchHintInfo.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SearchHintInfo
|
||||
/// </summary>
|
||||
public class SearchHintInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item.
|
||||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public BaseItem Item { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matched term.
|
||||
/// </summary>
|
||||
/// <value>The matched term.</value>
|
||||
public string MatchedTerm { get; set; }
|
||||
}
|
||||
}
|
|
@ -112,6 +112,7 @@
|
|||
<Compile Include="IServerApplicationPaths.cs" />
|
||||
<Compile Include="Library\ChildrenChangedEventArgs.cs" />
|
||||
<Compile Include="Dto\DtoBuilder.cs" />
|
||||
<Compile Include="Library\SearchHintInfo.cs" />
|
||||
<Compile Include="Providers\IProviderManager.cs" />
|
||||
<Compile Include="Providers\MediaInfo\MediaEncoderHelpers.cs" />
|
||||
<Compile Include="Providers\MetadataProviderPriority.cs" />
|
||||
|
|
|
@ -167,7 +167,11 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
|||
|
||||
if (!string.IsNullOrEmpty(val))
|
||||
{
|
||||
audio.AddStudios(val.Split(new[] { '/', '|' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
var studios =
|
||||
val.Split(new[] {'/', '|'}, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Where(i => !string.Equals(i, audio.Artist, StringComparison.OrdinalIgnoreCase) && !string.Equals(i, audio.AlbumArtist, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
audio.AddStudios(studios);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace MediaBrowser.Controller.Providers.Music
|
|||
var folder = (Folder)item;
|
||||
|
||||
// Get each song, distinct by the combination of AlbumArtist and Album
|
||||
var songs = folder.Children.OfType<Audio>().DistinctBy(i => (i.AlbumArtist ?? string.Empty) + (i.Album ?? string.Empty), StringComparer.OrdinalIgnoreCase).ToList();
|
||||
var songs = folder.RecursiveChildren.OfType<Audio>().DistinctBy(i => (i.AlbumArtist ?? string.Empty) + (i.Album ?? string.Empty), StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
foreach (var song in songs.Where(song => !string.IsNullOrEmpty(song.Album) && !string.IsNullOrEmpty(song.AlbumArtist)))
|
||||
{
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
/// <summary>
|
||||
/// Class StreamOptions
|
||||
/// </summary>
|
||||
public abstract class StreamOptions
|
||||
public class StreamOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the audio bit rate.
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
<Compile Include="Net\NetworkShareType.cs" />
|
||||
<Compile Include="Querying\PersonsQuery.cs" />
|
||||
<Compile Include="Querying\ThemeSongsResult.cs" />
|
||||
<Compile Include="Search\SearchHint.cs" />
|
||||
<Compile Include="Search\SearchHintResult.cs" />
|
||||
<Compile Include="Serialization\IJsonSerializer.cs" />
|
||||
<Compile Include="Serialization\IXmlSerializer.cs" />
|
||||
|
|
106
MediaBrowser.Model/Search/SearchHint.cs
Normal file
106
MediaBrowser.Model/Search/SearchHint.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Search
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SearchHintResult
|
||||
/// </summary>
|
||||
public class SearchHint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item id.
|
||||
/// </summary>
|
||||
/// <value>The item id.</value>
|
||||
public string ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matched term.
|
||||
/// </summary>
|
||||
/// <value>The matched term.</value>
|
||||
public string MatchedTerm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index number.
|
||||
/// </summary>
|
||||
/// <value>The index number.</value>
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent index number.
|
||||
/// </summary>
|
||||
/// <value>The parent index number.</value>
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image tag.
|
||||
/// </summary>
|
||||
/// <value>The image tag.</value>
|
||||
public Guid? PrimaryImageTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the run time ticks.
|
||||
/// </summary>
|
||||
/// <value>The run time ticks.</value>
|
||||
public long? RunTimeTicks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the media.
|
||||
/// </summary>
|
||||
/// <value>The type of the media.</value>
|
||||
public string MediaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display type of the media.
|
||||
/// </summary>
|
||||
/// <value>The display type of the media.</value>
|
||||
public string DisplayMediaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the series.
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
public string Series { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album.
|
||||
/// </summary>
|
||||
/// <value>The album.</value>
|
||||
public string Album { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album artist.
|
||||
/// </summary>
|
||||
/// <value>The album artist.</value>
|
||||
public string AlbumArtist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artists.
|
||||
/// </summary>
|
||||
/// <value>The artists.</value>
|
||||
public string[] Artists { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the song count.
|
||||
/// </summary>
|
||||
/// <value>The song count.</value>
|
||||
public int? SongCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the episode count.
|
||||
/// </summary>
|
||||
/// <value>The episode count.</value>
|
||||
public int? EpisodeCount { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
|
||||
|
||||
namespace MediaBrowser.Model.Search
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -8,69 +7,15 @@ namespace MediaBrowser.Model.Search
|
|||
public class SearchHintResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item id.
|
||||
/// Gets or sets the search hints.
|
||||
/// </summary>
|
||||
/// <value>The item id.</value>
|
||||
public string ItemId { get; set; }
|
||||
/// <value>The search hints.</value>
|
||||
public SearchHint[] SearchHints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// Gets or sets the total record count.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index number.
|
||||
/// </summary>
|
||||
/// <value>The index number.</value>
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent index number.
|
||||
/// </summary>
|
||||
/// <value>The parent index number.</value>
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image tag.
|
||||
/// </summary>
|
||||
/// <value>The image tag.</value>
|
||||
public Guid? PrimaryImageTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the media.
|
||||
/// </summary>
|
||||
/// <value>The type of the media.</value>
|
||||
public string MediaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the series.
|
||||
/// </summary>
|
||||
/// <value>The series.</value>
|
||||
public string Series { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album.
|
||||
/// </summary>
|
||||
/// <value>The album.</value>
|
||||
public string Album { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the album artist.
|
||||
/// </summary>
|
||||
/// <value>The album artist.</value>
|
||||
public string AlbumArtist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artists.
|
||||
/// </summary>
|
||||
/// <value>The artists.</value>
|
||||
public string[] Artists { get; set; }
|
||||
/// <value>The total record count.</value>
|
||||
public int TotalRecordCount { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,24 +97,26 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <param name="searchTerm">The search term.</param>
|
||||
/// <returns>IEnumerable{SearchHintResult}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">searchTerm</exception>
|
||||
public async Task<IEnumerable<BaseItem>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm)
|
||||
public async Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
throw new ArgumentNullException("searchTerm");
|
||||
}
|
||||
|
||||
var hints = new List<Tuple<BaseItem, int>>();
|
||||
var terms = GetWords(searchTerm);
|
||||
|
||||
var hints = new List<Tuple<BaseItem, string, int>>();
|
||||
|
||||
var items = inputItems.Where(i => !(i is MusicArtist)).ToList();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var index = IndexOf(item.Name, searchTerm);
|
||||
var index = GetIndex(item.Name, searchTerm, terms);
|
||||
|
||||
if (index != -1)
|
||||
if (index.Item2 != -1)
|
||||
{
|
||||
hints.Add(new Tuple<BaseItem, int>(item, index));
|
||||
hints.Add(new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,16 +129,23 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
foreach (var item in artists)
|
||||
{
|
||||
var index = IndexOf(item, searchTerm);
|
||||
var index = GetIndex(item, searchTerm, terms);
|
||||
|
||||
if (index != -1)
|
||||
if (index.Item2 != -1)
|
||||
{
|
||||
var artist = await _libraryManager.GetArtist(item).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var artist = await _libraryManager.GetArtist(item).ConfigureAwait(false);
|
||||
|
||||
hints.Add(new Tuple<BaseItem, int>(artist, index));
|
||||
hints.Add(new Tuple<BaseItem, string, int>(artist, index.Item1, index.Item2));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting {0}", ex, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find genres
|
||||
var genres = items.SelectMany(i => i.Genres)
|
||||
.Where(i => !string.IsNullOrEmpty(i))
|
||||
|
@ -145,13 +154,20 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
foreach (var item in genres)
|
||||
{
|
||||
var index = IndexOf(item, searchTerm);
|
||||
var index = GetIndex(item, searchTerm, terms);
|
||||
|
||||
if (index != -1)
|
||||
if (index.Item2 != -1)
|
||||
{
|
||||
var genre = await _libraryManager.GetGenre(item).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var genre = await _libraryManager.GetGenre(item).ConfigureAwait(false);
|
||||
|
||||
hints.Add(new Tuple<BaseItem, int>(genre, index));
|
||||
hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting {0}", ex, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,13 +179,20 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
foreach (var item in studios)
|
||||
{
|
||||
var index = IndexOf(item, searchTerm);
|
||||
var index = GetIndex(item, searchTerm, terms);
|
||||
|
||||
if (index != -1)
|
||||
if (index.Item2 != -1)
|
||||
{
|
||||
var studio = await _libraryManager.GetStudio(item).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var studio = await _libraryManager.GetStudio(item).ConfigureAwait(false);
|
||||
|
||||
hints.Add(new Tuple<BaseItem, int>(studio, index));
|
||||
hints.Add(new Tuple<BaseItem, string, int>(studio, index.Item1, index.Item2));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting {0}", ex, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,17 +205,83 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
foreach (var item in persons)
|
||||
{
|
||||
var index = IndexOf(item, searchTerm);
|
||||
var index = GetIndex(item, searchTerm, terms);
|
||||
|
||||
if (index != -1)
|
||||
if (index.Item2 != -1)
|
||||
{
|
||||
var person = await _libraryManager.GetPerson(item).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
var person = await _libraryManager.GetPerson(item).ConfigureAwait(false);
|
||||
|
||||
hints.Add(new Tuple<BaseItem, int>(person, index));
|
||||
hints.Add(new Tuple<BaseItem, string, int>(person, index.Item1, index.Item2));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting {0}", ex, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hints.OrderBy(i => i.Item2).Select(i => i.Item1);
|
||||
return hints.OrderBy(i => i.Item3).Select(i => new SearchHintInfo
|
||||
{
|
||||
Item = i.Item1,
|
||||
MatchedTerm = i.Item2
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="searchInput">The search input.</param>
|
||||
/// <param name="searchWords">The search input.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
private Tuple<string, int> GetIndex(string input, string searchInput, string[] searchWords)
|
||||
{
|
||||
if (string.Equals(input, searchInput, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new Tuple<string, int>(searchInput, 0);
|
||||
}
|
||||
|
||||
var index = input.IndexOf(searchInput, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
return new Tuple<string, int>(searchInput, 1);
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
return new Tuple<string, int>(searchInput, 2);
|
||||
}
|
||||
|
||||
var items = GetWords(input);
|
||||
|
||||
for (var i = 0; i < searchWords.Length; i++)
|
||||
{
|
||||
var searchTerm = searchWords[i];
|
||||
|
||||
for (var j = 0; j < items.Length; j++)
|
||||
{
|
||||
var item = items[j];
|
||||
|
||||
if (string.Equals(item, searchTerm, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new Tuple<string, int>(searchTerm, 3 + (i + 1) * (j + 1));
|
||||
}
|
||||
|
||||
index = item.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
return new Tuple<string, int>(searchTerm, 4 + (i + 1) * (j + 1));
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
return new Tuple<string, int>(searchTerm, 5 + (i + 1) * (j + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Tuple<string, int>(null, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -202,32 +291,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <returns>System.String[][].</returns>
|
||||
private string[] GetWords(string term)
|
||||
{
|
||||
// TODO: Improve this to be more accurate and respect culture
|
||||
var words = term.Split(' ');
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indexes the of.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <param name="term">The term.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
private int IndexOf(string input, string term)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
foreach (var word in GetWords(input))
|
||||
{
|
||||
if (word.IndexOf(term, StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
return -1;
|
||||
return term.Split().Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -535,13 +535,14 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
|||
/// </summary>
|
||||
/// <param name="inputPath">The input path.</param>
|
||||
/// <param name="outputPath">The output path.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">inputPath
|
||||
/// or
|
||||
/// outputPath</exception>
|
||||
/// <exception cref="System.ApplicationException"></exception>
|
||||
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, CancellationToken cancellationToken)
|
||||
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, TimeSpan offset, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(inputPath))
|
||||
{
|
||||
|
|
|
@ -93,6 +93,21 @@
|
|||
<Content Include="dashboard-ui\css\images\bgflip.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\items\searchhints\film.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\items\searchhints\game.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\items\searchhints\music.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\items\searchhints\person.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\items\searchhints\tv.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\css\images\searchbutton.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common.Internal</id>
|
||||
<version>3.0.84</version>
|
||||
<version>3.0.85</version>
|
||||
<title>MediaBrowser.Common.Internal</title>
|
||||
<authors>Luke</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.84" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.85" />
|
||||
<dependency id="NLog" version="2.0.1.2" />
|
||||
<dependency id="ServiceStack.Text" version="3.9.38" />
|
||||
<dependency id="SimpleInjector" version="2.2.1" />
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common</id>
|
||||
<version>3.0.84</version>
|
||||
<version>3.0.85</version>
|
||||
<title>MediaBrowser.Common</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Server.Core</id>
|
||||
<version>3.0.84</version>
|
||||
<version>3.0.85</version>
|
||||
<title>Media Browser.Server.Core</title>
|
||||
<authors>Media Browser Team</authors>
|
||||
<owners>ebr,Luke,scottisafool</owners>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
||||
<copyright>Copyright © Media Browser 2013</copyright>
|
||||
<dependencies>
|
||||
<dependency id="MediaBrowser.Common" version="3.0.84" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.85" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
Loading…
Reference in New Issue
Block a user