Trouble synchronising script start with the start of a video playback
Posted: 09 Jul 2024 04:19
I am trying to synchronise LEDs flashing with a video being played using a Raspberry Pi 3B+ and the Python wrappers for libVLC. For example, I want the LED to flash red at exactly 2000ms of video playback and green at 5500ms etc.
I can get the timings in-between the LED flashes accurate enough in Python (to within a few ms) but I cannot seem to synchronise the start of the video playback with the start of the timing for the LEDs. I have already tried a few things
1) Initialise the video player, load the media, sleep in the script a few seconds to let the player start and load the media. Call play() and immediately start the LED timings.
-- The playback is always delayed after play is called for 100+ms it seems causing the LEDs to trigger earlier than wanted
2) Query for State.Playing using player.get_state() in a while True loop and starting the LEDs immediately after detection
-- The state change seems to be delayed by 100+ms despite the getState being called in a busy loop, this causes the LED routine to start late
3) Adding a few seconds of black screen to the start of the video, calling player.get_time() after a second or so and sleeping for the duration until the 'start' of the real part of the video
get_time() doesn't seem to give accurate timings, it appears to only update itself every 300ms or so giving it a large window where it is off the actual video progress.
Are there any alternatives I should be considering here? Any way to get more accurate timing for when to start the LED routine? I preferably want the delay to be less than 30ms so that the difference is mostly imperceptible to the eye..
For reference here is some code I have been trying so far:
[1]
[2]
[3]
I can get the timings in-between the LED flashes accurate enough in Python (to within a few ms) but I cannot seem to synchronise the start of the video playback with the start of the timing for the LEDs. I have already tried a few things
1) Initialise the video player, load the media, sleep in the script a few seconds to let the player start and load the media. Call play() and immediately start the LED timings.
-- The playback is always delayed after play is called for 100+ms it seems causing the LEDs to trigger earlier than wanted
2) Query for State.Playing using player.get_state() in a while True loop and starting the LEDs immediately after detection
-- The state change seems to be delayed by 100+ms despite the getState being called in a busy loop, this causes the LED routine to start late
3) Adding a few seconds of black screen to the start of the video, calling player.get_time() after a second or so and sleeping for the duration until the 'start' of the real part of the video
get_time() doesn't seem to give accurate timings, it appears to only update itself every 300ms or so giving it a large window where it is off the actual video progress.
Are there any alternatives I should be considering here? Any way to get more accurate timing for when to start the LED routine? I preferably want the delay to be less than 30ms so that the difference is mostly imperceptible to the eye..
For reference here is some code I have been trying so far:
[1]
Code: Select all
player = vlc.MediaPlayer()
player.toggle_fullscreen()
media = vlc.Media('/home/pi/Downloads/test.mp4')
player.set_media(media)
sleep(5)
player.play()
startLedRoutine()
Code: Select all
player = vlc.MediaPlayer()
player.toggle_fullscreen()
media = vlc.Media('/home/pi/Downloads/test.mp4')
player.set_media(media)
sleep(5)
player.play()
while True:
if player.get_state() == vlc.State.Playing:
break
startLedRoutine()
Code: Select all
player = vlc.MediaPlayer()
player.toggle_fullscreen()
media = vlc.Media('/home/pi/Downloads/test.mp4')
player.set_media(media)
sleep(5)
player.play()
sleep(5) # 10 seconds of black screen has been added to the start of the video
sleep(10 - player.get_time() * 1000) # sleep for the remainder of the time before 10s is reached
startLedRoutine()