Esempio n. 1
0
        /// <summary>
        /// Used to execute custom commands after the conversion process is compelte just before the file is moved to the desination directory
        /// </summary>
        /// <param name="prefix">Prefix for reading lines from profile</param>
        /// <param name="profile">Profile name</param>
        /// <param name="taskName">Task Name</param>
        /// <param name="workingPath">Temp working path</param>
        /// <param name="destinationPath">Destination path for converted file</param>
        /// <param name="convertedFile">Full path to final converted file</param>
        /// <param name="sourceFile">Full path to original source file</param>
        /// <param name="remuxFile">Full path to intermediate remuxed file</param>
        /// <param name="edlFile">Full path to EDL file</param>
        /// <param name="srtFile">Full path to SRT file</param>
        /// <param name="metaData">Video metadata structure for source file</param>
        /// <param name="jobStatus">ref to JobStatus</param>
        /// <param name="jobLog">JobLog</param>
        public CustomCommand(string prefix, string profile, string taskName, string workingPath, string destinationPath, string convertedFile, string sourceFile, string remuxFile, string edlFile, string srtFile, VideoTags metaData, JobStatus jobStatus, Log jobLog)
        {
            _profile = profile;
            _taskName = taskName;
            _jobLog = jobLog;
            _jobStatus = jobStatus;
            _workingPath = workingPath;
            _destinationPath = destinationPath;
            _convertedFile = convertedFile;
            _sourceFile = sourceFile;
            _remuxFile = remuxFile;
            _edlFile = edlFile;
            _srtFile = srtFile;
            _metaData = metaData;
            _prefix = prefix;

            Ini ini = new Ini(GlobalDefs.ProfileFile);
            commandPath = ini.ReadString(profile, prefix + "Path", "").ToLower().Trim();
            commandParameters = ini.ReadString(profile, prefix + "Parameters", "");
            hangPeriod = ini.ReadInteger(profile, prefix + "HangPeriod", GlobalDefs.HANG_PERIOD_DETECT);
            customCommandCritical = ini.ReadBoolean(profile, prefix + "Critical", false); // NOTE: if customCommandCritical is TRUE will need to return false in case it's a failure
            customCommandUISession = ini.ReadBoolean(profile, prefix + "UISession", false); // Does the custom command need a UI Session (Session 1) with admin privileges
            customCommandShowWindow = ini.ReadBoolean(profile, prefix + "ShowWindow", true); // Show the window or hide it
            customCommandExitCodeCheck = ini.ReadBoolean(profile, prefix + "ExitCodeCheck", false); // Don't check for exit code

            _jobLog.WriteEntry(this, "Custom command parameters read -> " + " \n" + _prefix + "Path = " + commandPath + " \n" + _prefix + "Parameters = " + commandParameters + " \n" + _prefix + "HangPeriod = " + hangPeriod.ToString(System.Globalization.CultureInfo.InvariantCulture) + " \n" + _prefix + "Critical = " + customCommandCritical.ToString() + " \n" + _prefix + "UISession = " + customCommandUISession.ToString() + " \n" + _prefix + "ShowWindow = " + customCommandShowWindow.ToString() + " \n" + _prefix + "ExitCodeCheck = " + customCommandExitCodeCheck.ToString(), Log.LogEntryType.Debug);
        }
Esempio n. 2
0
        public RemuxMCERecording(ConversionJobOptions cjo, JobStatus jobStatus, Log jobLog)
        {
            _jobStatus = jobStatus;
            _jobLog = jobLog;
            _RecordingFile = cjo.sourceVideo;
            _destinationPath = cjo.workingPath;
            _requestedAudioLanguage = cjo.audioLanguage;
            _tivoMAKKey = cjo.tivoMAKKey;

            if (Util.FilePaths.CleanExt(_RecordingFile) == ".ts") // Handle TS files difference since they will have the same namess
                _RemuxedFile = Path.Combine(_destinationPath, Path.GetFileNameWithoutExtension(_RecordingFile) + "-REMUXED.ts");
            else
                _RemuxedFile = Path.Combine(_destinationPath, Path.GetFileNameWithoutExtension(_RecordingFile) + ".ts");

            // Read various profile parameters
            Ini configProfileIni = new Ini(GlobalDefs.ProfileFile);
            _useRemuxsupp = configProfileIni.ReadBoolean(cjo.profile, "UseWTVRemuxsupp", false); // Some videos fail with FFMPEG remuxing and Mencoder encoding (use remuxsupp for remuxing there)
            _jobLog.WriteEntry(this, "Force Remuxsupp (UseWTVRemuxsupp) : " + _useRemuxsupp.ToString(), Log.LogEntryType.Debug);

            _forceWTVStreamsRemuxing = configProfileIni.ReadBoolean(cjo.profile, "ForceWTVStreamsRemuxing", false); // Use Streams remuxing for DVRMS and WTV files
            _jobLog.WriteEntry(this, "Force Streams Remuxing (ForceWTVStreamsRemuxing) : " + _forceWTVStreamsRemuxing.ToString(), Log.LogEntryType.Debug);

            _allowH264CopyRemuxing = configProfileIni.ReadBoolean(cjo.profile, "AllowH264CopyRemuxing", true); // Allow H.264 files to be remuxed into TS without recoding to MPEG2
            _jobLog.WriteEntry(this, "Allow H264 Copy Remuxing (AllowH264CopyRemuxing) (default: true) : " + _allowH264CopyRemuxing.ToString(), Log.LogEntryType.Debug);

            _allowAllCopyRemuxing = configProfileIni.ReadBoolean(cjo.profile, "AllowAllCopyRemuxing", false); // Allow any video codec to be remuxed into TS without recoding to MPEG2
            _jobLog.WriteEntry(this, "Allow All Video codec formats Copy Remuxing (AllowAllCopyRemuxing) (default: false) : " + _allowAllCopyRemuxing.ToString(), Log.LogEntryType.Debug);

            // Get the media info for the recording file once for the entire operation to reuse
            _jobLog.WriteEntry(this, "Reading Recording file " + _RecordingFile + " media information", Log.LogEntryType.Debug);
            _RecordingFileMediaInfo = new FFmpegMediaInfo(_RecordingFile, _jobStatus, _jobLog);

            // Check for donator version of Comskip
            Comskip checkComskip = new Comskip(MCEBuddyConf.GlobalMCEConfig.GeneralOptions.comskipPath, _jobLog);

            // Check if we are using a mpeg4 video and allowing h264 video codec for commercial skipping purposes
            if (_allowH264CopyRemuxing)
            {
                if (_mpeg4Codecs.Any(s => s.Contains(_RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec.ToLower())))
                {
                    if (cjo.commercialRemoval == CommercialRemovalOptions.Comskip)
                    {
                        if (checkComskip.IsDonator)
                            _jobLog.WriteEntry(this, "AllowH264CopyRemuxing will run fast for commercial detection, using donator version of Comskip", Log.LogEntryType.Information);
                        else
                            _jobLog.WriteEntry(this, "AllowH264CopyRemuxing is SLOW with the bundled Comskip. Use ShowAnalyzer or Comskip Donator version (http://www.comskip.org) to speed up commercial detection. Codec detected -> " + _RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec, Log.LogEntryType.Warning);
                    }
                }
            }

            // Check if we are using an unsupported codec and copying to TS format
            if (_allowAllCopyRemuxing)
                if (!_supportedCodecs.Any(s => s.Contains(_RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec.ToLower()))) // Check if we using any of the default supported codecs
                        _jobLog.WriteEntry(this, "AllowAllCopyRemuxing is enabled and an unsupported codec in the source video is detected. Some underlying programs may not work with this codec. Codec detected -> " + _RecordingFileMediaInfo.MediaInfo.VideoInfo.VideoCodec, Log.LogEntryType.Warning);
        }
Esempio n. 3
0
        private string _srtFile = ""; // Subtitle file

        public ConvertWithFfmpeg(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan, string srtFile)
            : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan)
        {
            passLog = Path.Combine(_workingPath, "MCEBuddy2Pass.log"); // Name of passlog file
            //Check if MEncoder EDL Removal has been disabled at conversion time
            Ini ini = new Ini(GlobalDefs.ProfileFile);
            if(ini.ReadBoolean(conversionOptions.profile, tool + "-SubtitleBurn", false))
                _srtFile = srtFile; // Save the SRT file info otherwise skip it
        }
Esempio n. 4
0
        private string _XMLCHAPFile = ""; // If the XML CHAP file exists

        /// <summary>
        /// Class for manipulating EDL, EDLP and CHAP files
        /// </summary>
        /// <param name="profile">Conversion Profile name</param>
        /// <param name="fileName">Full path Video from which EDL, EDLP and CHAP filenames will be dervied</param>
        /// <param name="duration">Length of video</param>
        /// <param name="edlFile">EDL File used to set the initial EDLFile property</param>
        /// <param name="initialSkipSeconds">Number of seconds of the file cut which needs to be adjusted while calculating cut segments</param>
        public EDL(string profile, string fileName, float duration, string edlFile, float initialSkipSeconds, JobStatus jobStatus, Log jobLog)
        {
            _profile = profile;
            _videoFileName = fileName;
            _duration = duration;
            _initialSkipSeconds = initialSkipSeconds;
            _jobLog = jobLog;
            _jobStatus = jobStatus;
            _EDLFile = edlFile;

            //check if we need to use the EDL file instead of the EDLP file
            Ini ini = new Ini(GlobalDefs.ProfileFile);
            _forceEDL = ini.ReadBoolean(_profile, "ForceEDL", false);
            _forceEDLP = ini.ReadBoolean(_profile, "ForceEDLP", false);

            // Fix duration for initial skip seconds
            _duration = (_duration - _initialSkipSeconds < 0 ? 0 : _duration - _initialSkipSeconds);

            _jobLog.WriteEntry(this, "EDL: Initial skip seconds adjustment " + _initialSkipSeconds.ToString(CultureInfo.InvariantCulture) + " seconds.", Log.LogEntryType.Debug);
        }
Esempio n. 5
0
        public Remover(string profile, string uncutVideo, string workingPath, string edlFile, float initialSkipSeconds, VideoInfo remuxedVideoFileInfo, JobStatus jobStatus, Log jobLog)
            : base(profile, uncutVideo, remuxedVideoFileInfo.Duration, edlFile, initialSkipSeconds, jobStatus, jobLog)
        {
            _remuxedVideoFileInfo = remuxedVideoFileInfo;
            _uncutVideo = uncutVideo;
            _ext = Util.FilePaths.CleanExt(_uncutVideo);
            _workingPath = workingPath;
            _duration = _remuxedVideoFileInfo.Duration;
            _jobStatus = jobStatus;
            _jobLog = jobLog;

            // Read various profile parameters
            Ini configProfileIni = new Ini(GlobalDefs.ProfileFile);
            _cutMP4Alternative = configProfileIni.ReadBoolean(profile, "CutMP4Alternate", false); // for FFMPEG and Handbrake, we have commerical cutting options, for mEncoder cutting is done during conversion using -edl option
            jobLog.WriteEntry("MP4 Alternative Cutting -> " + _cutMP4Alternative.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            _universalCommercialRemover = configProfileIni.ReadBoolean(profile, "UniversalCommercialRemover", false); // Forcing the use of CutFFMPEG which works on all video types
            jobLog.WriteEntry("Universal Commercial Remover -> " + _universalCommercialRemover.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug);
            string commercialMerge = configProfileIni.ReadString(profile, "CommercialMergeTool", ""); // Force tool to merge commercial segments
            jobLog.WriteEntry("Force Commercial Segment Merging Tool -> " + commercialMerge, Log.LogEntryType.Debug);

            switch (commercialMerge.ToLower())
            {
                case "avidemux":
                    _useAVIDemuxMerge = true;
                    break;

                case "ffmpeg":
                    _useFFMPEGMerge = true;
                    break;

                case "":
                    break;

                default:
                    jobLog.WriteEntry("INVALID Force Commercial Segment Merging Tool -> " + commercialMerge, Log.LogEntryType.Warning);
                    break;
            }
        }
Esempio n. 6
0
        public ConversionJob(ConversionJobOptions conversionJobOptions, VideoMetaData metaData)
        {
            _conversionOptions = conversionJobOptions; // First thing to do
            _metaData = metaData; // Save the metadata if present

            _originalFileNameBackup = _conversionOptions.sourceVideo; // This is what we use to report to the world what we're working on, _sourceVideo may change under certain conditions below
            if (String.IsNullOrEmpty(_conversionOptions.destinationPath))
                _conversionOptions.destinationPath = Path.GetDirectoryName(_conversionOptions.sourceVideo); // No dest path = convert in place

            _jobStatus = new JobStatus();
            _jobStatus.SourceFile = _conversionOptions.sourceVideo;
            _jobStatus.TaskName = _conversionOptions.taskName;

            // Read various engine parameters
            _maxConcurrentJobs = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.maxConcurrentJobs;
            _spaceCheck = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.spaceCheck;
            _subtitleSegmentOffset = MCEBuddyConf.GlobalMCEConfig.GeneralOptions.subtitleSegmentOffset;

            // Read various profile parameters
            Ini configProfileIni = new Ini(GlobalDefs.ProfileFile);

            // Profile only parameters 
            _preConversionCommercialRemover = configProfileIni.ReadBoolean(_conversionOptions.profile, "PreConversionCommercialRemover", false); // Check if the user wants to remove commercials before the actual conversion in which case we always return false - i.e. remove commercial during remux stage
            _copyLOGFile = configProfileIni.ReadBoolean(_conversionOptions.profile, "CopyLogFile", false); // Check if the user wants to save the log file generated by Comskip
            _copyPropertiesFile = configProfileIni.ReadBoolean(_conversionOptions.profile, "CopyPropertiesFile", false); // Check if the user wants to save the properties file for SageTV metadata

            if (configProfileIni.ReadString(_conversionOptions.profile, "AutoDeinterlace", "default") == "default")
                _autoDeinterlace = _conversionOptions.autoDeInterlace;
            else
                _autoDeinterlace = configProfileIni.ReadBoolean(_conversionOptions.profile, "AutoDeinterlace", false);

            if (_conversionOptions.renameOnly)
                _commercialSkipCut = true; //no cutting if we are renaming only
            else if (configProfileIni.ReadString(_conversionOptions.profile, "CommercialSkipCut", "default") == "default")
                _commercialSkipCut = _conversionOptions.commercialSkipCut;
            else _commercialSkipCut = configProfileIni.ReadBoolean(_conversionOptions.profile, "CommercialSkipCut", false);
        }
Esempio n. 7
0
        private const double DRC = 0.8; // Dynamic Range Compression to 80%

        public ConvertWithMencoder(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan)
            : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan)
        {
            //Check if MEncoder EDL Removal has been disabled at conversion time
            Ini ini = new Ini(GlobalDefs.ProfileFile);
            mEncoderEDLSkip = ini.ReadBoolean(conversionOptions.profile, "MEncoderEDLSkip", false);
            
            _extractCC = conversionOptions.extractCC;
            if (!String.IsNullOrEmpty(_extractCC)) // If Closed Caption extraction is enabled, we don't use cut EDL using Mencoder during encoding, Mencoder has a bug which causes it to cut out of sync with the EDL file which throws the CC out of sync, it will be cut separately
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("Closed Captions Enabled, skipping EDL cutting during encoding"), Log.LogEntryType.Information);
                mEncoderEDLSkip = true;
            }
            
            if ((_startTrim != 0) || (_endTrim != 0)) // If trimming is enabled skip cutting using EDL otherwise MEncoder messes it up
            {
                _jobLog.WriteEntry(this, Localise.GetPhrase("Trimming Enabled, skipping EDL cutting during encoding"), Log.LogEntryType.Information);
                mEncoderEDLSkip = true;
            }
        }
Esempio n. 8
0
        public ConvertWithHandbrake(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan)
            : base(conversionOptions, tool, videoFile, jobStatus, jobLog, commercialScan)
        {
            // Check if we have hardware encoding support available on the system
            Handbrake hb = new Handbrake(jobLog);
            hardwareEncodingAvailable = hb.QuickSyncEncodingAvailable;

            //Check if the profiles is setup for Hardware encoding, if so don't adjust hardware encoding options
            Ini ini = new Ini(GlobalDefs.ProfileFile);
            bool profileHardwareEncoding = ini.ReadBoolean(conversionOptions.profile, tool + "-UsingHardwareEncoding", false);
            if (_preferHardwareEncoding && profileHardwareEncoding)
            {
                _jobLog.WriteEntry(this, "Hardware enabled handbrake profile, disabling auto hardware encoder adjustments", Log.LogEntryType.Debug);
                _preferHardwareEncoding = false; // Don't change any settings, this profile is already setup for hardware encoding
            }

            // Check if we are using any of the h264 codecs, only then can we use hardware encoder for H264
            if (_preferHardwareEncoding && !h264Encoders.Any((new FFMpegMEncoderParams(_videoParams)).ParameterValue("-e").ToLower().Equals))
            {
                _jobLog.WriteEntry(this, "Cannot find h264 encoder, disabling auto hardware h264 encoder adjustments", Log.LogEntryType.Debug);
                _preferHardwareEncoding = false; // Don't use hardware encoder since this isn't a h264 profile
            }
        }
