예제 #1
0
        public async Task <ObservableCollection <Recording> > Find(IProgress <ProgressBarInfo> progressBar, IProgress <string> progressFileCountLabel)
        {
            progressFileCountLabel.Report("Initalizing finding recordings...");
            await Task.Delay(10);

            ObservableCollection <Recording> recordings = new ObservableCollection <Recording>();

            IMediaNamingConvention mediaNamingConvention = ServiceLocator.Current.GetInstance <IMediaNamingConvention>();

            progressFileCountLabel.Report(String.Format("Finding recordings on Tablo at IP {0}...", TabloIPAddress));
            List <int> foundRecordings = await GetRecordingList(TabloIPAddress);

            progressFileCountLabel.Report(String.Format("Found {0} files - getting recording metadata...", foundRecordings.Count()));

            int foundCount = foundRecordings.Count();
            int i          = 0;

            progressBar.Report(new ProgressBarInfo()
            {
                Maximum = foundCount, Value = i
            });
            progressFileCountLabel.Report("Loading metadata for recordings found...");

            foreach (var foundRecording in foundRecordings)
            {
                #region IF DEFs
#if TargetSingleRecording
                if (foundRecording != 611517)
                {
                    continue;
                }
#endif // TargetSingleRecording
#if LimitRecordingsFound
                if (recordings.Count == 10)
                {
                    break;
                }
#endif // LimitRecordingsFound
                #endregion
                RecordingMetadata metadata = GetRecordingMetadata(TabloIPAddress, foundRecording);
                if (metadata != null)
                {
                    if (i % 10 == 0)
                    {
                        progressFileCountLabel.Report(String.Format("Loading metadata for recordings found: {0} of {1}", i, foundCount));
                    }

                    Recording recording = new Recording()
                    {
                        Id = foundRecording, Metadata = metadata
                    };
                    if (recording.Metadata.recEpisode != null)
                    {
                        recording.Type = RecordingType.Episode;
                        if (recording.IsS00E00)
                        {
                            recording.Description = mediaNamingConvention.GetS00E00Description(OutputDirectory, recording, recordings);
                        }
                        else
                        {
                            recording.Description = mediaNamingConvention.GetEpisodeDescription(recording);
                        }
                        recording.Plot           = recording.Metadata.recEpisode.jsonForClient.description;
                        recording.RecordedOnDate = DateTime.Parse(recording.Metadata.recEpisode.jsonForClient.airDate);
                        if (recording.Metadata.recEpisode.jsonForClient.video.state.ToLower() != "finished")
                        {
                            recording.HasFinishedRecording = false;
                        }
                    }
                    else if (recording.Metadata.recMovie != null)
                    {
                        recording.Type           = RecordingType.Movie;
                        recording.Description    = mediaNamingConvention.GetMovieDescription(recording);
                        recording.RecordedOnDate = DateTime.Parse(recording.Metadata.recMovieAiring.jsonForClient.airDate);
                        recording.Plot           = recording.Metadata.recMovie.jsonForClient.plot;

                        if (recording.Metadata.recMovieAiring.jsonForClient.video.state.ToLower() != "finished")
                        {
                            recording.HasFinishedRecording = false;
                        }
                    }
                    else if (recording.Metadata.recSportEvent != null)
                    {
                        recording.Type           = RecordingType.Sports;
                        recording.Description    = mediaNamingConvention.GetSportsDescription(recording);
                        recording.RecordedOnDate = DateTime.Parse(recording.Metadata.recSportEvent.jsonForClient.airDate);
                        recording.Plot           = recording.Metadata.recSportEvent.jsonForClient.description;

                        if (recording.Metadata.recSportEvent.jsonForClient.video.state.ToLower() != "finished")
                        {
                            recording.HasFinishedRecording = false;
                        }
                    }
                    else if (recording.Metadata.recManualProgram != null)
                    {
                        recording.Type           = RecordingType.Manual;
                        recording.Description    = mediaNamingConvention.GetManualDescription(recording);
                        recording.RecordedOnDate = DateTime.Parse(recording.Metadata.recManualProgramAiring.jsonForClient.airDate);

                        if (recording.Metadata.recManualProgramAiring.jsonForClient.video.state.ToLower() != "finished")
                        {
                            recording.HasFinishedRecording = false;
                        }
                    }
                    else //If this is not a recognized recording type
                    {
                        continue; // Skip the remainder of this iteration.
                    }

                    recordings.Add(recording);
                    i++;
                    progressBar.Report(new ProgressBarInfo()
                    {
                        Maximum = null, Value = i
                    });
                    await Task.Delay(10);
                }
            }
            // });
            progressFileCountLabel.Report(String.Format("Loading metadata for recordings found: {0}", foundCount));
            progressBar.Report(new ProgressBarInfo()
            {
                Maximum = null, Value = 0
            });
            await Task.Delay(10);

            return(recordings);
        }
        private async Task GetRecordingVideo(IPEndPoint ipEndPoint, Recording recording,
                                             IProgress <ProgressBarInfo> secondaryProgressBar,
                                             IProgress <string> secondaryLabel)
        {
            try
            {
                string path = string.Format("{0}\\TempTabloExtract", Path.GetTempPath());
                if (!Directory.Exists(path))
                {
                    log.InfoFormat("Creating directory: {0}", path);
                    Directory.CreateDirectory(path);
                }
            }
            catch (IOException ex)
            {
                string text = string.Format("Unable to create temporary directory at '{0}\\TempTabloExtract'", Path.GetTempPath());
                log.Error(text, ex);
                MessageBox.Show(text);
                return;
            }

            try
            {
                if (!Directory.Exists(OutputDirectory))
                {
                    Directory.CreateDirectory(OutputDirectory);
                }
            }
            catch (IOException ex)
            {
                string text = string.Format("Unable to create output directory at '{0}'", OutputDirectory);
                log.Error(text, ex);
                MessageBox.Show(text);
                return;
            }

            IMediaNamingConvention mediaNamingConvention = ServiceLocator.Current.GetInstance <IMediaNamingConvention>();
            string OutputFile;

            if (recording.Type == RecordingType.Episode)
            {
                OutputFile = mediaNamingConvention.GetEpisodeOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Movie)
            {
                OutputFile = mediaNamingConvention.GetMovieOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Sports)
            {
                OutputFile = mediaNamingConvention.GetSportsOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Manual)
            {
                OutputFile = mediaNamingConvention.GetManualOutputFileName(OutputDirectory, recording);
            }
            else
            {
                OutputFile = mediaNamingConvention.GetOtherOutputFileName(OutputDirectory, recording);
            }

            if (File.Exists(OutputFile))
            {
                log.InfoFormat(String.Format("File {0} already exists - skipping", OutputFile));
                return;
            }

            if (!File.Exists(FFMPEGLocation))
            {
                string notFound = "FFMPEG could not be found. It must be located before you can proceed.";
                log.InfoFormat(notFound);
                MessageBox.Show(notFound);
                return;
            }

            try
            {
                FileInfo fileInfo = new FileInfo(FFMPEGLocation);
                if (fileInfo.Name != "ffmpeg.exe")
                {
                    string notFound = "The file name provided for FFMPEG was not \"ffpmeg.exe\". It must be located before you can proceed.";
                    log.InfoFormat(notFound);
                    MessageBox.Show(notFound);
                    return;
                }
            }
            catch (Exception ex)
            {
                string notFound = "There was a problem reading from the FFMPEG exe. It must be located before you can proceed.";
                log.Info(notFound, ex);
                MessageBox.Show(notFound);
                return;
            }

            RecordingWatch recordingWatch = TabloAPI.GetRecordingWatch(recording, TabloEndPoint);

            if (String.IsNullOrWhiteSpace(recordingWatch.playlist_url))
            {
                log.ErrorFormat("recordingWatch.playlist_url for {0} is empty.", recording);
            }
            else if (await ProcessVideosInFFMPEG(recordingWatch.playlist_url, recording, OutputFile, FFMPEGLocation, secondaryProgressBar, secondaryLabel))
            {
                log.InfoFormat("playlist_url: {0}", recordingWatch.playlist_url);
                string recordingJson       = JsonConvert.SerializeObject(recording, Formatting.Indented);
                string recordingOutputFile = Path.ChangeExtension(OutputFile, ".json");
                if (File.Exists(recordingOutputFile))
                {
                    File.Delete(recordingOutputFile);
                }
                File.WriteAllText(recordingOutputFile, recordingJson);
                if (!File.Exists(recordingOutputFile))
                {
                    log.InfoFormat("Recording file: {0} written to disk.", recordingOutputFile);
                }
            }
        }
        private async Task GetRecordingVideo(IPEndPoint ipEndPoint, Recording recording,
                                             IProgress <ProgressBarInfo> secondaryProgressBar,
                                             IProgress <string> secondaryLabel)
        {
            try
            {
                string path = string.Format("{0}\\TempTabloExtract", Path.GetTempPath());
                if (!Directory.Exists(path))
                {
                    log.InfoFormat("Creating directory: {0}", path);
                    Directory.CreateDirectory(path);
                }
            }
            catch (IOException ex)
            {
                string text = string.Format("Unable to create temporary directory at '{0}\\TempTabloExtract'", Path.GetTempPath());
                log.Debug(text, ex);
                MessageBox.Show(text);
                return;
            }

            try
            {
                if (!Directory.Exists(OutputDirectory))
                {
                    Directory.CreateDirectory(OutputDirectory);
                }
            }
            catch (IOException ex)
            {
                string text = string.Format("Unable to create output directory at '{0}'", OutputDirectory);
                log.Debug(text, ex);
                MessageBox.Show(text);
                return;
            }

            IMediaNamingConvention mediaNamingConvention = ServiceLocator.Current.GetInstance <IMediaNamingConvention>();
            string OutputFile;

            if (recording.Type == RecordingType.Episode)
            {
                OutputFile = mediaNamingConvention.GetEpisodeOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Movie)
            {
                OutputFile = mediaNamingConvention.GetMovieOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Sports)
            {
                OutputFile = mediaNamingConvention.GetSportsOutputFileName(OutputDirectory, recording);
                string dir = Path.GetDirectoryName(OutputFile);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
            else if (recording.Type == RecordingType.Manual)
            {
                OutputFile = mediaNamingConvention.GetManualOutputFileName(OutputDirectory, recording);
            }
            else
            {
                OutputFile = mediaNamingConvention.GetOtherOutputFileName(OutputDirectory, recording);
            }

            if (File.Exists(OutputFile))
            {
                log.InfoFormat(String.Format("File {0} already exists - skipping", OutputFile));
                return;
            }

            if (!File.Exists(FFMPEGLocation))
            {
                string notFound = "FFMPEG could not be found. It must be located before you can proceed.";
                log.InfoFormat(notFound);
                MessageBox.Show(notFound);
                return;
            }
            try
            {
                FileInfo fileInfo = new FileInfo(FFMPEGLocation);
                if (fileInfo.Name != "ffmpeg.exe")
                {
                    string notFound = "The file name provided for FFMPEG was not \"ffpmeg.exe\". It must be located before you can proceed.";
                    log.InfoFormat(notFound);
                    MessageBox.Show(notFound);
                    return;
                }
            }
            catch (Exception ex)
            {
                string notFound = "There was a problem reading from the FFMPEG exe. It must be located before you can proceed.";
                log.Info(notFound, ex);
                MessageBox.Show(notFound);
                return;
            }

            string webPageText;

            using (WebClient client = new WebClient())
            {
                string webAddress = string.Format("http://{0}:18080/pvr/{1}/segs/", TabloEndPoint.Address, recording.Id);
                log.InfoFormat("Downloading web resource from: {0}", webAddress);
                webPageText = client.DownloadString(webAddress);
            }
            log.Info("Getting TS files...");
            List <string> tsFileNames = new List <string>();

            foreach (var line in webPageText.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None))
            {
                if (line.Contains("video/MP2T"))
                {
                    string tsFileName = line.Split(new string[] { "<a href=\"", ".ts" }, StringSplitOptions.None)[1] + ".ts";
                    tsFileNames.Add(tsFileName);
                }
#if LimitTSFilesInVideo
                if (tsFileNames.Count == 100)
                {
                    break;
                }
#endif
            }

            log.InfoFormat("Found {0} TS files for {1}.", tsFileNames.Count(), recording.Description);
            secondaryLabel.Report(String.Format("TS file count: {0}", tsFileNames.Count()));
            await Task.Delay(5);

            List <string> tsVideoFileNames = new List <string>();

            int i = 0;
            secondaryProgressBar.Report(new ProgressBarInfo()
            {
                Maximum = tsFileNames.Count(), Value = 0
            });
            await Task.Delay(5);

            foreach (var tsFileName in tsFileNames)
            {
                //progress.Report(String.Format("  Downloading '{0}'...", tsFileName));
                using (WebClient Client = new WebClient())
                {
                    string downloadURL = String.Format("http://{0}:18080/pvr/{1}/segs/{2}", TabloEndPoint.Address, recording.Id, tsFileName);
                    //  string outputFileName = String.Format("{0}\\TempTabloExtract\\{1}-{2}", Path.GetTempPath(), recording.Id, tsFileName);
                    string outputFileName = String.Format("{0}\\TempTabloExtract\\{1}", Path.GetTempPath(), tsFileName);

                    log.InfoFormat("Downloading TS file: {0} to {1}", downloadURL, outputFileName);
                    await Client.DownloadFileTaskAsync(downloadURL, outputFileName);

                    tsVideoFileNames.Add(outputFileName);
                }
                i++;
                secondaryProgressBar.Report(new ProgressBarInfo()
                {
                    Maximum = null, Value = i
                });
                await Task.Delay(5);
            }

            secondaryProgressBar.Report(new ProgressBarInfo()
            {
                Maximum = 1, Value = 0
            });
            //progress.Report(String.Format("Processing in FFMPEG to create '{0}'...", OutputFile));

            ProcessVideosInFFMPEG(tsVideoFileNames, recording, OutputFile, FFMPEGLocation);

            //ProcessVideoInHandbrake(String.Format("{0}\\TempTabloExtract", Path.GetTempPath()), OutputFile);

            string recordingJson       = JsonConvert.SerializeObject(recording, Formatting.Indented);
            string recordingOutputFile = Path.ChangeExtension(OutputFile, ".json");
            if (File.Exists(recordingOutputFile))
            {
                File.Delete(recordingOutputFile);
            }
            File.WriteAllText(recordingOutputFile, recordingJson);
            if (!File.Exists(recordingOutputFile))
            {
                log.ErrorFormat("Recording file: {0} was not written!", recordingOutputFile);
            }
            else
            {
                log.InfoFormat("Recording file: {0} written to disk.", recordingOutputFile);
            }

            foreach (var outputFileName in tsVideoFileNames)
            {
                if (File.Exists(outputFileName))
                {
                    File.Delete(outputFileName);
                }
            }
        }