75

As described in the title I experience a half a second delay when playing audio over Bluetooth with A2DP.
This makes watching movies not possible as the sound is not synchronised with the video.

I'm not sure if the delay is caused by the Bluetooth standard, the A2PD protocol, the A2DP implementation on Ubuntu 12.04, or the Belkin Z73 Bluetooth Receiver.

Anyways, is this a normal lag? Is there a way to play audio over Bluetooth without any noticeable latency?

5
  • 9
    Not a real solution to your problem but a workaround: If it's only about playing movies, you can adjust the audio/video offset, which will delay the video too. Using mplayer, you do so by pressing the + and - keys. In VLC, I don't know how to set the delay, but I'd be surprised if VLC doesn't have such an option.
    – leemes
    Jun 3, 2012 at 14:29
  • 1
    I thought about that but I'm missing a solution for YouTube. When the video is played with HTML5 a solution could be to install a browser extension that sets a video offset. But for the case the video is played with flash I'm not sure how to achieve that.
    – brillout
    Jun 3, 2012 at 14:33
  • Incidentally, the VLC option is at Tools->Track Synchronisation, or play with the --audio-desync option. I'm afraid I'm not sure what the units are, and which direction is positive, and the help is not forthcoming on the matter, but that's where you want to look.
    – Darael
    Jul 31, 2012 at 19:32
  • Have you found a permanent solution to this problem? I am currently using the solution to switch between the A2DP / HSP / A2DP, but it's not practical to stay doing that every time the sync problem. Jul 18, 2016 at 22:54

13 Answers 13

43
+100

No, this is not normal but I've had a similar problem occasionally with my Altec Lansing iMT525 Bluetooth Speakers. Something similar in concept to Sri's answer almost always works for me, and I need to do it only once per connect.

Auto-switching Bluetooth profiles to re-initialize PulseAudio

If you're looking for a culprit, I'd look at Ubuntu's sound system, PulseAudio first, and then your Bluetooth receiver. Try this:

  • First, delete and re-pair your Bluetooth device.

  • Then, copy and paste the below into a .sh file in your home directory, say /home/brillout/pabluezswitch.sh:

    #!/bin/bash
    bluezcard=$(pactl list cards short | awk '/bluez/{print $2}')
    pactl set-card-profile "$bluezcard" a2dp
    pactl set-card-profile "$bluezcard" hsp
    pactl set-card-profile "$bluezcard" a2dp
    
  • Make the file executable by opening a terminal and typing chmod +x ~/pabluezswitch.sh

  • Go to Settings...Keyboard...Shortcuts, and create a custom shortcut; name it whatever you want, with the command as /home/$USER/pabluezswitch.sh (substitute with the appropriate path). Click Apply, and then click on the right where it says Disabled to set up a keyboard shortcut to execute the script.

What this does is force the PulseAudio system to resynchronize the audio being sent to your headset/speakers by switching profiles from ad2p -> hsp -> a2dp, thus hopefully getting rid of any latency.


Whenever you connect and notice the lag, you should press the keyboard shortcut chosen above to attempt to fix the latency -- hopefully it works for you!

14
  • 12
    Note that pactl has terrible error messages, and that many audio equipment don't have these ad2p and hsp. My Bose only has ad2p_sink, not these other two. Jun 12, 2016 at 10:10
  • 1
    I think you need quotes around that egrep pattern
    – naught101
    Aug 4, 2016 at 5:33
  • 1
    I don't suppose there's a way to monitor the latency and trigger this script automatically when it exceeds some threshold above reference? pacmd info | grep "current latency" and pacmd stat seem to give the same latency numbers/buffer size no matter how great the actual latency grows (e.g. when taking the headset out of range and bringing it back), so maybe a different part of the stack is responsible for the latency? Aug 10, 2016 at 4:00
  • 2
    @odinho-Velmont toggling between ad2p_sink and off works for me. I've recently aded this to my Pulse audio/volume control script that might be helpful to somebody
    – Sam Mason
    Mar 31, 2017 at 16:37
  • 2
    This seems outdated, not working on latest Linux Mint. pavucontrol is the better answer in late 2020/2021 Dec 26, 2020 at 22:21
39
  • Install pavucontrol: sudo apt install pavucontrol
  • Run pavucontrol from the menu
  • Go to Output Devices
  • Under the Bluetooth Device, open the Advanced menu
    • There you can set the latency offset to the value in millisecond (plus or minus). To make sure of the value you need to put start with any value e.g., 250.00 ms.
    • Play any "audio sync test" from YouTube and set the playback speed to 0.25 (make it slower) and from there you can start noticing if the value is correct or needs to be increased or decreased.