Esempio n. 9
0
        private string _renameConvertedFileWithOriginalName = ""; // Keep track incase of filename conflict

        protected ConvertBase(ConversionJobOptions conversionOptions, string tool, VideoInfo videoFile, JobStatus jobStatus, Log jobLog, Scanner commercialScan)
            : base (true)
        {
            //Setup log and status
            _jobStatus = jobStatus;
            _jobLog = jobLog;

            //Set the destination paths
            _workingPath = conversionOptions.workingPath;
            Util.FilePaths.CreateDir(_workingPath);

            // Check first up to see if the source video uses an unsupported combination for this profile
            // Container, Video Codec, Audio Codec and whether it was originally a Media Center recording or not
            _videoFile = videoFile;
            _commercialScan = commercialScan;
            if (CheckUnsupported(conversionOptions.profile, tool)) return;

            // Set the input params and get the standard settings
            _maxWidth = conversionOptions.maxWidth;
            _userQuality = conversionOptions.qualityMultiplier;
            _volume = conversionOptions.volumeMultiplier;
            _drc = conversionOptions.drc;
            _startTrim = conversionOptions.startTrim;
            _endTrim = conversionOptions.endTrim;
            _encoderChooseBestAudioTrack = conversionOptions.encoderSelectBestAudioTrack;
            _fps = conversionOptions.FPS;
            _preferHardwareEncoding = conversionOptions.preferHardwareEncoding;

            Ini ini = new Ini(GlobalDefs.ProfileFile);

            // Profile override parameters - if default (i.e. does not exist then use conversion options else use profile parameters)
            if (ini.ReadString(conversionOptions.profile, "2ChannelAudio", "default") == "default")
                _2ChannelAudio = conversionOptions.stereoAudio;
            else
                _2ChannelAudio = ini.ReadBoolean(conversionOptions.profile, "2ChannelAudio", false); // Fix output to 2 channels (from profile)
            
            if (ini.ReadString(conversionOptions.profile, "SkipCropping", "default") == "default")
                _skipCropping = conversionOptions.disableCropping;
            else
                _skipCropping = ini.ReadBoolean(conversionOptions.profile, "SkipCropping", false); // Cropping can be forced in the profile
            
            if (ini.ReadString(conversionOptions.profile, "AutoDeinterlace", "default") == "default")
                _autoDeInterlacing = conversionOptions.autoDeInterlace;
            else
                _autoDeInterlacing = ini.ReadBoolean(conversionOptions.profile, "AutoDeinterlace", false);

            if (conversionOptions.renameOnly)
                _commercialSkipCut = true; //no cutting if we are renaming only
            else if (ini.ReadString(conversionOptions.profile, "CommercialSkipCut", "default") == "default")
                _commercialSkipCut = conversionOptions.commercialSkipCut;
            else _commercialSkipCut = ini.ReadBoolean(conversionOptions.profile, "CommercialSkipCut", false);

            // Profile only parameters
            _fixedResolution = ini.ReadBoolean(conversionOptions.profile, "FixedResolution", false);
            _2Pass = ini.ReadBoolean(conversionOptions.profile, "2pass", false);
            _generalParams = ini.ReadString(conversionOptions.profile, tool + "-general", "");
            _videoParams = ini.ReadString(conversionOptions.profile, tool + "-video", "");
            _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audio", "");
            _extension = _videoFile.Extension = ini.ReadString(conversionOptions.profile, tool + "-ext", "").ToLower().Trim();
            if (string.IsNullOrWhiteSpace(_extension)) // Special case copy converter if there is no specified extension, it will be using the source file extension
                _extension = FilePaths.CleanExt(SourceVideo);
            _remuxTo = _videoFile.RemuxTo = ini.ReadString(conversionOptions.profile, tool + "-remuxto", "").ToLower().Trim();
            _audioDelay = ini.ReadString(conversionOptions.profile, tool + "-audiodelay", "skip").ToLower().Trim();

            if (_audioDelay == "auto") // Use the audio delay specified in the file
                _toolAudioDelay = videoFile.AudioDelay;
            else if (_audioDelay != "skip")
                double.TryParse(_audioDelay, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out _toolAudioDelay);

            if (conversionOptions.audioOffset != 0) // Conversion options Audio Delay takes priority over profile Audio Delay
                _toolAudioDelay = conversionOptions.audioOffset; 

            // Audio select the AC3 audio option if the source video has AC3)
            if (((videoFile.AudioCodec == "ac-3") || (videoFile.AudioCodec == "ac3") || (videoFile.AudioCodec != "e-ac-3") || (videoFile.AudioCodec != "eac3")) && (ini.ReadString(conversionOptions.profile, tool + "-audioac3", "") != ""))
                _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audioac3", _audioParams);

            // E-AC3 test option if the source video has E-AC3 - Not required as mencoder can handle eac3 audio
            /*
            if (videoFile.AudioCodec == "e-ac-3" || _videoFile.AudioCodec != "eac3")
            {
                _audioParams = ini.ReadString(conversionOptions.profile, tool + "-audioeac3", _audioParams);
                if ((_audioParams == "") && (tool == "mencoder"))
                    _audioParams = "-noaudio ";
            }*/

            // Important to use temp name while converting - sometimes the sources files are copied to the working directory and the converted files conflict with teh original filename, compensate. E.g. TS file input, TS file output with Copy converter
            _convertedFile = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + "-converted" + _extension);
            _renameConvertedFileWithOriginalName = Path.Combine(_workingPath, Path.GetFileNameWithoutExtension(SourceVideo) + _extension);
        }
