// TODO: Write full implementation public void Rename(CancellationToken cancellationToken, Job job) { Host.ReportProgress(this, 0.0, "Auto-renaming output file..."); var namer = new FileNamer(job, Preferences); job.OutputPath = namer.GetPath().FullName; Host.ReportProgress(this, 100.0, "Finished auto-renaming output file"); }
public FormFileNamerPreferences(Preferences prefs) { _userPrefs = prefs; _prefsCopy = _userPrefs.Clone(); _movieJob = MockJobFactory.CreateMovieJob(); _movieNamer = new FileNamer(_movieJob, _prefsCopy); _tvShowJob = MockJobFactory.CreateTVShowJob(); _tvShowNamer = new FileNamer(_tvShowJob, _prefsCopy); InitializeComponent(); Load += OnLoad; this.EnableSelectAll(); }
public void GetMetadata(CancellationToken cancellationToken, Job job) { if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 0.0, "Querying ChapterDb.org..."); //var playlist = job.Disc.Playlists[job.SelectedPlaylistIndex]; if (job.SearchQuery != null) { var apiResults = GetChapters(job.SearchQuery.Title); /* var apiValues = CompareChapters(apiResults, playlist.Chapters); if (apiValues != null && apiValues.Count > 0) { ReplaceChapters(apiValues[0], playlist.Chapters); }*/ if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 90.0, "Comparing search results to available playlists..."); foreach(var moviePlaylist in job.Disc.Playlists) { var apiValues = CompareChapters(apiResults, moviePlaylist.Chapters); if (apiValues != null && apiValues.Count > 0) { StoreSearchResults(apiValues, moviePlaylist); // To Do: Allow the user to select which chapter list to use when // defaulted to [0] first chapter list that matches filter criteria ReplaceChapters(apiValues[0], moviePlaylist.Chapters); var Message = "Custom chapters were added to: " + moviePlaylist.FileName; Logger.Info(Message); } } } if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 100.0, "Finished querying ChapterDb.org"); }
public void GetMetadata(CancellationToken cancellationToken, Job job) { var raw = job.Disc.Metadata.Raw; var derived = job.Disc.Metadata.Derived; var token = new ProgressToken(Host, this, cancellationToken); var provider = new IsanMetadataProvider(token); provider.Populate(raw.V_ISAN); var isan = raw.ISAN; if (isan != null && !string.IsNullOrWhiteSpace(isan.Title)) { // TODO: Scrape language from isan.org // Don't insert twice if (!derived.SearchQueries.Any(query => query.Title == isan.Title && query.Year == isan.Year)) derived.SearchQueries.Insert(0, new SearchQuery { Title = isan.Title, Year = isan.Year }); } }
public void GetMetadata(CancellationToken cancellationToken, Job job) { var raw = job.Disc.Metadata.Raw; var derived = job.Disc.Metadata.Derived; var token = new ProgressToken(Host, this, cancellationToken); var prefs = PluginUtils.GetPreferences(AssemblyInfo, () => new IsanPreferences()); if (raw.V_ISAN != null && prefs.TryPopulate(raw.V_ISAN)) { return; } Lookup(token, raw, derived); if (raw.V_ISAN != null) { prefs.Store(raw.V_ISAN); PluginUtils.SavePreferences(AssemblyInfo, prefs); } }
public void GetMetadata(CancellationToken cancellationToken, Job job) { if (cancellationToken.IsCancellationRequested) return; StartProgress("Loading plugin preferences..."); var prefs = LoadPreferences(); if (cancellationToken.IsCancellationRequested) return; ApiRequest(job); if (cancellationToken.IsCancellationRequested) return; GetPosters(job); FinishProgress("Finished querying TMDb"); }
public FFmpeg(Job job, Playlist playlist, string outputMKVPath, IJobObjectManager jobObjectManager, ITempFileRegistrar tempFileRegistrar) : base(jobObjectManager) { _playlistLength = playlist.Length; _inputM2TSPaths = playlist.StreamClips.Select(clip => clip.FileInfo.FullName).ToList(); _selectedTracks = playlist.Tracks.Where(track => track.Keep).ToList(); _outputMKVPath = outputMKVPath; _jobObjectManager = jobObjectManager; _tempFileRegistrar = tempFileRegistrar; _progressFilePath = _tempFileRegistrar.CreateTempFile(GetType(), "progress.log"); _inputFileListPath = _tempFileRegistrar.CreateTempFile(GetType(), "inputFileList.txt"); _indexer = new FFmpegTrackIndexer(playlist); VerifyInputPaths(); VerifySelectedTracks(); SetExePath(); SetFFmpegLogLevel(); RedirectProgressToFile(); ReplaceExistingFiles(); SetInputFiles(); SetMovieTitle(job); MapSelectedTracks(); CopyAllCodecs(); ConvertLPCM(); SetOutputMKVPath(); BeforeStart += OnBeforeStart; StdErr += OnStdErr; Exited += (state, code, exception, time) => OnExited(state, code, job.SelectedReleaseMedium, playlist, _selectedTracks, outputMKVPath); foreach (var track in playlist.Tracks) { var index = _indexer[track]; Logger.InfoFormat("Track w/ stream PID {0} (0x{0:x4}): index {1} => {2} ({3})", track.PID, index.InputIndex, index.OutputIndex, track.Codec); } }
public void AutoDetect(CancellationToken cancellationToken, Job job) { if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 0.0, "Gathering data..."); var disc = job.Disc; // Data gathering (round 1) FindDuplicatePlaylists(disc); TransformPlaylistQuality(disc); if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 25.0, "Auto-detecting track types..."); // Auto-configuration DetectPlaylistTypes(disc); DetectMainFeaturePlaylistTrackTypes(disc); DetectCommentaryPlaylistTrackTypes(disc); DetectSpecialFeaturePlaylistTrackTypes(disc); if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 75.0, "Auto-selecting best playlists and tracks..."); SelectBestPlaylist(job); SelectBestTracks(disc); if (cancellationToken.IsCancellationRequested) return; Host.ReportProgress(this, 100.0, "Finished auto detecting"); }
private void GetPosters(Job job) { MakeProgress("Getting poster images..."); foreach (var movie in job.Movies) { var tmdbMovieImages = new TmdbMovieImages(); try { if (string.IsNullOrEmpty(_rootImageUrl)) { _rootImageUrl = GetConfiguration().images.base_url + "original"; } tmdbMovieImages = _tmdbApi.GetMovieImages(movie.Id, null); var posterLanguages = (tmdbMovieImages.posters.Select(poster => poster.iso_639_1).ToList()); posterLanguages = posterLanguages.Distinct().ToList(); if (posterLanguages.Count == 0) { tmdbMovieImages = _tmdbApi.GetMovieImages(movie.Id, "en"); } } catch (Exception ex) { HandleTmdbError(ex); } if (tmdbMovieImages == null) continue; foreach (var poster in tmdbMovieImages.posters) { poster.file_path = _rootImageUrl + poster.file_path; if (movie.CoverArtImages.OfType<RemoteCoverArt>().All(x => x.Uri != poster.file_path)) { movie.CoverArtImages.Add(new RemoteCoverArt { Uri = _rootImageUrl + poster.file_path, Language = Language.FromCode(poster.iso_639_1) }); } } } }
private static void SelectBestPlaylist(Job job) { var bestPlaylists = job.Disc.ValidMainFeaturePlaylists; var bestPlaylist = bestPlaylists.FirstOrDefault(); if (bestPlaylist == null) return; bestPlaylists.ForEach(playlist => playlist.IsBestGuess = true); job.SelectedPlaylistIndex = job.Disc.Playlists.IndexOf(bestPlaylist); }
private void SetMovieTitle(Job job) { var title = job.SearchQuery.Title; var releaseMedium = job.SelectedReleaseMedium; if (releaseMedium != null) { var movie = releaseMedium as Movie; var tvShow = releaseMedium as TVShow; if (movie != null) { title = movie.ToString(); } else if (tvShow != null) { title = string.Format("{0} - {1}, season {2}, episode {3} ({4})", tvShow.SelectedEpisode.Title, tvShow.Title, tvShow.SelectedEpisode.SeasonNumber, tvShow.SelectedEpisode.EpisodeNumber, tvShow.SelectedEpisode.ReleaseDate.ToString("yyyy'-'MM'-'dd")); } else { title = releaseMedium.Title; } } Arguments.AddAll("-metadata", "title=" + title); }
private void SearchTmdb(TmdbApiParameters requestParameters, Job job) { GetBaseImageUrl(); _tmdbMovieSearch = _tmdbApi.SearchMovie(requestParameters.Query, 1, requestParameters.Iso6391, false, requestParameters.Year); if (_tmdbMovieSearch == null) { Logger.Warn("TMDb movie search returned null"); return; } job.Movies.AddRange(_tmdbMovieSearch.results.Select(ToMovie)); LogSearchResults(); }
private void ApiRequest(Job job) { var searchYear = job.SearchQuery.Year; QueryTmdb(job, 1, searchYear); if (!searchYear.HasValue || job.Movies.Any()) return; // isan.org has the wrong year for some movies... // Search again w/ year + 1 if there are zero results for isan.org's year value QueryTmdb(job, 2, searchYear + 1); if (job.Movies.Any()) return; // Search again w/o sending a year if there are still zero results QueryTmdb(job, 3); }
internal static Job CreateTVShowJob() { var metadata = new DiscMetadata { Derived = new DiscMetadata.DerivedMetadata { VolumeLabel = "SCRUBS_S1_D1" } }; var disc = new Disc { Metadata = metadata, Playlists = new List<Playlist> { new Playlist { Tracks = new List<Track> { new Track { IsVideo = true, Codec = Codec.AVC, Type = TrackType.MainFeature, VideoFormat = TSVideoFormat.VIDEOFORMAT_1080p, AspectRatio = TSAspectRatio.ASPECT_16_9, Index = 0, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsAudio = true, Codec = Codec.DTSHDMA, Type = TrackType.MainFeature, ChannelCount = 5.1, Index = 1, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsSubtitle = true, Codec = Codec.PGS, Type = TrackType.MainFeature, Index = 2, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, } } } }; var job = new Job(disc) { ReleaseMediumType = ReleaseMediumType.TVShow, SearchQuery = new SearchQuery { Title = "Scrubs", Year = 2001, Language = Language.English } }; var tvShow = new TVShow { IsSelected = true, Title = "Scrubs", Id = 76156, Url = "http://thetvdb.com/?tab=series&id=76156&lid=7", SelectedEpisodeIndex = 0 }; tvShow.Episodes.AddRange(new[] { new TVShow.Episode { SeasonNumber = 1, EpisodeNumber = 1, Title = "My First Day", Id = 184602, ReleaseDate = DateTime.Parse("2001-10-02") } }); job.TVShows.Add(tvShow); return job; }
public FileNamer(Job job, Preferences prefs) { _job = job; _prefs = prefs; }
private void ApiRequest(Job job, SearchQuery query) { job.Movies.Clear(); var searchTitle = query.Title; var searchYear = query.Year; if (_apiKey == null) { const string message = "ERROR: No API key found"; Logger.Error(message); throw new Exception(message); } _tmdbApi = new Tmdb(_apiKey, _searchISO_639_1); // TMDb (previously) choked on dashes - not sure if it still does or not... // E.G.: "The Amazing Spider-Man" --> "The Amazing Spider Man" searchTitle = Regex.Replace(searchTitle, @"-+", " "); var requestParameters = new TmdbApiParameters(searchTitle, searchYear, _searchISO_639_1); try { SearchTmdb(requestParameters, job); } catch (Exception ex) { HandleTmdbError(ex); } }
private bool ReadBDROM(CancellationToken cancellationToken, string bdromPath) { IDiscReaderPlugin discReader = _pluginRepository.DiscReaderPlugins.First(plugin => plugin.Enabled); var pluginTask = RunPluginSync(cancellationToken, discReader, delegate(CancellationToken token) { var disc = discReader.ReadBDROM(token, bdromPath); if (!token.IsCancellationRequested) { Job = new Job(disc); } }); return pluginTask.IsCompleted && pluginTask.Result; }
private void QueryTmdb(Job job, int attempt, int? searchYear = null) { MakeProgress(string.Format("Querying TMDb w/ year = {0} (attempt {1})...", searchYear, attempt)); ApiRequest(job, searchYear); }
public void Mux(CancellationToken cancellationToken, Job job) { }
public void Mux(CancellationToken cancellationToken, Job job) { if (cancellationToken.IsCancellationRequested) return; const string startStatus = "Starting FFmpeg process..."; Host.ReportProgress(this, 0.0, startStatus); Logger.Info(startStatus); _exception = null; var ffmpeg = new FFmpeg(job, job.SelectedPlaylist, job.OutputPath, _jobObjectManager, _tempFileRegistrar); ffmpeg.ProgressUpdated += state => OnProgressUpdated(ffmpeg, state, cancellationToken); ffmpeg.Exited += FFmpegOnExited; ffmpeg.StartAsync(); cancellationToken.Register(ffmpeg.Kill, true); WaitForThreadToExit(); if (_exception == null) return; if (_exception is OperationCanceledException) throw new OperationCanceledException("FFmpeg was canceled", _exception); throw new Exception("Error occurred while muxing with FFmpeg", _exception); }
private void QueryTmdb(int attempt, Job job, SearchQuery query) { MakeProgress(string.Format("Querying TMDb w/ year = {0} (attempt {1})...", query.Year, attempt)); ApiRequest(job, query); }
internal static Job CreateMovieJob() { var metadata = new DiscMetadata { Derived = new DiscMetadata.DerivedMetadata { VolumeLabel = "EMPIRE_STRIKES_BACK" } }; var disc = new Disc { Metadata = metadata, Playlists = new List<Playlist> { new Playlist { Tracks = new List<Track> { new Track { IsVideo = true, Codec = Codec.AVC, Type = TrackType.MainFeature, VideoFormat = TSVideoFormat.VIDEOFORMAT_1080p, AspectRatio = TSAspectRatio.ASPECT_16_9, Index = 0, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsAudio = true, Codec = Codec.DTSHDMA, Type = TrackType.MainFeature, ChannelCount = 6.1, Index = 1, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, new Track { IsSubtitle = true, Codec = Codec.PGS, Type = TrackType.MainFeature, Index = 2, IndexOfType = 0, IsBestGuess = true, Keep = true, Language = Language.English }, } } } }; var job = new Job(disc) { ReleaseMediumType = ReleaseMediumType.Movie, SearchQuery = new SearchQuery { Title = "Star Wars: Episode V - The Empire Strikes Back", Year = 1980, Language = Language.English } }; job.Movies.Add(new Movie { IsSelected = true, Title = "Star Wars: Episode V - The Empire Strikes Back", ReleaseYear = 1980, Id = 1891, Url = "http://www.themoviedb.org/movie/1891-star-wars-episode-v-the-empire-strikes-back" }); return job; }
private void Search(Job job) { var attempt = 0; var queries = job.SearchQueries.SelectMany(ConstructQueries).ToArray(); _totalSteps = queries.Count() + 2; // 2 = 1 config req + 1 poster image req foreach (var query in queries) { QueryTmdb(++attempt, job, query); if (job.Movies.Any()) break; } }