5
  • 7
    Removed unnecessary sass from answer - no need to be rude. Also, this sounds like it should work, but it doesn't seem to actually do anything for me...
    – naught101
    Aug 16, 2016 at 1:31
  • 1
    For me this worked for youtube playback with bluetooth speakers. Thanks. When I first opened pavucontrol the advanced option was hidden. Had to vertically expand the window.
    – Mark D
    Jan 15, 2018 at 23:20
  • 2
    This works really well. I believe this should now be the accepted answer, as there is no need to repeat operations every connect...
    – Francky_V
    May 11, 2020 at 21:07
  • Wow, searched for this since a long time, simple and efficient, should be the accepted answer Dec 26, 2020 at 22:20
  • I am running 22.04 and messed around with the delay. The positive values seemed to have an effect, but the negative values (even -2000 ms) had no noticable effect. I feel like the solution has to be a video delay. I see solutions with vlc, but I don't know if these can be implemented when streaming in, say, firefox. Jun 16, 2023 at 3:25
13

I tried a lot of approaches to this problem, but nothing could fix it. Then I stumbled upon set-port-latency-offset

If you are using pulseaudio do :

pactl list cards short | egrep -o bluez.*[[:space:]]

This will give you the bluetooth interface. Now set the latency accordingly :

pactl set-port-latency-offset <INTERFACE> speaker-output 100000

I am using 100000 microseconds which works fine for me.

2
  • 4
    For anyone else stumbling across this old post searching for an answer, Arindam Mani Das's answer works perfectly. If you receive the "no such entity" error, run 'pactl list cards' and check which ports are available for your device. I had to change "speaker-output" to "headset-output" in the second command since my device does not have a speaker-output port. May 22, 2018 at 0:46
  • Bluetooth from my point of view has no delay issues in 2020 (since 2016?), even when I pair JBL speakers and daisy chain them through JBL connect. But I got a pair of Nest Audio which can do Chromecast (terrible to set up and more delay at the moment) and Bluetooth. Running nest_audio="bluez_card.$id"; pactl set-port-latency-offset "${nest_audio}" unknown-output 1000000 compensates for delay of the 2 speakers in stereo mode syncing over Wifi while I use one of them as a bluetooth output at the moment. I've been fumbling with browser extensions and mpv till I remembered that PA could do it.
    – LiveWireBT
    Nov 8, 2020 at 10:41
13

The top reply here works, but not for every Bluetooth audio device. Some devices have different profile names than what that poster has with his Bluetooth speakers. For instance, in the following code, which was originally posted by that person, it apparently has profiles named a2dp and hsp. Neither of these are available with my LG Tones, for example, but they are with other devices like my Sony headset.

#!/bin/bash

BLUEZCARD=$(pactl list cards short | egrep -o bluez.*[[:space:]])
pactl set-card-profile $BLUEZCARD a2dp
pactl set-card-profile $BLUEZCARD hsp
pactl set-card-profile $BLUEZCARD a2dp

That code will work for most bluetooth devices it appears, but to get this working correctly for those devices that don't have the a2dp profile or the hsp profile, type in:

pactl list | grep -Pzo '.*bluez_card(.*\n)*'

This will return everything after where it finds a bluetooth device. For instance, with the LG Tone Ultra headset, I get this:

Name: bluez_card.B8_AD_3E_**_**_**
    Driver: module-bluez5-device.c
    Owner Module: 36
    Properties:
        device.description = "LG HBS810"
        device.string = "B8:AD:3E:**:**:**"
        device.api = "bluez"
        device.class = "sound"
        device.bus = "bluetooth"
        device.form_factor = "headset"
        bluez.path = "/org/bluez/hci0/dev_B8_AD_3E_**_**_**"
        bluez.class = "0x240404"
        bluez.alias = "LG HBS810"
        device.icon_name = "audio-headset-bluetooth"
        device.intended_roles = "phone"
    Profiles:
        a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
        headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
        off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
    Active Profile: a2dp_sink
    Ports:
        headset-output: Headset (priority: 0, latency offset: 0 usec)
            Part of profile(s): a2dp_sink, headset_head_unit
        headset-input: Headset (priority: 0, latency offset: 0 usec)
            Part of profile(s): headset_head_unit

We are interested in the profiles section. In this section, we see three profiles, which are a2dp_sink, headset_head_unit, and off. The two profiles we need should have in them (A2DP Sink) and (HSP/HFP). In this case, they are a2dp_sink for the a2dp profile, and headsethead_unit for the hsp profile. Notice this is different than the original poster's a2dp and hsp.

Now, with the above code, we will modify it and put it into a file. I called the file bluezswitch.sh.

Change to the directory you want to put the file. It can be anywhere.

touch bluezswitch.sh

Then

nano bluezswitch.sh

Copy and paste the code at the very top of this comment and replace the a2dp and hsp with the values you got when you ran the above command, and paste it in that file. For instance, this is what my file looked like for my LG Tones.

#!/bin/bash

BLUEZCARD=$(pactl list cards short | egrep -o bluez.*[[:space:]])
pactl set-card-profile $BLUEZCARD a2dp_sink
pactl set-card-profile $BLUEZCARD headset_head_unit
pactl set-card-profile $BLUEZCARD a2dp_sink

Now, ctrl-x then y to save the file and exit nano, and then make the file executable:

chmod +x bluezswitch.sh

Then follow up by setting a keyboard shortcut as has been explained.