Esempio n. 10
0
        private void ReadMonitorSettings(Ini configIni)
        {
            // Read the Monitor Tasks
            string[] searchRecords = configIni.ReadString("Engine", "SearchRecords", "").Split(',');
            foreach (string searchRecord in searchRecords)
            {
                if (String.IsNullOrEmpty(searchRecord))
                    continue;

                MonitorJobOptions mjo = new MonitorJobOptions();

                mjo.taskName = searchRecord;
                mjo.searchPath = configIni.ReadString(searchRecord, "SearchPath", "");
                CheckPathEnding(ref mjo.searchPath);
                mjo.searchPattern = configIni.ReadString(searchRecord, "SearchPattern", GlobalDefs.DEFAULT_VIDEO_STRING);
                mjo.searchPattern = mjo.searchPattern.Replace(GlobalDefs.DEFAULT_VIDEO_STRING, GlobalDefs.DEFAULT_VIDEO_FILE_TYPES);
                mjo.monitorSubdirectories = configIni.ReadBoolean(searchRecord, "MonitorSubdirectories", true);
                mjo.monitorConvertedFiles = configIni.ReadBoolean(searchRecord, "MonitorConvertedFiles", false);
                mjo.reMonitorRecordedFiles = configIni.ReadBoolean(searchRecord, "ReMonitorRecordedFiles", false);

                mjo.domainName = configIni.ReadString(searchRecord, "DomainName", "");
                mjo.userName = configIni.ReadString(searchRecord, "UserName", "Guest");
                mjo.password = configIni.ReadString(searchRecord, "Password", "");
                if (!String.IsNullOrEmpty(mjo.password))
                    mjo.password = Crypto.Decrypt(mjo.password); // Password is kept as encrypted

                mceBuddyConfSettings.monitorTasks.Add(mjo); // Add the Monitor Task object
            }
        }
