Exemplo n.º 1
0
        public object Get(GetSubtitlePlaylist request)
        {
            var item = (Video)_libraryManager.GetItemById(new Guid(request.Id));

            var mediaSource = _mediaSourceManager.GetStaticMediaSource(item, request.MediaSourceId, false);

            var builder = new StringBuilder();

            var runtime = mediaSource.RunTimeTicks ?? -1;

            if (runtime <= 0)
            {
                throw new ArgumentException("HLS Subtitles are not supported for this media.");
            }

            builder.AppendLine("#EXTM3U");
            builder.AppendLine("#EXT-X-TARGETDURATION:" + request.SegmentLength.ToString(CultureInfo.InvariantCulture));
            builder.AppendLine("#EXT-X-VERSION:3");
            builder.AppendLine("#EXT-X-MEDIA-SEQUENCE:0");

            long positionTicks      = 0;
            var  segmentLengthTicks = TimeSpan.FromSeconds(request.SegmentLength).Ticks;

            while (positionTicks < runtime)
            {
                var remaining   = runtime - positionTicks;
                var lengthTicks = Math.Min(remaining, segmentLengthTicks);

                builder.AppendLine("#EXTINF:" + TimeSpan.FromTicks(lengthTicks).TotalSeconds.ToString(CultureInfo.InvariantCulture));

                var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);

                var url = string.Format("stream.srt?StartPositionTicks={0}&EndPositionTicks={1}",
                                        positionTicks.ToString(CultureInfo.InvariantCulture),
                                        endPositionTicks.ToString(CultureInfo.InvariantCulture));

                builder.AppendLine(url);

                positionTicks += segmentLengthTicks;
            }

            builder.AppendLine("#EXT-X-ENDLIST");

            return(ResultFactory.GetResult(builder.ToString(), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary <string, string>()));
        }
Exemplo n.º 2
0
            public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager)
            {
                var request = new StreamParams
                {
                    ItemId = GetItemId(url)
                };

                Guid parsedId;

                if (string.IsNullOrWhiteSpace(request.ItemId) || !Guid.TryParse(request.ItemId, out parsedId))
                {
                    return(request);
                }

                const string srch  = "params=";
                var          index = url.IndexOf(srch, StringComparison.OrdinalIgnoreCase);

                if (index == -1)
                {
                    return(request);
                }

                var vals = url.Substring(index + srch.Length).Split(';');

                for (var i = 0; i < vals.Length; i++)
                {
                    var val = vals[i];

                    if (string.IsNullOrWhiteSpace(val))
                    {
                        continue;
                    }

                    if (i == 0)
                    {
                        request.DeviceProfileId = val;
                    }
                    else if (i == 1)
                    {
                        request.DeviceId = val;
                    }
                    else if (i == 2)
                    {
                        request.MediaSourceId = val;
                    }
                    else if (i == 3)
                    {
                        request.IsDirectStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
                    }
                    else if (i == 6)
                    {
                        request.AudioStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
                    }
                    else if (i == 7)
                    {
                        request.SubtitleStreamIndex = int.Parse(val, CultureInfo.InvariantCulture);
                    }
                    else if (i == 14)
                    {
                        request.StartPositionTicks = long.Parse(val, CultureInfo.InvariantCulture);
                    }
                }

                request.Item = string.IsNullOrWhiteSpace(request.ItemId)
                    ? null
                    : libraryManager.GetItemById(parsedId);

                var hasMediaSources = request.Item as IHasMediaSources;

                request.MediaSource = hasMediaSources == null ?
                                      null :
                                      mediaSourceManager.GetStaticMediaSource(hasMediaSources, request.MediaSourceId, false);



                return(request);
            }
