Skip to content

improve audio/video synchronization #29

@dasl-

Description

@dasl-

look into ways to start ffplay as paused so we can send it a signal to unpause once we start receiving data. Or use another audio player command that supports starting paused. Sync is already pretty good though, so not sure if this needs to be a priority?

Option 1: ffplay:

use SIGSTOP and SIGCONT to pause/unpause ffplay

The pipeline is something like this:

yt-dlp | ffplay

We have to immediately pause ffplay via something like kill -SIGSTOP $(pidof ffplay). Then start it when we're ready via something like: kill -SIGCONT $(pidof ffplay). This is a bit hacky because what if there's another ffplay proc running at the same time. Apparently getting the pid of an arbitrary process in a pipeline is not straightforward...

Also: consider that if we are playing a local file, playback may start immediately. I.e. in a pipeline like:

cat video.mp4 | ffplay

Thus we might not have time to send SIGSTOP before playback starts. So we may want to consider something like:

cat video.mp4 | { sleep 1 ; cat - } | ffplay

That will give us one second to send SIGSTOP to ffplay before playback starts.

Option 2: vlc:

dependencies:

sudo apt install vlc dbus-x11

First, call dbus-launch to get a DBUS session address:

% dbus-launch
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-02KOCyLr9y,guid=8aad4bde669062820dbc382e62a119c4
DBUS_SESSION_BUS_PID=2605

Note that calling dbus-launch multiple times launches a long lived process for each time. E.g. calling it 9 times, you'll see something like this: https://gist.github.com/dasl-/6dbd9a7f4517c4d4806333a2159d7fb4

Thus, we can do something similar to what omxplayer does and only start a new dbus session if one doesn't already exist. We write the dbus address to a tmp file and check for the file's existence to conditionally start a dbus session: https://github.com/popcornmix/omxplayer/blob/1f1d0ccd65d3a1caa86dc79d2863a8f067c8e3f8/omxplayer#L46-L59

Also, it looks like dbus-launch is basically a wrapper around the dbus-daemon that omxplayer is using, so maybe we could cut out the dbus-x11 dependency by doing that (dbus-x11 is what provides the dbus-launch command).

Here's what a dbus-daemon invocation would look like:

% dbus-daemon --fork --print-address= --print-pid= --session
unix:abstract=/tmp/dbus-No3e8ssDtr,guid=ae3dd10615db0c98f1da3ff662a11eb2
3400

Use the DBUS_SESSION_BUS_ADDRESS in the following commands. The pipeline becomes something like:

yt-dlp | DBUS_SESSION_BUS_ADDRESS=... cvlc --play-and-exit --no-video --control dbus --start-paused -

Note we make use of the --start-paused option, so we don't need to worry about pausing the video explicitly unlike with ffplay.

We start vlc when we're ready via:

DBUS_SESSION_BUS_ADDRESS=... dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions