using MediaBrowser.Controller; using ServiceStack; using System; using System.IO; using System.Linq; using System.Threading.Tasks; namespace MediaBrowser.Api.Playback.Hls { /// /// Class GetHlsAudioSegment /// [Route("/Audio/{Id}/hls/{SegmentId}/stream.mp3", "GET")] [Route("/Audio/{Id}/hls/{SegmentId}/stream.aac", "GET")] [Api(Description = "Gets an Http live streaming segment file. Internal use only.")] public class GetHlsAudioSegment { /// /// Gets or sets the id. /// /// The id. public string Id { get; set; } /// /// Gets or sets the segment id. /// /// The segment id. public string SegmentId { get; set; } } /// /// Class GetHlsVideoSegment /// [Route("/Videos/{Id}/hls/{PlaylistId}/stream.m3u8", "GET")] [Api(Description = "Gets an Http live streaming segment file. Internal use only.")] public class GetHlsPlaylist { /// /// Gets or sets the id. /// /// The id. public string Id { get; set; } public string PlaylistId { get; set; } } [Route("/Videos/ActiveEncodings", "DELETE")] [Api(Description = "Stops an encoding process")] public class StopEncodingProcess { [ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] public string DeviceId { get; set; } } public class HlsSegmentService : BaseApiService { private readonly IServerApplicationPaths _appPaths; public HlsSegmentService(IServerApplicationPaths appPaths) { _appPaths = appPaths; } public object Get(GetHlsPlaylist request) { var normalizedPlaylistId = request.PlaylistId.Replace("-low", string.Empty); foreach (var playlist in Directory.EnumerateFiles(_appPaths.TranscodingTempPath, "*.m3u8") .Where(i => i.IndexOf(normalizedPlaylistId, StringComparison.OrdinalIgnoreCase) != -1) .ToList()) { if (!string.IsNullOrEmpty(playlist)) { ExtendPlaylistTimer(playlist); } } var file = request.PlaylistId + Path.GetExtension(Request.PathInfo); file = Path.Combine(_appPaths.TranscodingTempPath, file); return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite); } public void Delete(StopEncodingProcess request) { var task = ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, path => true, true); Task.WaitAll(task); } /// /// Gets the specified request. /// /// The request. /// System.Object. public object Get(GetHlsAudioSegment request) { var file = request.SegmentId + Path.GetExtension(Request.PathInfo); file = Path.Combine(_appPaths.TranscodingTempPath, file); return ResultFactory.GetStaticFileResult(Request, file, FileShare.ReadWrite); } private async void ExtendPlaylistTimer(string playlist) { var job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlist, TranscodingJobType.Hls); await Task.Delay(20000).ConfigureAwait(false); if (job != null) { ApiEntryPoint.Instance.OnTranscodeEndRequest(job); } } } }