Esempio n. 11
0
        private void ReadConversionSettings(Ini configIni)
        {
            // Read the Conversion Tasks
            string[] conversionRecords = configIni.ReadString("Engine", "Tasks", "").Split(',');
            foreach (string conversionRecord in conversionRecords)
            {
                if (String.IsNullOrEmpty(conversionRecord))
                    continue;

                ConversionJobOptions cjo = new ConversionJobOptions();

                cjo.taskName = conversionRecord;
                cjo.profile = configIni.ReadString(conversionRecord, "Profile", "");
                cjo.destinationPath = configIni.ReadString(conversionRecord, "DestinationPath", "");
                CheckPathEnding(ref cjo.destinationPath);
                cjo.workingPath = configIni.ReadString(conversionRecord, "WorkingPath", "");
                CheckPathEnding(ref cjo.workingPath);
                cjo.fallbackToSourcePath = configIni.ReadBoolean(conversionRecord, "FallbackDestination", false);
                cjo.autoIncrementFilename = configIni.ReadBoolean(conversionRecord, "AutoIncrementFilename", false);
                cjo.skipReprocessing = configIni.ReadBoolean(conversionRecord, "SkipReprocessing", false);
                cjo.checkReprocessingHistory = configIni.ReadBoolean(conversionRecord, "CheckReprocessingHistory", false);
                cjo.addToiTunes = configIni.ReadBoolean(conversionRecord, "AddToiTunesLibrary", false);
                cjo.addToWMP = configIni.ReadBoolean(conversionRecord, "AddToWMPLibrary", false);
                cjo.maxWidth = configIni.ReadInteger(conversionRecord, "MaxWidth", 720);
                cjo.FPS = configIni.ReadString(conversionRecord, "FPS", "");
                cjo.renameBySeries = configIni.ReadBoolean(conversionRecord, "RenameBySeries", true);
                cjo.altRenameBySeries = configIni.ReadBoolean(conversionRecord, "AltRenameBySeries", false);
                cjo.customRenameBySeries = configIni.ReadString(conversionRecord, "CustomRenameBySeries", "");
                cjo.renameOnly = configIni.ReadBoolean(conversionRecord, "RenameOnly", false);
                cjo.fileSelection = configIni.ReadString(conversionRecord, "FileSelection", "");
                cjo.metaShowSelection = configIni.ReadString(conversionRecord, "MetaSelection", "");
                cjo.metaNetworkSelection = configIni.ReadString(conversionRecord, "MetaChannelSelection", "");
                string monitorNameList = configIni.ReadString(conversionRecord, "MonitorTaskNames", "");
                if (String.IsNullOrWhiteSpace(monitorNameList))
                    cjo.monitorTaskNames = null; // list should be empty if nothing is there
                else
                    cjo.monitorTaskNames = monitorNameList.Split(',');
                cjo.audioLanguage = configIni.ReadString(conversionRecord, "AudioLanguage", "");
                string audioOffsetStr = configIni.ReadString(conversionRecord, "AudioOffset", "0");
                double.TryParse(audioOffsetStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.audioOffset);
                cjo.drc = configIni.ReadBoolean(conversionRecord, "DRC", true);
                cjo.stereoAudio = configIni.ReadBoolean(conversionRecord, "StereoAudio", true);
                cjo.encoderSelectBestAudioTrack = configIni.ReadBoolean(conversionRecord, "EncoderSelectBestAudioTrack", true);
                cjo.autoDeInterlace = configIni.ReadBoolean(conversionRecord, "AutoDeInterlace", true);
                cjo.preferHardwareEncoding = configIni.ReadBoolean(conversionRecord, "PreferHardwareEncoding", true);
                cjo.startTrim = configIni.ReadInteger(conversionRecord, "StartTrim", 0);
                cjo.endTrim = configIni.ReadInteger(conversionRecord, "EndTrim", 0);
                cjo.insertQueueTop = configIni.ReadBoolean(conversionRecord, "InsertQueueTop", false);
                cjo.extractXML = configIni.ReadBoolean(conversionRecord, "ExtractXML", false);
                cjo.writeMetadata = configIni.ReadBoolean(conversionRecord, "WriteMetadata", true);
                cjo.disableCropping = configIni.ReadBoolean(conversionRecord, "DisableCropping", false);
                cjo.commercialSkipCut = configIni.ReadBoolean(conversionRecord, "TaskCommercialSkipCut", false);
                cjo.skipCopyBackup = configIni.ReadBoolean(conversionRecord, "SkipCopyBackup", false);
                cjo.skipRemuxing = configIni.ReadBoolean(conversionRecord, "SkipRemux", false);
                cjo.ignoreCopyProtection = configIni.ReadBoolean(conversionRecord, "IgnoreCopyProtection", false);
                cjo.tivoMAKKey = configIni.ReadString(conversionRecord, "TiVOMAKKey", "");
                cjo.downloadSeriesDetails = configIni.ReadBoolean(conversionRecord, "DownloadSeriesDetails", true);
                cjo.downloadBanner = configIni.ReadBoolean(conversionRecord, "DownloadBanner", true);
                cjo.enabled = configIni.ReadBoolean(conversionRecord, "Enabled", true);
                cjo.extractCC = configIni.ReadString(conversionRecord, "ExtractCC", "");
                cjo.embedSubtitlesChapters = configIni.ReadBoolean(conversionRecord, "EmbedSubtitlesChapters", false);
                cjo.prioritizeOriginalBroadcastDateMatch = configIni.ReadBoolean(conversionRecord, "PrioritizeOriginalBroadcastDateMatch", false);

                string ccOffsetStr = configIni.ReadString(conversionRecord, "CCOffset", GlobalDefs.DefaultCCOffset);
                double.TryParse(ccOffsetStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.ccOffset);

                string qualityMultiplierStr = configIni.ReadString(conversionRecord, "QualityMultiplier", "1");
                double.TryParse(qualityMultiplierStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.qualityMultiplier);
                if (cjo.qualityMultiplier <= 0.01) cjo.qualityMultiplier = 0.01F;
                if (cjo.qualityMultiplier > 4) cjo.qualityMultiplier = 4F;

                string volumeMultiplierStr = configIni.ReadString(conversionRecord, "VolumeMultiplier", "0");
                double.TryParse(volumeMultiplierStr, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out cjo.volumeMultiplier);
                if (cjo.volumeMultiplier <= -20) cjo.volumeMultiplier = -20F; //-10db minimum
                if (cjo.volumeMultiplier > 60) cjo.volumeMultiplier = 60F; //30db max

                string metaShowType = configIni.ReadString(conversionRecord, "MetaShowTypeSelection", ShowType.Default.ToString());
                if (String.Compare(metaShowType, ShowType.Movie.ToString(), true) == 0)
                    cjo.metaShowTypeSelection = ShowType.Movie;
                else if (String.Compare(metaShowType, ShowType.Series.ToString(), true) == 0)
                    cjo.metaShowTypeSelection = ShowType.Series;
                else if (String.Compare(metaShowType, ShowType.Sports.ToString(), true) == 0)
                    cjo.metaShowTypeSelection = ShowType.Sports;
                else
                    cjo.metaShowTypeSelection = ShowType.Default;

                string drmType = configIni.ReadString(conversionRecord, "MetaDRMTypeSelection", DRMType.All.ToString());
                if (String.Compare(drmType, DRMType.Protected.ToString(), true) == 0)
                    cjo.metaDRMSelection = DRMType.Protected;
                else if (String.Compare(drmType, DRMType.Unprotected.ToString(), true) == 0)
                    cjo.metaDRMSelection = DRMType.Unprotected;
                else
                    cjo.metaDRMSelection = DRMType.All;

                string showType = configIni.ReadString(conversionRecord, "ForceShowType", ShowType.Default.ToString());
                if (String.Compare(showType, ShowType.Movie.ToString(), true) == 0)
                    cjo.forceShowType = ShowType.Movie;
                else if (String.Compare(showType, ShowType.Series.ToString(), true) == 0)
                    cjo.forceShowType = ShowType.Series;
                else if (String.Compare(showType, ShowType.Sports.ToString(), true) == 0)
                    cjo.forceShowType = ShowType.Sports;
                else
                    cjo.forceShowType = ShowType.Default;
                
                string commercialRemovalStr = configIni.ReadString(conversionRecord, "CommercialRemoval", CommercialRemovalOptions.Comskip.ToString());
                if (String.Compare(commercialRemovalStr, CommercialRemovalOptions.Comskip.ToString(), true) == 0)
                    cjo.commercialRemoval = CommercialRemovalOptions.Comskip;
                else if (String.Compare(commercialRemovalStr, CommercialRemovalOptions.ShowAnalyzer.ToString(), true) == 0)
                    cjo.commercialRemoval = CommercialRemovalOptions.ShowAnalyzer;
                else
                    cjo.commercialRemoval = CommercialRemovalOptions.None;
                
                cjo.comskipIni = configIni.ReadString(conversionRecord, "ComskipINI", "");

                cjo.domainName = configIni.ReadString(conversionRecord, "DomainName", "");
                cjo.userName = configIni.ReadString(conversionRecord, "UserName", "Guest");
                cjo.password = configIni.ReadString(conversionRecord, "Password", "");
                if (!String.IsNullOrEmpty(cjo.password))
                    cjo.password = Crypto.Decrypt(cjo.password); // Password is kept as encrypted

                int metaCorrectionsCount = configIni.ReadInteger(conversionRecord, "MetaCorrectionsCount", 0);
                if (metaCorrectionsCount < 1)
                    cjo.metadataCorrections = null;
                else
                {
                    cjo.metadataCorrections = new ConversionJobOptions.MetadataCorrectionOptions[metaCorrectionsCount];
                    for (int i = 0; i < metaCorrectionsCount; i++) // The entries are kept in their own section, easier to manage
                    {
                        cjo.metadataCorrections[i] = new ConversionJobOptions.MetadataCorrectionOptions();
                        cjo.metadataCorrections[i].originalTitle = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "OriginalTitle" + i.ToString(), "");
                        cjo.metadataCorrections[i].correctedTitle = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "CorrectedTitle" + i.ToString(), "");
                        cjo.metadataCorrections[i].tvdbSeriesId = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "TVDBSeriesId" + i.ToString(), "");
                        cjo.metadataCorrections[i].imdbSeriesId = configIni.ReadString(conversionRecord + "-MetaCorrectionEntries", "IMDBSeriesId" + i.ToString(), "");
                    }
                }

                mceBuddyConfSettings.conversionTasks.Add(cjo); // Add the Monitor Task object
            }
        }
