/// <summary> /// Starts recording. /// </summary> /// <param name="user">User</param> /// <param name="fileName">Name of the recording file.</param> /// <returns></returns> public TvResult Start(ref IUser user, ref string fileName) { TvResult result = TvResult.UnknownError; try { #if DEBUG if (File.Exists(@"\failrec_" + _cardHandler.DataBaseCard.IdCard)) { throw new Exception("failed rec. on purpose"); } #endif if (IsTuneCancelled()) { result = TvResult.TuneCancelled; return(result); } _eventTimeshift.Reset(); if (_cardHandler.DataBaseCard.Enabled) { var context = _cardHandler.Card.Context as TvCardContext; if (context != null) { context.GetUser(ref user); ITvSubChannel subchannel = GetSubChannel(user.SubChannel); if (subchannel != null) { _subchannel = subchannel; fileName = fileName.Replace("\r\n", " "); fileName = Path.ChangeExtension(fileName, ".ts"); bool useErrorDetection = true; if (useErrorDetection) { // fix mantis 0002807: A/V detection for recordings is not working correctly // reset the events ONLY before attaching the observer, at a later position it can already miss the a/v callback. if (IsTuneCancelled()) { result = TvResult.TuneCancelled; return(result); } _eventVideo.Reset(); _eventAudio.Reset(); Log.Debug("Recorder.start add audioVideoEventHandler"); AttachAudioVideoEventHandler(subchannel); } Log.Write("card: StartRecording {0} {1}", _cardHandler.DataBaseCard.IdCard, fileName); bool recStarted = subchannel.StartRecording(fileName); if (recStarted) { fileName = subchannel.RecordingFileName; context.Owner = user; if (useErrorDetection) { bool isScrambled; if (WaitForFile(ref user, out isScrambled)) { result = TvResult.Succeeded; } else { DetachAudioVideoEventHandler(subchannel); result = GetFailedTvResult(isScrambled); } } } } } } else { result = TvResult.CardIsDisabled; } if (result == TvResult.Succeeded) { StartTimeShiftingEPGgrabber(user); } } catch (Exception ex) { Log.Write(ex); result = TvResult.UnknownError; } finally { _eventTimeshift.Set(); _cancelled = false; if (result != TvResult.Succeeded) { HandleFailedRecording(ref user, fileName); } } return(result); }
/// <summary> /// Starts recording. /// </summary> /// <param name="user">User</param> /// <param name="fileName">Name of the recording file.</param> /// <param name="contentRecording">if true then create a content recording else a reference recording</param> /// <param name="startTime">not used</param> /// <returns></returns> public TvResult Start(ref IUser user, ref string fileName, bool contentRecording, long startTime) { bool useErrorDetection = false; try { if (_cardHandler.DataBaseCard.Enabled == false) { return(TvResult.CardIsDisabled); } lock (this) { try { RemoteControl.HostName = _cardHandler.DataBaseCard.ReferencedServer().HostName; if (!RemoteControl.Instance.CardPresent(_cardHandler.DataBaseCard.IdCard)) { return(TvResult.CardIsDisabled); } if (_cardHandler.IsLocal == false) { return(RemoteControl.Instance.StartRecording(ref user, ref fileName, contentRecording, startTime)); } } catch (Exception) { Log.Error("card: unable to connect to slave controller at:{0}", _cardHandler.DataBaseCard.ReferencedServer().HostName); return(TvResult.UnknownError); } TvCardContext context = _cardHandler.Card.Context as TvCardContext; if (context == null) { return(TvResult.UnknownChannel); } context.GetUser(ref user); ITvSubChannel subchannel = _cardHandler.Card.GetSubChannel(user.SubChannel); if (subchannel == null) { return(TvResult.UnknownChannel); } _subchannel = subchannel; //gibman // RecordingFormat 0 = ts // RecordingFormat 1 = mpeg fileName = fileName.Replace("\r\n", " "); fileName = System.IO.Path.ChangeExtension(fileName, ".ts"); useErrorDetection = true; if (useErrorDetection) { // fix mantis 0002807: A/V detection for recordings is not working correctly // reset the events ONLY before attaching the observer, at a later position it can already miss the a/v callback. _eventVideo.Reset(); _eventAudio.Reset(); Log.Debug("Recorder.start add audioVideoEventHandler"); ((BaseSubChannel)subchannel).AudioVideoEvent += AudioVideoEventHandler; } Log.Write("card: StartRecording {0} {1}", _cardHandler.DataBaseCard.IdCard, fileName); bool result = subchannel.StartRecording(fileName); bool isScrambled; if (result) { fileName = subchannel.RecordingFileName; context.Owner = user; if (useErrorDetection) { if (!WaitForRecordingFile(ref user, out isScrambled)) { Log.Write("card: Recording failed! {0} {1}", _cardHandler.DataBaseCard.IdCard, fileName); string cardRecordingFolderName = _cardHandler.DataBaseCard.RecordingFolder; Stop(ref user); _cardHandler.Users.RemoveUser(user); string recordingfolderName = System.IO.Path.GetDirectoryName(fileName); if (recordingfolderName == cardRecordingFolderName) { Utils.FileDelete(fileName); } else { // delete 0-byte file in case of error Utils.DeleteFileAndEmptyDirectory(fileName); } ((BaseSubChannel)subchannel).AudioVideoEvent -= AudioVideoEventHandler; if (isScrambled) { return(TvResult.ChannelIsScrambled); } return(TvResult.NoVideoAudioDetected); } ((BaseSubChannel)subchannel).AudioVideoEvent -= AudioVideoEventHandler; } } if (_timeshiftingEpgGrabberEnabled) { Channel channel = Channel.Retrieve(user.IdChannel); if (channel.GrabEpg) { _cardHandler.Card.GrabEpg(); } else { Log.Info("TimeshiftingEPG: channel {0} is not configured for grabbing epg", channel.DisplayName); } } return(TvResult.Succeeded); } } catch (Exception ex) { Log.Write(ex); } return(TvResult.UnknownError); }