Exemplo n.º 3
0
        public async Task <EncodingJob> CreateJob(EncodingJobOptions options, bool isVideoRequest, IProgress <double> progress, CancellationToken cancellationToken)
        {
            var request = options;

            if (string.IsNullOrEmpty(request.AudioCodec))
            {
                request.AudioCodec = InferAudioCodec(request.OutputContainer);
            }

            var state = new EncodingJob(_logger, _liveTvManager)
            {
                Options        = options,
                IsVideoRequest = isVideoRequest,
                Progress       = progress
            };

            if (!string.IsNullOrWhiteSpace(request.AudioCodec))
            {
                state.SupportedAudioCodecs = request.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
                request.AudioCodec         = state.SupportedAudioCodecs.FirstOrDefault();
            }

            var item = _libraryManager.GetItemById(request.ItemId);

            List <MediaStream> mediaStreams = null;

            state.ItemType = item.GetType().Name;

            if (item is ILiveTvRecording)
            {
                var recording = await _liveTvManager.GetInternalRecording(request.ItemId, cancellationToken).ConfigureAwait(false);

                state.VideoType    = VideoType.VideoFile;
                state.IsInputVideo = string.Equals(recording.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);

                var path     = recording.RecordingInfo.Path;
                var mediaUrl = recording.RecordingInfo.Url;

                var source = string.IsNullOrEmpty(request.MediaSourceId)
                    ? recording.GetMediaSources(false).First()
                    : _mediaSourceManager.GetStaticMediaSource(recording, request.MediaSourceId, false);

                mediaStreams = source.MediaStreams;

                // Just to prevent this from being null and causing other methods to fail
                state.MediaPath = string.Empty;

                if (!string.IsNullOrEmpty(path))
                {
                    state.MediaPath     = path;
                    state.InputProtocol = MediaProtocol.File;
                }
                else if (!string.IsNullOrEmpty(mediaUrl))
                {
                    state.MediaPath     = mediaUrl;
                    state.InputProtocol = MediaProtocol.Http;
                }

                state.RunTimeTicks               = recording.RunTimeTicks;
                state.DeInterlace                = true;
                state.OutputAudioSync            = "1000";
                state.InputVideoSync             = "-1";
                state.InputAudioSync             = "1";
                state.InputContainer             = recording.Container;
                state.ReadInputAtNativeFramerate = source.ReadAtNativeFramerate;
            }
            else if (item is LiveTvChannel)
            {
                var channel = _liveTvManager.GetInternalChannel(request.ItemId);

                state.VideoType    = VideoType.VideoFile;
                state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
                mediaStreams       = new List <MediaStream>();

                state.DeInterlace = true;

                // Just to prevent this from being null and causing other methods to fail
                state.MediaPath = string.Empty;
            }
            else
            {
                var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, false, cancellationToken).ConfigureAwait(false);

                var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
                    ? mediaSources.First()
                    : mediaSources.First(i => string.Equals(i.Id, request.MediaSourceId));

                mediaStreams = mediaSource.MediaStreams;

                state.MediaPath                  = mediaSource.Path;
                state.InputProtocol              = mediaSource.Protocol;
                state.InputContainer             = mediaSource.Container;
                state.InputFileSize              = mediaSource.Size;
                state.InputBitrate               = mediaSource.Bitrate;
                state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
                state.RunTimeTicks               = mediaSource.RunTimeTicks;
                state.RemoteHttpHeaders          = mediaSource.RequiredHttpHeaders;

                var video = item as Video;

                if (video != null)
                {
                    state.IsInputVideo = true;

                    if (mediaSource.VideoType.HasValue)
                    {
                        state.VideoType = mediaSource.VideoType.Value;
                    }

                    state.IsoType = mediaSource.IsoType;

                    state.PlayableStreamFileNames = mediaSource.PlayableStreamFileNames.ToList();

                    if (mediaSource.Timestamp.HasValue)
                    {
                        state.InputTimestamp = mediaSource.Timestamp.Value;
                    }
                }

                state.RunTimeTicks = mediaSource.RunTimeTicks;
            }

            AttachMediaStreamInfo(state, mediaStreams, request);

            state.OutputAudioBitrate    = GetAudioBitrateParam(request, state.AudioStream);
            state.OutputAudioSampleRate = request.AudioSampleRate;

            state.OutputAudioCodec = GetAudioCodec(request);

            state.OutputAudioChannels = GetNumAudioChannelsParam(request, state.AudioStream, state.OutputAudioCodec);

            if (isVideoRequest)
            {
                state.OutputVideoCodec   = GetVideoCodec(request);
                state.OutputVideoBitrate = GetVideoBitrateParamValue(request, state.VideoStream);

                if (state.OutputVideoBitrate.HasValue)
                {
                    var resolution = ResolutionNormalizer.Normalize(state.OutputVideoBitrate.Value,
                                                                    state.OutputVideoCodec,
                                                                    request.MaxWidth,
                                                                    request.MaxHeight);

                    request.MaxWidth  = resolution.MaxWidth;
                    request.MaxHeight = resolution.MaxHeight;
                }
            }

            ApplyDeviceProfileSettings(state);

            if (isVideoRequest)
            {
                if (state.VideoStream != null && CanStreamCopyVideo(request, state.VideoStream))
                {
                    state.OutputVideoCodec = "copy";
                }

                if (state.AudioStream != null && CanStreamCopyAudio(request, state.AudioStream, state.SupportedAudioCodecs))
                {
                    state.OutputAudioCodec = "copy";
                }
            }

            return(state);
        }