Пример #1
0
        private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken)
        {
            var options = new VideoOptions
            {
                Context = EncodingContext.Static,
                ItemId = item.Id.ToString("N"),
                DeviceId = jobItem.TargetId,
                Profile = profile,
                MediaSources = item.GetMediaSources(false).ToList()
            };

            var streamInfo = new StreamBuilder().BuildVideoItem(options);
            var mediaSource = streamInfo.MediaSource;

            jobItem.MediaSourceId = streamInfo.MediaSourceId;

            if (streamInfo.PlayMethod == PlayMethod.Transcode)
            {
                jobItem.Status = SyncJobItemStatus.Converting;
                await _syncRepo.Update(jobItem).ConfigureAwait(false);

                jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
            }
            else
            {
                if (mediaSource.Protocol == MediaProtocol.File)
                {
                    jobItem.OutputPath = mediaSource.Path;
                }
                else if (mediaSource.Protocol == MediaProtocol.Http)
                {
                    jobItem.OutputPath = await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
                }
            }

            jobItem.Progress = 50;
            jobItem.Status = SyncJobItemStatus.Transferring;
            await _syncRepo.Update(jobItem).ConfigureAwait(false);
        }
Пример #2
0
        private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter, StreamInfo streamInfo = null)
        {
            if (streamInfo == null)
            {
                var sources = _user == null ? video.GetMediaSources(true).ToList() : video.GetMediaSources(true, _user).ToList();

               streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
               {
                   ItemId = video.Id.ToString("N"),
                   MediaSources = sources,
                   Profile = _profile,
                   DeviceId = deviceId,
                   MaxBitrate = _profile.MaxStreamingBitrate
               });
            }

            var targetWidth = streamInfo.TargetWidth;
            var targetHeight = streamInfo.TargetHeight;

            var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container,
                streamInfo.VideoCodec,
                streamInfo.AudioCodec,
                targetWidth,
                targetHeight,
                streamInfo.TargetVideoBitDepth,
                streamInfo.TargetVideoBitrate,
                streamInfo.TargetAudioChannels,
                streamInfo.TargetAudioBitrate,
                streamInfo.TargetTimestamp,
                streamInfo.IsDirectStream,
                streamInfo.RunTimeTicks,
                streamInfo.TargetVideoProfile,
                streamInfo.TargetVideoLevel,
                streamInfo.TargetFramerate,
                streamInfo.TargetPacketLength,
                streamInfo.TranscodeSeekInfo,
                streamInfo.IsTargetAnamorphic);

            foreach (var contentFeature in contentFeatureList)
            {
                AddVideoResource(container, video, deviceId, filter, contentFeature, streamInfo);
            }

            foreach (var subtitle in streamInfo.GetExternalSubtitles(_serverAddress))
            {
                AddSubtitleElement(container, subtitle);
            }
        }
        private async Task DownloadSubtitles(Video video, SubtitleOptions options, CancellationToken cancellationToken)
        {
            if ((options.DownloadEpisodeSubtitles &&
                video is Episode) ||
                (options.DownloadMovieSubtitles &&
                video is Movie))
            {
                var mediaStreams = video.GetMediaSources(false).First().MediaStreams;

                var downloadedLanguages = await new SubtitleDownloader(_logger,
                    _subtitleManager)
                    .DownloadSubtitles(video,
                    mediaStreams,
                    options.SkipIfGraphicalSubtitlesPresent,
                    options.SkipIfAudioTrackMatches,
                    options.DownloadLanguages,
                    cancellationToken).ConfigureAwait(false);

                // Rescan
                if (downloadedLanguages.Count > 0)
                {
                    await video.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                }
            }
        }
        private async Task DownloadSubtitles(Video video, CancellationToken cancellationToken)
        {
            if ((_config.Configuration.SubtitleOptions.DownloadEpisodeSubtitles &&
                video is Episode) ||
                (_config.Configuration.SubtitleOptions.DownloadMovieSubtitles &&
                video is Movie))
            {
                var mediaStreams = video.GetMediaSources(false).First().MediaStreams;

                var externalSubtitleStreams = mediaStreams.Where(i => i.Type == MediaStreamType.Subtitle && i.IsExternal).ToList();
                var currentStreams = mediaStreams.Except(externalSubtitleStreams).ToList();

                var downloadedLanguages = await new SubtitleDownloader(_logger,
                    _subtitleManager)
                    .DownloadSubtitles(video,
                    currentStreams,
                    externalSubtitleStreams,
                    _config.Configuration.SubtitleOptions.SkipIfGraphicalSubtitlesPresent,
                    _config.Configuration.SubtitleOptions.SkipIfAudioTrackMatches,
                    _config.Configuration.SubtitleOptions.DownloadLanguages,
                    cancellationToken).ConfigureAwait(false);

                // Rescan
                if (downloadedLanguages.Count > 0)
                {
                    await video.RefreshMetadata(cancellationToken).ConfigureAwait(false);
                }
            }
        }