Esempio n. 12
0
        private void ReadGeneralSettings(Ini configIni)
        {
            // Read the General Settings
            ReadHourMinute(configIni, ref mceBuddyConfSettings.generalOptions.wakeHour, ref mceBuddyConfSettings.generalOptions.wakeMinute, "Wake");
            ReadHourMinute(configIni, ref mceBuddyConfSettings.generalOptions.startHour, ref mceBuddyConfSettings.generalOptions.startMinute, "Start");
            ReadHourMinute(configIni, ref mceBuddyConfSettings.generalOptions.stopHour, ref mceBuddyConfSettings.generalOptions.stopMinute, "Stop");

            mceBuddyConfSettings.generalOptions.domainName = configIni.ReadString("Engine", "DomainName", "");
            mceBuddyConfSettings.generalOptions.userName = configIni.ReadString("Engine", "UserName", "Guest");
            mceBuddyConfSettings.generalOptions.password = configIni.ReadString("Engine", "Password", "");
            if (!String.IsNullOrEmpty(mceBuddyConfSettings.generalOptions.password))
                mceBuddyConfSettings.generalOptions.password = Crypto.Decrypt(mceBuddyConfSettings.generalOptions.password); // Password is kept as encrypted
            mceBuddyConfSettings.generalOptions.daysOfWeek = configIni.ReadString("Engine", "DaysOfWeek", "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday");
            mceBuddyConfSettings.generalOptions.maxConcurrentJobs = configIni.ReadInteger("Engine", "MaxConcurrentJobs", 1);
            mceBuddyConfSettings.generalOptions.logJobs = configIni.ReadBoolean("Engine", "LogJobs", true);
            mceBuddyConfSettings.generalOptions.logLevel = configIni.ReadInteger("Engine", "LogLevel", 3);
            mceBuddyConfSettings.generalOptions.logKeepDays = configIni.ReadInteger("Engine", "LogKeepDays", 15);
            mceBuddyConfSettings.generalOptions.deleteOriginal = configIni.ReadBoolean("Engine", "DeleteOriginal", false);
            mceBuddyConfSettings.generalOptions.useRecycleBin = configIni.ReadBoolean("Engine", "UseRecycleBin", false);
            mceBuddyConfSettings.generalOptions.archiveOriginal = configIni.ReadBoolean("Engine", "ArchiveOriginal", false);
            mceBuddyConfSettings.generalOptions.deleteConverted = configIni.ReadBoolean("Engine", "DeleteConverted", false); 
            mceBuddyConfSettings.generalOptions.allowSleep = configIni.ReadBoolean("Engine", "AllowSleep", true);
            mceBuddyConfSettings.generalOptions.suspendOnBattery = configIni.ReadBoolean("Engine", "SuspendOnBattery", false);
            mceBuddyConfSettings.generalOptions.minimumAge = configIni.ReadInteger("Engine", "MinimumAge", 0);
            mceBuddyConfSettings.generalOptions.sendEmail = configIni.ReadBoolean("Engine", "SendEmail", false);
            mceBuddyConfSettings.generalOptions.locale = configIni.ReadString("Engine", "Locale", CultureInfo.CurrentCulture.Name);
            mceBuddyConfSettings.generalOptions.tempWorkingPath = configIni.ReadString("Engine", "TempWorkingPath", "");
            CheckPathEnding(ref mceBuddyConfSettings.generalOptions.tempWorkingPath);
            mceBuddyConfSettings.generalOptions.archivePath = configIni.ReadString("Engine", "ArchivePath", "");
            CheckPathEnding(ref mceBuddyConfSettings.generalOptions.archivePath);
            mceBuddyConfSettings.generalOptions.failedPath = configIni.ReadString("Engine", "FailedPath", "");
            CheckPathEnding(ref mceBuddyConfSettings.generalOptions.failedPath);
            mceBuddyConfSettings.generalOptions.spaceCheck = configIni.ReadBoolean("Engine", "SpaceCheck", true);
            mceBuddyConfSettings.generalOptions.comskipPath = configIni.ReadString("Engine", "CustomComskipPath", "");
            mceBuddyConfSettings.generalOptions.customProfilePath = configIni.ReadString("Engine", "CustomProfilePath", "");
            mceBuddyConfSettings.generalOptions.hangTimeout = configIni.ReadInteger("Engine", "HangPeriod", GlobalDefs.HANG_PERIOD_DETECT);
            mceBuddyConfSettings.generalOptions.pollPeriod = configIni.ReadInteger("Engine", "PollPeriod", GlobalDefs.MONITOR_POLL_PERIOD);
            mceBuddyConfSettings.generalOptions.processPriority = configIni.ReadString("Engine", "ProcessPriority", "Normal");
            mceBuddyConfSettings.generalOptions.CPUAffinity = (IntPtr) configIni.ReadLong("Engine", "CPUAffinity", 0);
            mceBuddyConfSettings.generalOptions.engineRunning = configIni.ReadBoolean("Engine", "EngineRunning", false);
            mceBuddyConfSettings.generalOptions.localServerPort = configIni.ReadInteger("Engine", "LocalServerPort", int.Parse(GlobalDefs.MCEBUDDY_SERVER_PORT));
            mceBuddyConfSettings.generalOptions.uPnPEnable = configIni.ReadBoolean("Engine", "UPnPEnable", false);
            mceBuddyConfSettings.generalOptions.firewallExceptionEnabled = configIni.ReadBoolean("Engine", "FirewallExceptionEnable", false);
            string srtSegmentOffset = configIni.ReadString("Engine", "SubtitleSegmentOffset", GlobalDefs.SEGMENT_CUT_OFFSET_GOP_COMPENSATE);
            double.TryParse(srtSegmentOffset, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out mceBuddyConfSettings.generalOptions.subtitleSegmentOffset);
            
            ReadEMailSettings(configIni);
        }
Esempio n. 13
0
 private void ReadEMailSettings(Ini configIni)
 {
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.smtpServer = configIni.ReadString("Engine", "eMailServer", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.port = configIni.ReadInteger("Engine", "eMailPort", 25); // default port is 25
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.ssl = configIni.ReadBoolean("Engine", "eMailSSL", false);
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.fromAddress = configIni.ReadString("Engine", "eMailFrom", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.toAddresses = configIni.ReadString("Engine", "eMailTo", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.successEvent = configIni.ReadBoolean("Engine", "eMailSuccess", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.failedEvent = configIni.ReadBoolean("Engine", "eMailFailed", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.cancelledEvent = configIni.ReadBoolean("Engine", "eMailCancelled", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.startEvent = configIni.ReadBoolean("Engine", "eMailStart", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.downloadFailedEvent = configIni.ReadBoolean("Engine", "eMailDownloadFailed", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.queueEvent = configIni.ReadBoolean("Engine", "eMailQueue", true);
     mceBuddyConfSettings.generalOptions.eMailSettings.successSubject = configIni.ReadString("Engine", "eMailSuccessSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.failedSubject = configIni.ReadString("Engine", "eMailFailedSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.cancelledSubject = configIni.ReadString("Engine", "eMailCancelledSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.startSubject = configIni.ReadString("Engine", "eMailStartSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.downloadFailedSubject = configIni.ReadString("Engine", "eMailDownloadFailedSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.queueSubject = configIni.ReadString("Engine", "eMailQueueSubject", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.skipBody = configIni.ReadBoolean("Engine", "eMailSkipBody", false);
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.userName = configIni.ReadString("Engine", "eMailUsername", "");
     mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.password = configIni.ReadString("Engine", "eMailPassword", "");
     if (!String.IsNullOrEmpty(mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.password))
         mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.password = Util.Crypto.Decrypt(mceBuddyConfSettings.generalOptions.eMailSettings.eMailBasicSettings.password); // password is stored encrypted
 }
Esempio n. 14
0
        /// <summary>
        /// Check if removing commercials for the specified extension is supported
        /// </summary>
        /// <param name="extension">Extension to check</param>
        /// <param name="profile">Profile for which supported extensions for commercial removal is to be checked. If this is blank or null, then only natively supported extensions are checked and not those covered by generic commercial removal functions.</param>
        /// <returns>True if commercial stripping is support for the extension</returns>
        public static bool IsSupportedExtension(string extension, string profile="")
        {
            switch (extension)
            {
                case ".ts":
                case ".wmv":
                case ".mpg":
                case ".avi":
                case ".m4v":
                case ".mp4":
                case ".mkv":
                    return true;

                default:
                    if (string.IsNullOrWhiteSpace(profile)) // unknown profile
                        return false; // Just the native supported extensions

                    // If we are using the universal commercial remover, than yes ALL extensions are supported else, we use only native extensions
                    Ini configProfileIni = new Ini(GlobalDefs.ProfileFile);
                    bool universalCommercialRemover = configProfileIni.ReadBoolean(profile, "UniversalCommercialRemover", false); // Forcing the use of CutFFMPEG which works on all video types
                    if (universalCommercialRemover)
                        return true;
                    else
                        return false;
            }
        }
Esempio n. 15
0
        private void StatusForm_Load(object sender, EventArgs e)
        {
            // Check for changes in screen resolution and screen changes (multi monitor support) - this HAS to be in Load and NOT in the constructor since the form has not been initiatized yet
            this.MaximumSize = Screen.FromControl(this).WorkingArea.Size; // Set the maximum size for the form based on working areas so we don't end up with dead/inaccessible locations

            // Set the version properties (Versioning is driven as Major.Minor.Build.Revision)
            MajorTitle.Text = "MCEBuddy " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Major.ToString(System.Globalization.CultureInfo.InvariantCulture) + "." + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString(System.Globalization.CultureInfo.InvariantCulture);
            if (System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision == 0) // BETA versions have revision code (Major.Minor.Build.Revision) as 0
                BetaTitle.Text = "Beta " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build.ToString(System.Globalization.CultureInfo.InvariantCulture);
            else
                BetaTitle.Text = "Release " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build.ToString(System.Globalization.CultureInfo.InvariantCulture);

            Ini tempIni = new Ini(GlobalDefs.TempSettingsFile);
            // Check if this is the first time the GUI is start after an installation
            if (tempIni.ReadBoolean("GUI", "FirstStartComplete", false) == false)
            {
                MessageBox.Show(Localise.GetPhrase("Rest your mouse on any button, box or item to get Instant Help on it.\n\nFor more information on how to use, troubleshoot or get support for MCEBuddy click on the <Getting Started> link on the top right corner.\n\nDonations are always welcome :) Enjoy!\n\n  - Ramit, Derek & Goose"), Localise.GetPhrase("Welcome to MCEBuddy"));
                tempIni.Write("GUI", "FirstStartComplete", true);
            }

            // Check for server location and start the thread to keep the UI connected to the MCEBuddy engine
            string remoteServerName = tempIni.ReadString("Engine", "RemoteServerName", GlobalDefs.MCEBUDDY_SERVER_NAME);
            if (remoteServerName != GlobalDefs.MCEBUDDY_SERVER_NAME) // check if it's a remote machine
                _connectPeriod = GlobalDefs.REMOTE_ENGINE_POLL_PERIOD; // remote machine needs be pinged slower

            // If this thread is not the thread that created the control, we'll invoke a callback in a threadsafe way to fix the control
            _tryConnectThread = new Thread(TryConnect);
            _tryConnectThread.IsBackground = true; // Kill this thread if the process is closed
            _tryConnectThread.CurrentCulture = _tryConnectThread.CurrentUICulture = Localise.MCEBuddyCulture;
            _tryConnectThread.Start();

            // Start the announcement text scroll timer
            _announcementTextScrollTimer.Tick += new EventHandler(this.ScrollAnnouncementLabel);
            _announcementTextScrollTimer.Interval = 250;
            _announcementTextScrollTimer.Start();

            // Now start the core background job status thread
            backgroundUpdate.WorkerSupportsCancellation = true;
            backgroundUpdate.RunWorkerAsync();

            this.Show(); // Show the form
        }