视频和aufio文件的实际持续时间

时间:2019-04-17 11:22:59

标签: c# audio video ffmpeg ffprobe

目前,我正在开发一个可以录制视频文件的应用程序。与视频文件并行记录音频文件。最终,有两个文件:.mp4.wav

我的目的是合并这两个文件。为此,文件应具有大致相同的持续时间。为了确定视频和音频文件的持续时间是否相等,我进行了一系列实验。我已经录制了视频:5次15分钟,5次30分钟,5次45分钟和5次60分钟。

在实验过程中,我捕获了以下值:

  1. 文件创建时间(精确到ms)。

    IDateTime videoCreated = _fileWrapper.GetCreationTime(videoPath);
    
    IDateTime audioCreated = _fileWrapper.GetCreationTime(audioPath);
    
  2. 文件的最后修改时间(精确到ms)。

    IDateTime videoModified = _fileWrapper.GetLastWriteTime(videoPath);
    
    IDateTime audioModified = _fileWrapper.GetLastWriteTime(audioPath);
    
  3. 我借助ffprobe测量了文件的持续时间。

  4. 我还计算了文件的长度,从上次更改的时间中减去了创建文件的时间。我们将此值称为计算的持续时间。

接下来,我将描述获得的结果。

如果考虑到计算的持续时间,则视频和音频文件大致相同。音频文件比视频文件短(平均为0.415 s,无关紧要)。

让我们通过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框架。

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();
        }

0 个答案:

没有答案