Go to Settings...Keyboard...Shortcuts, and create a custom shortcut; name it whatever you want, with the command as /home/$USER/bluezswitch.sh (substitute appropriate username in path!). Click Apply, and then click on the right where it says Disabled to set up a keyboard shortcut to execute the script.

That should be all there is to it. This should work for all those that it didn't work for before.

1
  • 3
    For me, turning off a2dp_sink, off, a2dp_sink in sequence works very well for me. Setting to headset_head_unit I/O error. Apr 8, 2018 at 9:46
12

I get similar problem occasionally, irrespective of the player used. Mine is a Nokia BH-503 Bluetooth Stereo Headphone with MSI CR400 laptop and Ubuntu 11.10. I happened to come across a workaround which you can try.

  • Start the video playback.
  • Go to Sound Settings > Hardware.
  • Select the Bluetooth device.
  • Then in Settings for the Selected Device drop-down, switch to Telephony Duplex (HSP/HFP) profile, then switch back to High Fidelity Playback (A2DP).
7

Adaptive differential pulse code modulation involves a look-ahead type compressing algorithm where information cannot be transmitted before the encoder has had a chance to examine several bytes of forthcoming info. Hence, data has to stack up in the encoder, and there is an inherent time shift between the streams entering and leaving the encoder. Long ago, I did a study of data network delays to determine the feasibility of voice-over-data telephony (what is now VoIP). I think I concluded that ADPCM-style compression/encoding would introduce too much delay. I think to overcome this Bluetooth-delay problem, one might need a non-compressing type of audio encoding which should have lower latency.

2
  • 6
    The compression problem would account for a few tens of milliseconds, not half a second, surely?
    – naught101
    Aug 4, 2016 at 5:36
  • 1
    This answer is way into the weeds, imo, and may be true at a theorical level but not relevant practically.. One could easily just delay the video so it matches the audio sent via bluetooth to account for that. See @Roelf Renkema answer.
    – Francky_V
    May 11, 2020 at 21:09
1

Here's what solved it for me: $ sudo apt-get install phonon-backend-vlc and make sure it's the preferred backend, in KDE go to [System Settings][Multimedia][Audio and video settings][Backend] and use the [Prefer button]

1
  • 1
    @dargaud I recommend expanding this to explain how to make it the preferred backend. Jul 24, 2014 at 22:33
1

On VLC media player, Go to Tools Track synchronization Synchronize tab Under audio/ video audio track synchronize, use a negative value like about -0.67 and the lag will be compensated for fully. You have to manually do this every time you open a new file. Chris

1
  • That's cumbersome and just sad. +1 for the idea though
    – KiriSakow
    Feb 15, 2021 at 18:08
1

Similarly to Timm's answer, I did not have the profiles of the accepted answer either. Setting the HSP gave an error code.

I ended up using the following, almost identical, script.

#!/bin/bash
BLUEZCARD=`pactl list cards short | egrep -o bluez.*[[:space:]]`
pactl set-card-profile $BLUEZCARD a2dp_sink
pactl set-card-profile $BLUEZCARD off
pactl set-card-profile $BLUEZCARD a2dp_sink
1

Seem like this issue is still relevant after all those years.

Based on Arindam Mani Das's answer and Billy Farrington's comment I created the following shell script:

#!/bin/bash
export BLUEZCARD=`pactl list cards short | egrep -o bluez.*[[:space:]]`
pactl set-card-profile $BLUEZCARD a2dp_sink
pactl set-port-latency-offset $BLUEZCARD headphone-output 100000

I am using 100000 microseconds as Arindam recommended and it also works fine for me.

1
  • You are expecting one bluez device where there may be many. At the moment I have 3 which I use frequently with my computer and a few more for other devices. The setting is stored in PulseAudio so there is no need to complicate a simple command with error prone matching logic.
    – LiveWireBT
    Nov 8, 2020 at 10:28
0

individuals who are having this problem Please view this website: http://projectzeorymer.wordpress.com/2011/09/01/ubuntu-how-to-connect-nokia-bh-503-bluetooth-headset-to-your-pc/ to see a pic of what you need to download.

Download the bluetooth manager and use it to manipulate the settings of the headset. Set the sound settings to High Fidelity Playback (A2DP) and then go in sound settings.

1
  • 1
    Go on bluetooth manage and go to Audio Profile and then select High Fedelity Playback.. thats it
    – Alex Force
    Aug 18, 2012 at 22:25
0

Based on two other answers (1, 2), here's a version with some minor tweaks:

#!/usr/bin/env bash

set -o errexit -o noclobber -o nounset -o pipefail

bluez_card="$(pactl list cards short | grep --only-matching 'bluez_card[^[:space:]]*')"
pactl set-card-profile "$bluez_card" a2dp_sink
pactl set-card-profile "$bluez_card" headset_head_unit
pactl set-card-profile "$bluez_card" a2dp_sink

Changes from the other solutions:

Audio/video sync test

0

For me fallowing worked:

Install pavucontrol is you haven't already.

$ pavucontrol
  • go to Configuration tab
  • Look for your bluetooth device and play with Codec drop down menu.

for me switching from anything but LDAC(High Quality) works great. Good bye laggy sound :)

Using sony wh-1000xm3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .