Пример #1
0
        public Task <ItemUpdateType> FetchVideoInfo <T>(T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
            where T : Video
        {
            if (item.LocationType != LocationType.FileSystem)
            {
                return(_cachedTask);
            }

            if (item.VideoType == VideoType.Iso && !_isoManager.CanMount(item.Path))
            {
                return(_cachedTask);
            }

            if (item.VideoType == VideoType.HdDvd)
            {
                return(_cachedTask);
            }

            if (item.IsPlaceHolder)
            {
                return(_cachedTask);
            }

            if (item.IsShortcut)
            {
                FetchShortcutInfo(item);
                return(Task.FromResult(ItemUpdateType.MetadataImport));
            }

            var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager, _fileSystem, _config, _subtitleManager, _chapterManager, _libraryManager);

            return(prober.ProbeVideo(item, options, cancellationToken));
        }
Пример #2
0
        private async Task AcquireResources(EncodingJob state, CancellationToken cancellationToken)
        {
            if (state.VideoType == VideoType.Iso && state.IsoType.HasValue && IsoManager.CanMount(state.MediaPath))
            {
                state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false);
            }

            if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.Options.LiveStreamId))
            {
                var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest
                {
                    OpenToken = state.MediaSource.OpenToken
                }, cancellationToken).ConfigureAwait(false);

                EncodingHelper.AttachMediaSourceInfo(state, liveStreamResponse.MediaSource, null);

                if (state.IsVideoRequest)
                {
                    EncodingHelper.TryStreamCopy(state);
                }
            }

            if (state.MediaSource.BufferMs.HasValue)
            {
                await Task.Delay(state.MediaSource.BufferMs.Value, cancellationToken).ConfigureAwait(false);
            }
        }
Пример #3
0
        public Task <ItemUpdateType> FetchVideoInfo <T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken)
            where T : Video
        {
            if (item.LocationType != LocationType.FileSystem)
            {
                return(_cachedTask);
            }

            if (item.VideoType == VideoType.Iso && !_isoManager.CanMount(item.Path))
            {
                return(_cachedTask);
            }

            if (item.VideoType == VideoType.HdDvd)
            {
                return(_cachedTask);
            }

            if (item.IsPlaceHolder)
            {
                return(_cachedTask);
            }

            var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json, _encodingManager);

            return(prober.ProbeVideo(item, directoryService, cancellationToken));
        }
Пример #4
0
        /// <summary>
        /// Supportses the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        public override bool Supports(BaseItem item)
        {
            if (item.LocationType != LocationType.FileSystem)
            {
                return(false);
            }

            var video = item as Video;

            if (video != null)
            {
                // Can't extract images if there are no video streams
                if (video.MediaStreams == null || video.MediaStreams.All(m => m.Type != MediaStreamType.Video))
                {
                    return(false);
                }

                if (video.VideoType == VideoType.Iso && video.IsoType.HasValue && _isoManager.CanMount(item.Path))
                {
                    return(true);
                }

                // We can only extract images from folder rips if we know the largest stream path
                return(video.VideoType == VideoType.VideoFile || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd);
            }

            return(false);
        }
Пример #5
0
        private async Task AcquireResources(EncodingJob state, CancellationToken cancellationToken)
        {
            if (state.VideoType == VideoType.Iso && state.IsoType.HasValue && IsoManager.CanMount(state.MediaPath))
            {
                state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false);
            }

            if (string.IsNullOrEmpty(state.MediaPath))
            {
                var checkCodecs = false;

                if (string.Equals(state.ItemType, typeof(LiveTvChannel).Name))
                {
                    var streamInfo = await LiveTvManager.GetChannelStream(state.Options.ItemId, cancellationToken).ConfigureAwait(false);

                    state.LiveTvStreamId = streamInfo.Id;

                    state.MediaPath     = streamInfo.Path;
                    state.InputProtocol = streamInfo.Protocol;

                    await Task.Delay(1500, cancellationToken).ConfigureAwait(false);

                    AttachMediaStreamInfo(state, streamInfo, state.Options);
                    checkCodecs = true;
                }

                else if (string.Equals(state.ItemType, typeof(LiveTvVideoRecording).Name) ||
                         string.Equals(state.ItemType, typeof(LiveTvAudioRecording).Name))
                {
                    var streamInfo = await LiveTvManager.GetRecordingStream(state.Options.ItemId, cancellationToken).ConfigureAwait(false);

                    state.LiveTvStreamId = streamInfo.Id;

                    state.MediaPath     = streamInfo.Path;
                    state.InputProtocol = streamInfo.Protocol;

                    await Task.Delay(1500, cancellationToken).ConfigureAwait(false);

                    AttachMediaStreamInfo(state, streamInfo, state.Options);
                    checkCodecs = true;
                }

                if (state.IsVideoRequest && checkCodecs)
                {
                    if (state.VideoStream != null && EncodingJobFactory.CanStreamCopyVideo(state.Options, state.VideoStream))
                    {
                        state.OutputVideoCodec = "copy";
                    }

                    if (state.AudioStream != null && EncodingJobFactory.CanStreamCopyAudio(state.Options, state.AudioStream, state.SupportedAudioCodecs))
                    {
                        state.OutputAudioCodec = "copy";
                    }
                }
            }
        }
        /// <summary>
        /// Supports video files and dvd structures
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        public override bool Supports(BaseItem item)
        {
            if (item.LocationType != LocationType.FileSystem)
            {
                return(false);
            }

            var video = item as Video;

            if (video != null)
            {
                if (video.VideoType == VideoType.Iso)
                {
                    return(_isoManager.CanMount(item.Path));
                }

                return(video.VideoType == VideoType.VideoFile || video.VideoType == VideoType.Dvd || video.VideoType == VideoType.BluRay);
            }

            return(false);
        }
