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); } }
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)); }
/// <summary> /// Mounts the iso if needed. /// </summary> /// <param name="item">The item.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>IsoMount.</returns> protected Task <IIsoMount> MountIsoIfNeeded(Video item, CancellationToken cancellationToken) { if (item.VideoType == VideoType.Iso) { return(_isoManager.Mount(item.Path, cancellationToken)); } return(Task.FromResult <IIsoMount>(null)); }
/// <summary> /// Mounts the iso if needed. /// </summary> /// <param name="item">The item.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>IsoMount.</returns> protected override Task <IIsoMount> MountIsoIfNeeded(Video item, CancellationToken cancellationToken) { if (item.VideoType == VideoType.Iso) { return(_isoManager.Mount(item.Path, cancellationToken)); } return(base.MountIsoIfNeeded(item, cancellationToken)); }
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"; } } } }
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); }
private async Task <PlayableItem> GetPlayableItem(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(new PlayableItem { OriginalItem = item, PlayablePath = PlayablePathBuilder.GetPlayablePath(item, mountedIso, _apiClient) }); }
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 }