Пример #5
0
        public async Task<DynamicImageResponse> GetVideoImage(Video item, CancellationToken cancellationToken)
        {
            var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);

            try
            {
                var protocol = item.LocationType == LocationType.Remote
                    ? MediaProtocol.Http
                    : MediaProtocol.File;

                var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, item.Path, protocol, isoMount, item.PlayableStreamFileNames);

                var mediaStreams =
                    item.GetMediaSources(false)
                        .Take(1)
                        .SelectMany(i => i.MediaStreams)
                        .ToList();

                var imageStreams =
                    mediaStreams
                        .Where(i => i.Type == MediaStreamType.EmbeddedImage)
                        .ToList();

                var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
                    imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1) ??
                    imageStreams.FirstOrDefault();

                string extractedImagePath;

                if (imageStream != null)
                {
                    // Instead of using the raw stream index, we need to use nth video/embedded image stream
                    var videoIndex = -1;
                    foreach (var mediaStream in mediaStreams)
                    {
                        if (mediaStream.Type == MediaStreamType.Video ||
                            mediaStream.Type == MediaStreamType.EmbeddedImage)
                        {
                            videoIndex++;
                        }
                        if (mediaStream == imageStream)
                        {
                            break;
                        }
                    }

                    extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, protocol, videoIndex, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    // If we know the duration, grab it from 10% into the video. Otherwise just 10 seconds in.
                    // Always use 10 seconds for dvd because our duration could be out of whack
                    var imageOffset = item.VideoType != VideoType.Dvd && item.RunTimeTicks.HasValue &&
                                      item.RunTimeTicks.Value > 0
                                          ? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
                                          : TimeSpan.FromSeconds(10);

                    extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
                }

                return new DynamicImageResponse
                {
                    Format = ImageFormat.Jpg,
                    HasImage = true,
                    Path = extractedImagePath,
                    Protocol = MediaProtocol.File
                };
            }
            finally
            {
                if (isoMount != null)
                {
                    isoMount.Dispose();
                }
            }
        }
Пример #6
0
        private async Task<string> Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken)
        {
            var options = new VideoOptions
            {
                Context = EncodingContext.Streaming,
                ItemId = item.Id.ToString("N"),
                DeviceId = jobItem.TargetId,
                Profile = profile,
                MediaSources = item.GetMediaSources(false).ToList()
            };

            var streamInfo = new StreamBuilder().BuildVideoItem(options);
            var mediaSource = streamInfo.MediaSource;

            if (streamInfo.PlayMethod != PlayMethod.Transcode)
            {
                if (mediaSource.Protocol == MediaProtocol.File)
                {
                    return mediaSource.Path;
                }
                if (mediaSource.Protocol == MediaProtocol.Http)
                {
                    return await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
                }
                throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
            }

            // TODO: Transcode
            return mediaSource.Path;
        }