在Matlab中根据视频帧速率划分.wav文件



我有一个yuv视频(比如stream.yuv)和相应的音频文件(stream.wav)。现在我有了GUI,它可以逐帧渲染原始视频。我目前面临的问题是,我需要播放与每个视频帧相关的音频。

我已经尝试了以下操作,但当我执行此操作时,音频声音会打断

%% Dividing the audio into per-second samples
nframes = 720;
[audioFile, audioSampleFreq] = audioread('stream.wav');
numSamples = length(audioFile); 
audioLength = round(numSamples / audioSampleFreq);
for frame = 1:audioLength
    start = (frame-1)*audioSampleFreq+1;
    stop = frame*audioSampleFreq; 
    [start stop]
    audioFrame1 = audioFile(start:stop,:);
    sound(audioFrame1,audioSampleFreq);
end

为了将音频划分为每个视频帧的样本,

    audioFileName = 'stream.wav';
    nframes = 720;
    framerate = 25;
    [audioFile, audioSampleFreq] = audioread(audioFileName);
    audioFRate = round(audioSampleFreq/framerate);
    %% Total number of audio samples
    numSamples = length(audioFile); 
    %% number of audio frames
    numFrames = floor(numSamples/audioFRate);  
    for frame = 1:numFrames
        start = (frame-1)*audioFRate+1;
        stop = frame*audioFRate; 
        [start stop]
        audioFrame1 = audioFile(start:stop,:);
        sound(audioFrame1,audioSampleFreq);   
    end

关于如何同步YUV帧和每秒音频采样的每帧渲染,有什么想法吗?谢谢

我认为你处理这个问题的方法不对。将音频信号调整为视频信号通常是错误的,因为音频流中的小干扰非常明显,而普通观众不会注意到丢失的帧。相反,请将视频信号与音频信号同步。要快速启动,请设置一个音频播放器,并从以下代码开始:

videorate=25 %fps
audiorate=audio.SampleRate %sample rate
while audio.isplaying()
   displayFrame(ceil(audio.CurrentSample/audiorate*videorate))
end

还有很多可以改进的地方,但我认为这个简单的实现已经显示出比您当前尝试更好的结果。

需要改进的地方

  • 不要渲染同一帧两次
  • ceil只是一个快速而肮脏的近似。相反,您需要在时间f/fps-processing_delay为帧f调用displayFrame,其中processing_delay是调用displayFrame和实际出现在屏幕上的图像之间的时间。最初将其设置为1/25,如果音频和视频似乎不同步,则手动调整
  • 当错过了应该打电话给displayFrame的时间时,请做出决定。对于较小的时间静止显示帧,对于较大的间隙,放下帧并继续下一帧。也许暂停展示不早
  • 当您的视频信号真的出现问题时,例如在最后25帧中掉了15帧,请检查可能的原因。在处理高分辨率的原始视频时,通常会发生这种情况,因为你的硬盘驱动器会变慢,所以短时间暂停视频和音频应该会让缓冲区再次填满

这种方法的替代方案是使用可变播放速度的方法,稍微调整音频和视频播放速度以使两者同步。我认为这样的方法在Matlab中不会成功,因为你需要以非常低的延迟处理数据才能完成这种方法。

最新更新