Beispiel #1
0
        public MainPresenter(IMainView view)
        {
            if (view == null) {
            throw new ArgumentNullException("view");
             }
             // Load configuration
             this.configuration = Configuration.Load();
             // Initialize recorder
             this.displayProvider = new DisplayProvider();
             this.displaySettings = new DisplaySettings() {
            Mouse = this.displayProvider.MouseSettings,
            Tracking = this.displayProvider.TrackingSettings,
            Watermark = this.displayProvider.WatermarkSettings,
             };
             this.soundProvider = new SoundProvider();
             this.soundSettings = new SoundSettings() {
            DeviceId = this.soundProvider.DeviceId,
            Format = this.soundProvider.Format,
             };
             this.recorder = new Recorder();
             this.recorder.Error += new RecordErrorEventHandler(recorder_Error);

             // Initialize view
             this.view = view;
             this.InitializeView();

             // Apply configuration
             this.ApplyConfiguration(null);

             // Update View
             this.view.AllowUpdate = true;
             // this.UpdateView();
        }
Beispiel #2
0
        private void RecordPrivate(DisplayProvider displayProvider, SoundProvider soundProvider)
        {
            bool recordDisplay = displayProvider != null;
             bool recordSound = soundProvider != null;
             AviFile aviFile = null;
             AcmEncoder audioEncoder = null;

             this.duration = TimeSpan.Zero;
             try {
            DisplayFormat videoFormat = null;
            SoundFormat audioFormat = null;

            int soundReadInterval = 0;
            if (recordDisplay) {
               displayProvider.Open();
               videoFormat = displayProvider.Format;
            }
            if (recordSound) {
               soundProvider.Open();
               soundReadInterval = (int)Math.Ceiling(soundProvider.BufferLength / 2.0); // ms
               audioFormat = soundProvider.Format;
               audioEncoder = soundProvider.GetEncoder();
            }
            // Open AVI file
            aviFile = new AviFile();
            aviFile.Open(fileName, videoFormat, fps, this.compressor, audioFormat, audioEncoder);

            // Initialize helper variables
            int frameIndex = 0;
            int frameDuration = recordDisplay ? (int)(msPerSecond / this.fps) : 0;
            int frameBufferLength = recordDisplay ? displayProvider.BitmapBytes : 0;
            int startingFrameIndex = 0;
            int soundSampleIndex = 0;
            long startTime = DateTime.Now.Ticks;
            long lastSoundRead = DateTime.Now.Ticks;
            TimeSpan prevDuration = TimeSpan.Zero;
            TimeSpan currentDuration = TimeSpan.Zero;

            // Update state
            lock (syncRoot) {
               this.state = RecordingState.Recording;
            }
            if (recordSound) {
               // Start sound recording
               soundProvider.Start();
            }
            // Recording loop; this is a long one huh?!
            do {
               // Check if paused
               if (this.state == RecordingState.Paused) {
                  prevDuration = prevDuration.Add(currentDuration);
                  if (recordSound) {
                     // Read remaining sound data and stop sound recording
                     byte[] soundData = soundProvider.Read(true);
                     soundSampleIndex += aviFile.AddSound(soundSampleIndex, soundData, true);
                     soundProvider.Stop();
                  }
                  // Let the thread executing Pause() know that pause is done
                  this.stateTransition.Set();
                  while (this.state == RecordingState.Paused) {
                     Thread.Sleep(pauseDelay);
                  }

                  // State is changed, check new state
                  if (this.state == RecordingState.Idle) {
                     return;
                  }

                  // Resume() is called
                  if (recordSound) {
                     soundProvider.Start();
                     lastSoundRead = DateTime.Now.Ticks;
                  }
                  if (recordDisplay) {
                     startingFrameIndex = frameIndex;
                  }

                  // Reset duration variables
                  startTime = DateTime.Now.Ticks;
                  currentDuration = TimeSpan.Zero;

                  // Let that executing thread known resume is done
                  this.stateTransition.Set();
               }

               // Add a video from
               if (recordDisplay) {
                  // Render display and add rendered bitmap to the avi file
                  displayProvider.Render();
                  IntPtr pFrameData = displayProvider.Lock();
                  try {
                     aviFile.AddFrame(pFrameData, frameIndex, 1, frameBufferLength);
                  }
                  finally {
                     displayProvider.Unlock();
                  }
                  frameIndex++;
               }

               // Add sound
               if (recordSound) {
                  // Read recorded sound if it's time to do so
                  if ((DateTime.Now.Ticks - lastSoundRead) / ticksPerMs >= soundReadInterval) {
                     // Read sound data
                     SoundFormat sourceFormat = soundProvider.SourceFormat;
                     byte[] soundData = soundProvider.Read();
                     int samplesRead = (int)(soundData.Length / sourceFormat.BlockAlign);

                     // Get number of out of sync samples
                     TimeSpan durationByNow = prevDuration + new TimeSpan(DateTime.Now.Ticks - startTime);
                     int nOutOfSyncSamples = GetOutOfSyncSamples(soundProvider, soundSampleIndex , durationByNow,
                                                                 samplesRead);
                     if (nOutOfSyncSamples > 0) {
                        // Add silence samples if we have less than expected samples
                        soundSampleIndex += aviFile.AddSilence(soundSampleIndex, nOutOfSyncSamples);
                     }
                     else if (nOutOfSyncSamples < 0) {
                        // Drop read samples as much as possible if we have more than expected samples
                        int nSamplesToKeep = Math.Max(0, samplesRead + nOutOfSyncSamples);
                        if (nSamplesToKeep > 0) {
                           int nBytesToKeep = nSamplesToKeep * sourceFormat.BlockAlign;
                           int nBytesToDrop = soundData.Length - nBytesToKeep;
                           byte[] droppedSoundData = new byte[nBytesToKeep];
                           Array.Copy(soundData, nBytesToDrop, droppedSoundData, 0, nBytesToKeep);
                           soundData = droppedSoundData;
                        }
                        samplesRead = nSamplesToKeep;
                     }
                     // Add sound data to the avi file
                     if (samplesRead > 0) {
                        soundSampleIndex += aviFile.AddSound(soundSampleIndex, soundData, false);
                     }
                     lastSoundRead = DateTime.Now.Ticks;
                  }
               }

               // Synchronize display
               if (recordDisplay) {
                  long delay = (DateTime.Now.Ticks - startTime) / ticksPerMs -
                                frameDuration * ((frameIndex - startingFrameIndex) - 1);
                  if (delay < frameDuration) {
                     // Extra delay to synchornize with fps
                     Thread.Sleep((int)(frameDuration - delay));
                  }
                  else {
                     // Calculate how many frames are lost
                     int lostFrames = (int)Math.Floor((decimal)delay / frameDuration);
                     frameIndex += lostFrames;
                     // Extra delay to synchornize with fps
                     Thread.Sleep((int)(frameDuration - delay % frameDuration));
                  }
               }
               else { /* No display recording, just sleep for a while so that sound buffers get filled  */
                  Thread.Sleep(1);
               }

               // Update duration
               currentDuration = new TimeSpan(DateTime.Now.Ticks - startTime);
               this.duration = prevDuration + currentDuration;

            } while (this.state != RecordingState.Idle);

            // Read remaining sound data and stop sound recording
            if (recordSound) {
               byte[] soundData = soundProvider.Read(true);
               soundSampleIndex += aviFile.AddSound(soundSampleIndex, soundData, true);
               soundProvider.Stop();
            }
             }
             finally {
            if (recordSound) {
               soundProvider.Close();
               if (audioEncoder != null) {
                  audioEncoder.Dispose();
               }
            }
            if (recordDisplay) {
               displayProvider.Close();
            }
            if (aviFile != null) {
               aviFile.Dispose();
            }
             }
        }
Beispiel #3
0
 public void Record(DisplayProvider displayProvider, SoundProvider soundProvider)
 {
     if (this.fileName == null) {
     throw new InvalidOperationException("FileName is not specified");
      }
      // Check state
      lock (syncRoot) {
     if (state != RecordingState.Idle) {
        throw new InvalidOperationException("Invalid state.");
     }
     state = RecordingState.Preparing;
      }
      record = new RecordDelegate(this.RecordPrivate);
      AsyncCallback callback = new AsyncCallback(this.RecordCallBack);
      record.BeginInvoke(displayProvider, soundProvider, callback, null); // Start a new thread for recording
 }