Пример #7
0
        public async Task Start(InternalEncodingTask task, Func <InternalEncodingTask, string, string> argumentsFactory)
        {
            _task = task;
            if (!File.Exists(_ffmpegPath))
            {
                throw new InvalidOperationException("ffmpeg was not found at " + _ffmpegPath);
            }

            Directory.CreateDirectory(Path.GetDirectoryName(task.Request.OutputPath));

            string mountedPath = null;

            if (task.InputVideoType.HasValue && task.InputVideoType == VideoType.Iso && task.IsoType.HasValue)
            {
                if (_isoManager.CanMount(task.MediaPath))
                {
                    _isoMount = await _isoManager.Mount(task.MediaPath, CancellationToken.None).ConfigureAwait(false);

                    mountedPath = _isoMount.MountedPath;
                }
            }

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    CreateNoWindow  = true,
                    UseShellExecute = false,

                    // Must consume both stdout and stderr or deadlocks may occur
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,

                    FileName         = _ffmpegPath,
                    WorkingDirectory = Path.GetDirectoryName(_ffmpegPath),
                    Arguments        = argumentsFactory(task, mountedPath),

                    WindowStyle = ProcessWindowStyle.Hidden,
                    ErrorDialog = false
                },

                EnableRaisingEvents = true
            };

            _logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments);

            var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-" + task.Id + ".txt");

            Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));

            // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
            _logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);

            process.Exited += process_Exited;

            try
            {
                process.Start();
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error starting ffmpeg", ex);

                task.OnError();

                DisposeLogFileStream();

                process.Dispose();

                throw;
            }

            task.OnBegin();

            // MUST read both stdout and stderr asynchronously or a deadlock may occurr
            process.BeginOutputReadLine();

#pragma warning disable 4014
            // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
            process.StandardError.BaseStream.CopyToAsync(_logFileStream);
#pragma warning restore 4014
        }
Пример #8
0
        private async Task <PlayableItem> GetPlayableItem(BaseItemDto item, long?startTimeTicks, CancellationToken cancellationToken)
        {
            IIsoMount mountedIso = null;

            if (item.VideoType.HasValue && item.VideoType.Value == VideoType.Iso && item.IsoType.HasValue && _isoManager.CanMount(item.Path))
            {
                try
                {
                    mountedIso = await _isoManager.Mount(item.Path, cancellationToken);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error mounting iso {0}", ex, item.Path);
                }
            }

            var apiClient    = _connectionManager.GetApiClient(item);
            var mediaSources = item.MediaSources;

            try
            {
                var result = await apiClient.GetLiveMediaInfo(item.Id, apiClient.CurrentUserId);

                mediaSources = result.MediaSources;
            }
            catch
            {
            }

            return(PlayablePathBuilder.GetPlayableItem(item, mediaSources, mountedIso, apiClient, startTimeTicks, _config.Configuration.MaxStreamingBitrate));
        }
Пример #9
0
        private async Task <PlayableItem> GetPlayableItem(BaseItemDto item, long?startTimeTicks, CancellationToken cancellationToken)
        {
            IIsoMount mountedIso = null;

            if (item.VideoType.HasValue && item.VideoType.Value == VideoType.Iso && item.IsoType.HasValue && _isoManager.CanMount(item.Path))
            {
                try
                {
                    mountedIso = await _isoManager.Mount(item.Path, cancellationToken);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error mounting iso {0}", ex, item.Path);
                }
            }

            return(new PlayableItem
            {
                OriginalItem = item,
                PlayablePath = PlayablePathBuilder.GetPlayablePath(item, mountedIso, _apiClient, startTimeTicks, _config.Configuration.MaxStreamingBitrate),
                IsoMount = mountedIso
            });
        }
Пример #10
0
        private async Task <IIsoMount> GetIsoMount(BaseItemDto item, CancellationToken cancellationToken)
        {
            IIsoMount mountedIso = null;

            if (item.VideoType.HasValue && item.VideoType.Value == VideoType.Iso && item.IsoType.HasValue && _isoManager.CanMount(item.Path))
            {
                try
                {
                    mountedIso = await _isoManager.Mount(item.Path, cancellationToken);
                }
                catch (Exception ex)
                {
                    Logger.ErrorException("Error mounting iso {0}", ex, item.Path);
                }
            }

            return(mountedIso);
        }