1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api.Library
{
[Route("/Videos/{Id}/Subtitles/{Index}", "GET", Summary = "Gets an external subtitle file")]
public class GetSubtitle
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
public int Index { get; set; }
}
[Route("/Videos/{Id}/Subtitles/{Index}", "DELETE", Summary = "Deletes an external subtitle file")]
public class DeleteSubtitle
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
[ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "DELETE")]
public int Index { get; set; }
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/{Language}", "GET")]
public class SearchRemoteSubtitles : IReturn<List<RemoteSubtitleInfo>>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "Language", Description = "Language", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Language { get; set; }
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/Providers", "GET")]
public class GetSubtitleProviders : IReturn<List<SubtitleProviderInfo>>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/{SubtitleId}", "POST")]
public class DownloadRemoteSubtitles : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
[ApiMember(Name = "SubtitleId", Description = "SubtitleId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string SubtitleId { get; set; }
}
[Route("/Providers/Subtitles/Subtitles/{Id}", "GET")]
public class GetRemoteSubtitles : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
public class SubtitleService : BaseApiService
{
private readonly ILibraryManager _libraryManager;
private readonly ISubtitleManager _subtitleManager;
private readonly IItemRepository _itemRepo;
public SubtitleService(ILibraryManager libraryManager, ISubtitleManager subtitleManager, IItemRepository itemRepo)
{
_libraryManager = libraryManager;
_subtitleManager = subtitleManager;
_itemRepo = itemRepo;
}
public object Get(SearchRemoteSubtitles request)
{
var video = (Video)_libraryManager.GetItemById(request.Id);
var response = _subtitleManager.SearchSubtitles(video, request.Language, CancellationToken.None).Result;
return ToOptimizedResult(response);
}
public object Get(GetSubtitle request)
{
var subtitleStream = _itemRepo.GetMediaStreams(new MediaStreamQuery
{
Index = request.Index,
ItemId = new Guid(request.Id),
Type = MediaStreamType.Subtitle
}).FirstOrDefault();
if (subtitleStream == null)
{
throw new ResourceNotFoundException();
}
return ToStaticFileResult(subtitleStream.Path);
}
public void Delete(DeleteSubtitle request)
{
var task = _subtitleManager.DeleteSubtitles(request.Id, request.Index);
Task.WaitAll(task);
}
public object Get(GetSubtitleProviders request)
{
var result = _subtitleManager.GetProviders(request.Id);
return ToOptimizedResult(result);
}
public object Get(GetRemoteSubtitles request)
{
var result = _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).Result;
return ResultFactory.GetResult(result.Stream, MimeTypes.GetMimeType("file." + result.Format));
}
public void Post(DownloadRemoteSubtitles request)
{
var video = (Video)_libraryManager.GetItemById(request.Id);
Task.Run(async () =>
{
try
{
await _subtitleManager.DownloadSubtitles(video, request.SubtitleId, CancellationToken.None)
.ConfigureAwait(false);
await video.RefreshMetadata(new MetadataRefreshOptions(), CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
Logger.ErrorException("Error downloading subtitles", ex);
}
});
}
}
}
|