예제 #1
0
 private void CallAddNewRecording(RecorderCallbackProxy callbackProxy, DateTime actualStartTimeUtc)
 {
     WriteLog("RecordingThread [{0}]: Calling AddNewRecording()", _recordingProgram.CreateProgramTitle());
     try
     {
         callbackProxy.AddNewRecording(_recordingProgram, actualStartTimeUtc, this.RecordingFileName).Wait();
     }
     catch (Exception ex)
     {
         WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
     }
 }
예제 #2
0
 private void CallStartRecordingFailed(RecorderCallbackProxy callbackProxy, string reason)
 {
     WriteLog("RecordingThread [{0}]: Calling StartRecordingFailed(Reason=\"{1}\")", _recordingProgram.CreateProgramTitle(), reason);
     try
     {
         callbackProxy.StartRecordingFailed(_channelAllocation, _recordingProgram, reason).Wait();
     }
     catch (Exception ex)
     {
         WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
     }
 }
예제 #3
0
 protected override bool OnStopRecording(RecorderCallbackProxy proxy, bool abort)
 {
     if (_tve3User != null)
     {
         if (StopMediaPortalRecording(_tve3User))
         {
             _tve3User = null;
             return(true);
         }
     }
     return(false);
 }
예제 #4
0
        protected override bool OnPrepareRecording(RecorderCallbackProxy proxy, ref string errorMessage)
        {
            DeleteAllMediaPortalSchedules();

            string userName = String.Format(CultureInfo.InvariantCulture, "ArgusTV{0}", Thread.CurrentThread.ManagedThreadId);

            _tve3User            = new User(userName, true, _recordOnCard.IdCard);
            _tve3User.IdChannel  = _channel.IdChannel;
            _tve3User.SubChannel = -1;

            bool argusIsRecordingOnCard;

            return(EnsureCardFree(true, ref errorMessage, out argusIsRecordingOnCard));
        }
예제 #5
0
        private void CallEndRecording(RecorderCallbackProxy callbackProxy, DateTime actualStartTimeUtc, DateTime actualStopTimeUtc)
        {
            bool isPartial = (actualStartTimeUtc > _recordingProgram.StartTimeUtc.AddSeconds(30)) ||
                             (actualStopTimeUtc < _recordingProgram.StopTimeUtc.AddSeconds(-30));

            WriteLog("RecordingThread [{0}]: Calling EndRecording(IsPartial={1})", _recordingProgram.CreateProgramTitle(), isPartial);
            try
            {
                callbackProxy.EndRecording(this.RecordingFileName, actualStopTimeUtc, isPartial, !_usedSuggestedBaseFileName).Wait();
            }
            catch (Exception ex)
            {
                WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
            }
        }
예제 #6
0
 private void CallStartRecordingFailed(RecorderCallbackProxy callbackProxy, string reason)
 {
     WriteLog("RecordingThread [{0}]: Calling StartRecordingFailed(Reason=\"{1}\")", _recordingProgram.CreateProgramTitle(), reason);
     try
     {
         callbackProxy.StartRecordingFailed(_channelAllocation, _recordingProgram, reason).Wait();
     }
     catch (Exception ex)
     {
         WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
     }
 }
예제 #7
0
 abstract protected bool OnPrepareRecording(RecorderCallbackProxy callbackProxy, ref string errorMessage);
예제 #8
0
        protected override string OnStartRecording(RecorderCallbackProxy proxy, ref string errorMessage)
        {
            string baseFileName = _suggestedBaseFileName;

            if (String.IsNullOrEmpty(baseFileName))
            {
                baseFileName = FileUtility.BuildRecordingBaseFileName(null, this.RecordingProgram);
            }
            else
            {
                this.UsedSuggestedBaseFileName = true;
            }

            string fileName  = Path.Combine(_recordOnCard.RecordingFolder, baseFileName);
            string extension = (_recordOnCard.RecordingFormat == 0) ? ".ts" : ".mpg";

            _tve3RecordingFileName = FileUtility.GetFreeFileName(fileName, extension);
            string tve3RecordingDirectory = Path.GetDirectoryName(_tve3RecordingFileName);

            if (!Directory.Exists(tve3RecordingDirectory))
            {
                Directory.CreateDirectory(tve3RecordingDirectory);
            }

            string uncRecordingFolder = Common.ShareExplorer.GetUncPathForLocalPath(tve3RecordingDirectory);

            if (String.IsNullOrEmpty(uncRecordingFolder))
            {
                errorMessage = "Failed to convert '" + Path.GetDirectoryName(_tve3RecordingFileName) + "' to UNC path, please add required share";
                return(null);
            }

            bool argusIsRecordingOnCard;

            if (!EnsureCardFree(false, ref errorMessage, out argusIsRecordingOnCard))
            {
                if (!WaitCardFree(argusIsRecordingOnCard, ref errorMessage))
                {
                    return(null);
                }
            }

            IChannel tuningChannel = Utility.FindTuningChannelOnCard(_channel, _recordOnCard.IdCard);

            if (tuningChannel == null)
            {
                errorMessage = "Failed to find tuning details for channel " + _channel.DisplayName;
                return(null);
            }

            // Make sure only one thread can tune and start a recording at the same time.
            lock (_startRecordingLock)
            {
                if (TvServerPlugin.TvController_Tune(ref _tve3User, tuningChannel, _channel.IdChannel) != TvResult.Succeeded)
                {
                    errorMessage = "Failed to tune to channel " + _channel.DisplayName;
                    return(null);
                }

                if (TvServerPlugin.TvController_StartRecording(ref _tve3User, ref _tve3RecordingFileName) != TvResult.Succeeded)
                {
                    errorMessage = "TV Server failed to start recording on channel " + _channel.DisplayName;
                    return(null);
                }
            }

            return(Path.Combine(uncRecordingFolder, Path.GetFileName(_tve3RecordingFileName)));
        }
예제 #9
0
 abstract protected bool OnStopRecording(RecorderCallbackProxy callbackProxy, bool abort);
예제 #10
0
        protected override void Run()
        {
            var callbackProxy = new RecorderCallbackProxy(_schedulerBaseUrl);

            try
            {
                SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_AWAYMODE_REQUIRED);

                if (this.StopTimeUtc <= DateTime.UtcNow || _startTimeUtc >= this.StopTimeUtc)
                {
                    CallStartRecordingFailed(callbackProxy, String.Format(CultureInfo.InvariantCulture,
                                                                          "Recording of {0} at {1} for {2} has invalid timing parameters.",
                                                                          _channelAllocation.ChannelName, _startTimeUtc.ToLocalTime().ToShortTimeString(), this.StopTimeUtc.Subtract(_startTimeUtc)));
                    return;
                }

                if (_waitForThreadToComplete != null)
                {
                    _waitForThreadToComplete.Join();
                }

                bool aborted = false;
                _usedSuggestedBaseFileName = !_okToRenameRecordedFiles;

                // First of all make sure the recorder is tuned to the correct channel.
                string errorMessage = null;
                if (!OnPrepareRecording(callbackProxy, ref errorMessage))
                {
                    CallStartRecordingFailed(callbackProxy, errorMessage);
                    OnError();
                    aborted = true;
                }

                DateTime actualStartTimeUtc = DateTime.MaxValue;

                if (!aborted)
                {
                    // Now wait for the actual start-time
                    try
                    {
                        TimeSpan delay = _startTimeUtc.AddSeconds(-1) - DateTime.UtcNow;
                        if (delay.TotalMilliseconds > 0)
                        {
                            aborted = this.StopThreadEvent.WaitOne((int)delay.TotalMilliseconds, false);
                        }
                        if (!aborted)
                        {
                            errorMessage           = null;
                            this.RecordingFileName = OnStartRecording(callbackProxy, ref errorMessage);
                            if (String.IsNullOrEmpty(this.RecordingFileName))
                            {
                                CallStartRecordingFailed(callbackProxy, errorMessage);
                                OnError();
                                aborted = true;
                            }
                            else
                            {
                                this.ActualRecordingFileName = ShareExplorer.TryConvertUncToLocal(this.RecordingFileName);
                                actualStartTimeUtc           = DateTime.UtcNow;
                                CallAddNewRecording(callbackProxy, actualStartTimeUtc);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        CallStartRecordingFailed(callbackProxy, e.Message);
                        OnError();
                        aborted = true;
                    }
                }

                if (!aborted)
                {
                    TimeSpan?checkerInterval = this.FileSizeCheckerInterval;
                    if (!checkerInterval.HasValue)
                    {
                        checkerInterval = TimeSpan.MaxValue;
                    }
                    _fileSizeChecker = new FileSizeChecker(this.ActualRecordingFileName, checkerInterval.Value);

                    while (!aborted && DateTime.UtcNow < this.StopTimeUtc)
                    {
                        TimeSpan interval  = this.CheckRecordingActiveInterval;
                        TimeSpan timeToEnd = this.StopTimeUtc.AddMilliseconds(1) - DateTime.UtcNow;
                        if (timeToEnd < interval)
                        {
                            interval = timeToEnd;
                        }

                        aborted = this.StopThreadEvent.WaitOne(interval, false);
                    }

                    if (aborted)
                    {
                        WriteLog(TraceEventType.Warning, "RecordingThread [{0}]: Aborted", _recordingProgram.CreateProgramTitle());
                    }

                    if (!OnStopRecording(callbackProxy, aborted))
                    {
                        WriteLog(TraceEventType.Error, "RecordingThread [{0}]: Failed to stop recording", _recordingProgram.CreateProgramTitle());
                        try
                        {
                            callbackProxy.LogMessage(this.RecorderId, LogSeverity.Error, "Failed to stop recording " + _recordingProgram.CreateProgramTitle());
                        }
                        catch { }
                    }

                    CallEndRecording(callbackProxy, actualStartTimeUtc, DateTime.UtcNow);
                }
            }
            catch (Exception ex)
            {
                WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
                try
                {
                    callbackProxy.LogMessage(this.RecorderId, LogSeverity.Error, "Exception: " + ex.Message);
                }
                catch { }
                OnError();
            }
            finally
            {
                SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
            }

            OnThreadEnding();
        }
예제 #11
0
 abstract protected bool OnPrepareRecording(RecorderCallbackProxy callbackProxy, ref string errorMessage);
예제 #12
0
 abstract protected string OnStartRecording(RecorderCallbackProxy callbackProxy, ref string errorMessage);
예제 #13
0
 private void CallEndRecording(RecorderCallbackProxy callbackProxy, DateTime actualStartTimeUtc, DateTime actualStopTimeUtc)
 {
     bool isPartial = (actualStartTimeUtc > _recordingProgram.StartTimeUtc.AddSeconds(30))
         || (actualStopTimeUtc < _recordingProgram.StopTimeUtc.AddSeconds(-30));
     WriteLog("RecordingThread [{0}]: Calling EndRecording(IsPartial={1})", _recordingProgram.CreateProgramTitle(), isPartial);
     try
     {
         callbackProxy.EndRecording(this.RecordingFileName, actualStopTimeUtc, isPartial, !_usedSuggestedBaseFileName).Wait();
     }
     catch (Exception ex)
     {
         WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
     }
 }
예제 #14
0
 abstract protected string OnStartRecording(RecorderCallbackProxy callbackProxy, ref string errorMessage);
예제 #15
0
 private void CallAddNewRecording(RecorderCallbackProxy callbackProxy, DateTime actualStartTimeUtc)
 {
     WriteLog("RecordingThread [{0}]: Calling AddNewRecording()", _recordingProgram.CreateProgramTitle());
     try
     {
         callbackProxy.AddNewRecording(_recordingProgram, actualStartTimeUtc, this.RecordingFileName).Wait();
     }
     catch (Exception ex)
     {
         WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
     }
 }
예제 #16
0
        protected override void Run()
        {
            var callbackProxy = new RecorderCallbackProxy(_schedulerBaseUrl);

            try
            {
                SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_AWAYMODE_REQUIRED);

                if (this.StopTimeUtc <= DateTime.UtcNow || _startTimeUtc >= this.StopTimeUtc)
                {
                    CallStartRecordingFailed(callbackProxy, String.Format(CultureInfo.InvariantCulture,
                        "Recording of {0} at {1} for {2} has invalid timing parameters.",
                        _channelAllocation.ChannelName, _startTimeUtc.ToLocalTime().ToShortTimeString(), this.StopTimeUtc.Subtract(_startTimeUtc)));
                    return;
                }

                if (_waitForThreadToComplete != null)
                {
                    _waitForThreadToComplete.Join();
                }

                bool aborted = false;
                _usedSuggestedBaseFileName = !_okToRenameRecordedFiles;

                // First of all make sure the recorder is tuned to the correct channel.
                string errorMessage = null;
                if (!OnPrepareRecording(callbackProxy, ref errorMessage))
                {
                    CallStartRecordingFailed(callbackProxy, errorMessage);
                    OnError();
                    aborted = true;
                }

                DateTime actualStartTimeUtc = DateTime.MaxValue;

                if (!aborted)
                {
                    // Now wait for the actual start-time
                    try
                    {
                        TimeSpan delay = _startTimeUtc.AddSeconds(-1) - DateTime.UtcNow;
                        if (delay.TotalMilliseconds > 0)
                        {
                            aborted = this.StopThreadEvent.WaitOne((int)delay.TotalMilliseconds, false);
                        }
                        if (!aborted)
                        {
                            errorMessage = null;
                            this.RecordingFileName = OnStartRecording(callbackProxy, ref errorMessage);
                            if (String.IsNullOrEmpty(this.RecordingFileName))
                            {
                                CallStartRecordingFailed(callbackProxy, errorMessage);
                                OnError();
                                aborted = true;
                            }
                            else
                            {
                                this.ActualRecordingFileName = ShareExplorer.TryConvertUncToLocal(this.RecordingFileName);
                                actualStartTimeUtc = DateTime.UtcNow;
                                CallAddNewRecording(callbackProxy, actualStartTimeUtc);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        CallStartRecordingFailed(callbackProxy, e.Message);
                        OnError();
                        aborted = true;
                    }
                }

                if (!aborted)
                {
                    TimeSpan? checkerInterval = this.FileSizeCheckerInterval;
                    if (!checkerInterval.HasValue)
                    {
                        checkerInterval = TimeSpan.MaxValue;
                    }
                    _fileSizeChecker = new FileSizeChecker(this.ActualRecordingFileName, checkerInterval.Value);

                    while (!aborted && DateTime.UtcNow < this.StopTimeUtc)
                    {
                        TimeSpan interval = this.CheckRecordingActiveInterval;
                        TimeSpan timeToEnd = this.StopTimeUtc.AddMilliseconds(1) - DateTime.UtcNow;
                        if (timeToEnd < interval)
                        {
                            interval = timeToEnd;
                        }

                        aborted = this.StopThreadEvent.WaitOne(interval, false);
                    }

                    if (aborted)
                    {
                        WriteLog(TraceEventType.Warning, "RecordingThread [{0}]: Aborted", _recordingProgram.CreateProgramTitle());
                    }

                    if (!OnStopRecording(callbackProxy, aborted))
                    {
                        WriteLog(TraceEventType.Error, "RecordingThread [{0}]: Failed to stop recording", _recordingProgram.CreateProgramTitle());
                        try
                        {
                            callbackProxy.LogMessage(this.RecorderId, LogSeverity.Error, "Failed to stop recording " + _recordingProgram.CreateProgramTitle());
                        }
                        catch { }
                    }

                    CallEndRecording(callbackProxy, actualStartTimeUtc, DateTime.UtcNow);
                }
            }
            catch (Exception ex)
            {
                WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
                try
                {
                    callbackProxy.LogMessage(this.RecorderId, LogSeverity.Error, "Exception: " + ex.Message);
                }
                catch { }
                OnError();
            }
            finally
            {
                SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
            }

            OnThreadEnding();
        }
예제 #17
0
 abstract protected bool OnStopRecording(RecorderCallbackProxy callbackProxy, bool abort);