I’m using the QuickTimeMovieComponent for mp4 video playback. For reasons I won’t get into here, I have the audio for each video in a separate mp3 file, and am using AudioFormatReader/AudioTransportSource to playback the audio file. Most of the time it works perfect. But I’ve had a few users complain about “clicking” in the audio, and I’ve noticed occasional glitches in the audio when the video first starts playing back.
Currently, whenever the user hits play, it calls the QuickTimeMovieComponent’s play() method, and the AudioTransportSource’s start() method. I was worried about the two getting out of sync, so I have a background thread checking the video and audio file’s time every second. If they ever get off by more than 1/10 of a second, it corrects the video’s time to match the audio’s. I don’t think this is causing the audio glitch, because it doesn’t change the audio’s time, only the videos, so the audio should just be playing back smoothly. And I’ve never noticed the video get “corrected” so I think they’re playing back as expected. Two questions:
- Is there any reason why one file would get out of sync from the other? Or can I rely on them both being played back without a problem?
- Any obvious reason for the janky audio?
Video/Audio loading:
void VideoComponent::setupMovie(String vidPath, String demoAudioPath)
{
File curVid = vidPath;
movieStream = curVid.createInputStream();
videoPlayer->loadMovie (movieStream, false);
File audioFile = demoAudioPath;
if (audioFile.exists())
{
transportSource->stop();
transportSource->setSource (0);
currentAudioFileSource = 0;
AudioFormatManager formatManager;
formatManager.registerBasicFormats();
AudioFormatReader* reader = formatManager.createReaderFor (audioFile);
if (reader != 0)
{
currentAudioFileSource = new AudioFormatReaderSource (reader, true);
transportSource->setSource (currentAudioFileSource, 0, nullptr, reader->sampleRate);
}
}
}
Playback control:
if (videoPlayer->isPlaying())
{
videoPlayer->stop();
transportSource->stop();
}
else
{
videoPlayer->play();
transportSource->start();
}
Sync checker:
if (fabs(videoPlayer->getPosition() - transportSource->getCurrentPosition()) > 0.1)
videoPlayer->setPosition(transportSource->getCurrentPosition());