morevnaproject-org / papagayo-ng

Papagayo is a lip-syncing program designed to help you line up phonemes (mouth shapes) with the actual recorded sound of actors speaking. Papagayo makes it easy to lip sync animated characters by making the process very simple - just type in the words being spoken (or copy/paste them from the animation's script), then drag the words on top of the sound's waveform until they line up with the proper sounds.
233 stars 51 forks source link

Animation slow to respond #117

Open ItsMeBobO opened 2 years ago

ItsMeBobO commented 2 years ago

One processor on my i7 is pegged and it can not keep up. 50% of the phonemes do not animate. I see improvement with very short clips. The version I have is 1.6.4.0 which came from master branch. I am completely new to python and admit I may have something wrong in my setup.

steveway commented 1 year ago

I'm working on new improvements for the Playback. Using QMediaPlayer is not really a good solution since it stutters with some simple files. For example our lame.wav and scared.wav files from the Tutorial Files will stutter, but if I convert them to mp3 then they run fine. I created a minimal example which plays a file and even there it happens:

import sys
import time

from PySide6.QtCore import QUrl, QCoreApplication
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput
from PySide6.QtWidgets import QApplication

app = QApplication(sys.argv)

# create a QMediaPlayer instance
player = QMediaPlayer()

# set the URL of the audio file to play
# url = QUrl.fromLocalFile(r"E:\PyCharmProjects\papagayo_clean\Tutorial Files\lame.wav")
url = QUrl.fromLocalFile(r"E:\PyCharmProjects\papagayo_clean\Tutorial Files\scared.wav")
player.setSource(url)
audio_output = QAudioOutput()
player.setAudioOutput(audio_output)
while not player.mediaStatus() in [QMediaPlayer.MediaStatus.LoadedMedia, QMediaPlayer.MediaStatus.BufferedMedia,
                                   QMediaPlayer.MediaStatus.BufferingMedia]:
    print(player.mediaStatus())
    QCoreApplication.processEvents()
    time.sleep(0.1)
# play the audio file
print(player.mediaStatus())
print("Playing: {}".format(url.toString()))
player.play()
# connect to the stateChanged signal to exit the program when the audio has finished playing
player.playbackStateChanged.connect(lambda state:
                                    QApplication.quit() if state != QMediaPlayer.PlaybackState.PlayingState else None)

# start the application event loop
sys.exit(app.exec())

I have a guess that this might be caused by some audio information which QT guesses wrong, like the sample rate or bit depth maybe. We might be able to fix it on our side. But this is possibly a bug in QMediaPlayer.

steveway commented 1 year ago

For now I sent a bug report to QT about this. Ideally this code should automatically work regardless of the audio file, so they should try to fix this in QT. https://bugreports.qt.io/browse/QTBUG-113211

steveway commented 1 year ago

I need to experiment more, but it might be possible to play back the decoded raw data from QAudioDecoder via QAudioSink, that seems to play the audio without this problem. I'll have to investigate this more but this might be a workaround until they fix QMediaPlayer.

steveway commented 11 months ago

From my tests this bug seems to be fixed in QT now. I released a new version, 1.7.0.0, on my fork, make sure that your libraries are up to date. You can also get an updated installer from my Gumroad: https://steveway.gumroad.com/l/papagayo