Пример #1
0
        /// <summary>
        /// Get audio stream.
        /// </summary>
        /// <param name="transcodingJobType">Transcoding job type.</param>
        /// <param name="streamingRequest">Streaming controller.Request dto.</param>
        /// <returns>A <see cref="Task"/> containing the resulting <see cref="ActionResult"/>.</returns>
        public async Task <ActionResult> GetAudioStream(
            TranscodingJobType transcodingJobType,
            StreamingRequestDto streamingRequest)
        {
            if (_httpContextAccessor.HttpContext == null)
            {
                throw new ResourceNotFoundException(nameof(_httpContextAccessor.HttpContext));
            }

            bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head;

            // CTS lifecycle is managed internally.
            var cancellationTokenSource = new CancellationTokenSource();

            using var state = await StreamingHelpers.GetStreamingState(
                      streamingRequest,
                      _httpContextAccessor.HttpContext.Request,
                      _authContext,
                      _mediaSourceManager,
                      _userManager,
                      _libraryManager,
                      _serverConfigurationManager,
                      _mediaEncoder,
                      _encodingHelper,
                      _dlnaManager,
                      _deviceManager,
                      _transcodingJobHelper,
                      transcodingJobType,
                      cancellationTokenSource.Token)
                              .ConfigureAwait(false);

            if (streamingRequest.Static && state.DirectStreamProvider != null)
            {
                StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);

                var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfo(streamingRequest.LiveStreamId);
                if (liveStreamInfo == null)
                {
                    throw new FileNotFoundException();
                }

                var liveStream = new ProgressiveFileStream(liveStreamInfo.GetStream());
                // TODO (moved from MediaBrowser.Api): Don't hardcode contentType
                return(new FileStreamResult(liveStream, MimeTypes.GetMimeType("file.ts")));
            }

            // Static remote stream
            if (streamingRequest.Static && state.InputProtocol == MediaProtocol.Http)
            {
                StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);

                var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
                return(await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, httpClient, _httpContextAccessor.HttpContext).ConfigureAwait(false));
            }

            if (streamingRequest.Static && state.InputProtocol != MediaProtocol.File)
            {
                return(new BadRequestObjectResult($"Input protocol {state.InputProtocol} cannot be streamed statically"));
            }

            var outputPath       = state.OutputFilePath;
            var outputPathExists = File.Exists(outputPath);

            var transcodingJob    = _transcodingJobHelper.GetTranscodingJob(outputPath, TranscodingJobType.Progressive);
            var isTranscodeCached = outputPathExists && transcodingJob != null;

            StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, streamingRequest.Static || isTranscodeCached, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);

            // Static stream
            if (streamingRequest.Static)
            {
                var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath);

                if (state.MediaSource.IsInfiniteStream)
                {
                    var stream = new ProgressiveFileStream(state.MediaPath, null, _transcodingJobHelper);
                    return(new FileStreamResult(stream, contentType));
                }

                return(FileStreamResponseHelpers.GetStaticFileResult(
                           state.MediaPath,
                           contentType));
            }

            // Need to start ffmpeg (because media can't be returned directly)
            var encodingOptions            = _serverConfigurationManager.GetEncodingOptions();
            var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveAudioFullCommandLine(state, encodingOptions, outputPath);

            return(await FileStreamResponseHelpers.GetTranscodedFile(
                       state,
                       isHeadRequest,
                       _httpContextAccessor.HttpContext,
                       _transcodingJobHelper,
                       ffmpegCommandLineArguments,
                       transcodingJobType,
                       cancellationTokenSource).ConfigureAwait(false));
        }
