Фактическая продолжительность видео и aufio файлов - PullRequest
0 голосов
/ 17 апреля 2019

В данный момент я работаю над приложением, которое позволяет записывать видеофайлы.Параллельно с видеофайлом записывается аудиофайл.В конце концов, есть два файла: .mp4 и .wav.

Моя цель - объединить эти два файла.Для этого файлы должны быть примерно одинаковой продолжительности.Чтобы определить, имеют ли видео и аудио файлы одинаковую продолжительность, я провел серию экспериментов.Я записал видео: 5 раз за 15 минут, 5 раз за 30 минут, 5 раз за 45 минут и 5 раз за 60 минут.

Во время экспериментов я зафиксировал следующие значения:

  1. Время создания файла (с точностью до мс).

    IDateTime videoCreated = _fileWrapper.GetCreationTime(videoPath);
    
    IDateTime audioCreated = _fileWrapper.GetCreationTime(audioPath);
    
  2. Время последнего изменения файла (с точностью до мс).

    IDateTime videoModified = _fileWrapper.GetLastWriteTime(videoPath);
    
    IDateTime audioModified = _fileWrapper.GetLastWriteTime(audioPath);
    
  3. Я измерил продолжительность файлов с помощью ffprobe.

  4. Я также рассчитал длину файлов, вычитая время создания файла из временипоследние изменения.Давайте назовем это значение расчетной продолжительностью.

Далее я опишу полученные результаты.

Если мы примем во внимание рассчитанную продолжительность, видео и аудиофайлы примерно одинаковые.Аудиофайлы немного короче, чем видеофайлы (в среднем 0,415 с, что незначительно).

Давайте перейдем к длительности с помощью ffprobe.Аудио файлы значительно длиннее видео файлов.Ниже приведена средняя разница между аудио- и видеофайлами по группам:

15 min -12,426 s;
30 min -16,942 s;
45 min -31,403 s;
60 min -34,702 s.

Результаты только для аудиофайлов:

Длительность ffprobe немного меньше, чем рассчитанная длительность.Ниже приведена средняя разница в разных группах:

15 min - 0,424 s;
30 min - 1,129 s;
45 min - 1,816 s;
60 min - 2,292 s.

Результаты только для видеофайлов:

Продолжительность по ffprobe значительно меньше, чем рассчитанная длительность.Результаты группы:

15 min -13,171 s;
30 min -18,630 s;
45 min -33,666 s;
15 min -37,326 s.

Почему длительность по ffprobe меньше вычисленной?Как объяснить все эти наблюдения?Какова фактическая продолжительность файлов?

Обновлено.форматы: видео - .mp4, аудио - .wav Пример команды ffprobe: ffprove exampleFileName -v info -hide_banner -show_entries stream = duration -of xml

Запись видео.Используется библиотека Vlc.DotNet.Core.

public void Execute(object parameter)
        {        
            if (_videoRecorder != null && _videoRecorder.IsPlaying())
            {
                _videoRecorder.Stop(); //!!!
                _videoRecorder = null;

                TimeSpan videoRecordingTime = TimeSpan.Zero; OnRecordingStopped?.Invoke(sessionService.CurrentDevice.Device.Id, videoRecordingTime);
                return;
            }
            _videoRecorder = new VlcMediaPlayer(_vlcLibDirectory.DirectoryInfo);

            _filenameGenerator.Folder = sessionService.PatientVideoDirectory;
            _filenameGenerator.GenerateNextFileName();
            string fileName = _filenameGenerator.GetName();

            string fileDestination = Path.Combine(_filenameGenerator.FolderPath, fileName);

            string[] mediaOptions =
            {
                ":sout=#file{dst='" + fileDestination + "'}",
//                ":live-caching=0",// TODO: check what that parameter does!
                ":sout-keep" /*Keep sout open (default disabled) : use the same sout instance across the various playlist items, if possible.*/
//                ":file-logging", ":vvv", ":extraintf=logger", ":logfile=VlcLogs.log"
            };

            _videoRecorder.SetMedia(sessionService.CurrentDevice.MediaStreamUri, mediaOptions); _videoRecorder.Play();

            OnRecordingStarted?.Invoke(fileName);
        }

Аудиозапись.Используется NAudio framework.

private void StartRecording()
        {
            try
            {
                string patientFolder = Patient.GetString();
                _waveFileDestination = string.Empty;

                if (IsForVideo)
                {
                    _waveFileDestination = Path.Combine(_systemSetting.VideoServerPath, patientFolder,
                        _videoFileNameGenerator.GetCurrentNameWithExtension("wav"));
                }
                else
                {
                    _audioFileNameGenerator.Folder = Path.Combine(_systemSetting.AudioPath, patientFolder);
                    _audioFileNameGenerator.GenerateNextFileName();
                    _waveFileDestination = Path.Combine(_audioFileNameGenerator.FolderPath,
                        _audioFileNameGenerator.GetName());
                }

                _waveSource = new WaveInEvent
                {
                    DeviceNumber = CapturingDevice.Number,
                    WaveFormat = new WaveFormat(44100, 1)
                };

                _waveSource.DataAvailable += WaveSourceOnDataAvailable;
                _waveSource.RecordingStopped += WaveSourceOnRecordingStopped;

                _waveFile = new WaveFileWriter(_waveFileDestination, _waveSource.WaveFormat);

                _waveSource.StartRecording();

                if (!IsForVideo)
                {
                    // Save audio media entity
                    _recordingMediaId = Media.AddToLocation(Patient.Id,
                        ExaminationId, _audioFileNameGenerator.GetName(),
                        MediaType.Audio, 0, _workstation.LocationId, DateTime.Now);
                    Media newMedia = Media.Get(_recordingMediaId);

                    MediaItem mediaItem = new MediaItem(newMedia, _systemSetting, _mediaManager)
                    {
                        PatientSsn = newMedia.AccessionNumber
                    };

                    OnAudioAdded(mediaItem);
                }

            }
            catch (Exception exception)
            {

            }
            finally
            {

            }
        }

private void StopRecording()
        {

            try
            {

                _waveSource.StopRecording();

                if (!IsForVideo)
                {
                    Media media = Media.Get(_recordingMediaId);    
                    media.Duration = Duration.Seconds;
                    Media.Update(media);
                    _recordingMediaId = 0;
                }
                else
                {
                    IsForVideo = false;
                }
            }
            catch (Exception exception)
            {
            }

            OnStateChanged();
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...