Пример #2
0
        public async Task <ActionResult> GetVideoStream(
            [FromRoute, Required] Guid itemId,
            [FromQuery] string?container,
            [FromQuery] bool? @static,
            [FromQuery] string? @params,
            [FromQuery] string?tag,
            [FromQuery] string?deviceProfileId,
            [FromQuery] string?playSessionId,
            [FromQuery] string?segmentContainer,
            [FromQuery] int?segmentLength,
            [FromQuery] int?minSegments,
            [FromQuery] string?mediaSourceId,
            [FromQuery] string?deviceId,
            [FromQuery] string?audioCodec,
            [FromQuery] bool?enableAutoStreamCopy,
            [FromQuery] bool?allowVideoStreamCopy,
            [FromQuery] bool?allowAudioStreamCopy,
            [FromQuery] bool?breakOnNonKeyFrames,
            [FromQuery] int?audioSampleRate,
            [FromQuery] int?maxAudioBitDepth,
            [FromQuery] int?audioBitRate,
            [FromQuery] int?audioChannels,
            [FromQuery] int?maxAudioChannels,
            [FromQuery] string?profile,
            [FromQuery] string?level,
            [FromQuery] float?framerate,
            [FromQuery] float?maxFramerate,
            [FromQuery] bool?copyTimestamps,
            [FromQuery] long?startTimeTicks,
            [FromQuery] int?width,
            [FromQuery] int?height,
            [FromQuery] int?maxWidth,
            [FromQuery] int?maxHeight,
            [FromQuery] int?videoBitRate,
            [FromQuery] int?subtitleStreamIndex,
            [FromQuery] SubtitleDeliveryMethod?subtitleMethod,
            [FromQuery] int?maxRefFrames,
            [FromQuery] int?maxVideoBitDepth,
            [FromQuery] bool?requireAvc,
            [FromQuery] bool?deInterlace,
            [FromQuery] bool?requireNonAnamorphic,
            [FromQuery] int?transcodingMaxAudioChannels,
            [FromQuery] int?cpuCoreLimit,
            [FromQuery] string?liveStreamId,
            [FromQuery] bool?enableMpegtsM2TsMode,
            [FromQuery] string?videoCodec,
            [FromQuery] string?subtitleCodec,
            [FromQuery] string?transcodeReasons,
            [FromQuery] int?audioStreamIndex,
            [FromQuery] int?videoStreamIndex,
            [FromQuery] EncodingContext?context,
            [FromQuery] Dictionary <string, string> streamOptions)
        {
            var isHeadRequest = Request.Method == System.Net.WebRequestMethods.Http.Head;
            // CTS lifecycle is managed internally.
            var cancellationTokenSource = new CancellationTokenSource();
            var streamingRequest        = new VideoRequestDto
            {
                Id                          = itemId,
                Container                   = container,
                Static                      = @static ?? false,
                Params                      = @params,
                Tag                         = tag,
                DeviceProfileId             = deviceProfileId,
                PlaySessionId               = playSessionId,
                SegmentContainer            = segmentContainer,
                SegmentLength               = segmentLength,
                MinSegments                 = minSegments,
                MediaSourceId               = mediaSourceId,
                DeviceId                    = deviceId,
                AudioCodec                  = audioCodec,
                EnableAutoStreamCopy        = enableAutoStreamCopy ?? true,
                AllowAudioStreamCopy        = allowAudioStreamCopy ?? true,
                AllowVideoStreamCopy        = allowVideoStreamCopy ?? true,
                BreakOnNonKeyFrames         = breakOnNonKeyFrames ?? false,
                AudioSampleRate             = audioSampleRate,
                MaxAudioChannels            = maxAudioChannels,
                AudioBitRate                = audioBitRate,
                MaxAudioBitDepth            = maxAudioBitDepth,
                AudioChannels               = audioChannels,
                Profile                     = profile,
                Level                       = level,
                Framerate                   = framerate,
                MaxFramerate                = maxFramerate,
                CopyTimestamps              = copyTimestamps ?? false,
                StartTimeTicks              = startTimeTicks,
                Width                       = width,
                Height                      = height,
                MaxWidth                    = maxWidth,
                MaxHeight                   = maxHeight,
                VideoBitRate                = videoBitRate,
                SubtitleStreamIndex         = subtitleStreamIndex,
                SubtitleMethod              = subtitleMethod ?? SubtitleDeliveryMethod.Encode,
                MaxRefFrames                = maxRefFrames,
                MaxVideoBitDepth            = maxVideoBitDepth,
                RequireAvc                  = requireAvc ?? false,
                DeInterlace                 = deInterlace ?? false,
                RequireNonAnamorphic        = requireNonAnamorphic ?? false,
                TranscodingMaxAudioChannels = transcodingMaxAudioChannels,
                CpuCoreLimit                = cpuCoreLimit,
                LiveStreamId                = liveStreamId,
                EnableMpegtsM2TsMode        = enableMpegtsM2TsMode ?? false,
                VideoCodec                  = videoCodec,
                SubtitleCodec               = subtitleCodec,
                TranscodeReasons            = transcodeReasons,
                AudioStreamIndex            = audioStreamIndex,
                VideoStreamIndex            = videoStreamIndex,
                Context                     = context ?? EncodingContext.Streaming,
                StreamOptions               = streamOptions
            };

            using var state = await StreamingHelpers.GetStreamingState(
                      streamingRequest,
                      Request,
                      _authContext,
                      _mediaSourceManager,
                      _userManager,
                      _libraryManager,
                      _serverConfigurationManager,
                      _mediaEncoder,
                      _encodingHelper,
                      _dlnaManager,
                      _deviceManager,
                      _transcodingJobHelper,
                      _transcodingJobType,
                      cancellationTokenSource.Token)
                              .ConfigureAwait(false);

            if (@static.HasValue && @static.Value && state.DirectStreamProvider != null)
            {
                StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, state.Request.StartTimeTicks, Request, _dlnaManager);

                var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfo(streamingRequest.LiveStreamId);
                if (liveStreamInfo == null)
                {
                    return(NotFound());
                }

                var liveStream = new ProgressiveFileStream(liveStreamInfo.GetStream());
                // TODO (moved from MediaBrowser.Api): Don't hardcode contentType
                return(File(liveStream, MimeTypes.GetMimeType("file.ts")));
            }

            // Static remote stream
            if (@static.HasValue && @static.Value && state.InputProtocol == MediaProtocol.Http)
            {
                StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, state.Request.StartTimeTicks, Request, _dlnaManager);

                var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
                return(await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, httpClient, HttpContext).ConfigureAwait(false));
            }

            if (@static.HasValue && @static.Value && state.InputProtocol != MediaProtocol.File)
            {
                return(BadRequest($"Input protocol {state.InputProtocol} cannot be streamed statically"));
            }

            var outputPath       = state.OutputFilePath;
            var outputPathExists = System.IO.File.Exists(outputPath);

            var transcodingJob    = _transcodingJobHelper.GetTranscodingJob(outputPath, TranscodingJobType.Progressive);
            var isTranscodeCached = outputPathExists && transcodingJob != null;

            StreamingHelpers.AddDlnaHeaders(state, Response.Headers, (@static.HasValue && @static.Value) || isTranscodeCached, state.Request.StartTimeTicks, Request, _dlnaManager);

            // Static stream
            if (@static.HasValue && @static.Value)
            {
                var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath);

                if (state.MediaSource.IsInfiniteStream)
                {
                    var liveStream = new ProgressiveFileStream(state.MediaPath, null, _transcodingJobHelper);
                    return(File(liveStream, contentType));
                }

                return(FileStreamResponseHelpers.GetStaticFileResult(
                           state.MediaPath,
                           contentType,
                           isHeadRequest,
                           HttpContext));
            }

            // Need to start ffmpeg (because media can't be returned directly)
            var encodingOptions            = _serverConfigurationManager.GetEncodingOptions();
            var ffmpegCommandLineArguments = _encodingHelper.GetProgressiveVideoFullCommandLine(state, encodingOptions, outputPath, "superfast");

            return(await FileStreamResponseHelpers.GetTranscodedFile(
                       state,
                       isHeadRequest,
                       HttpContext,
                       _transcodingJobHelper,
                       ffmpegCommandLineArguments,
                       _transcodingJobType,
                       cancellationTokenSource).ConfigureAwait(false));
        }