I have experienced a lot of trouble with Bluetooth sound synchronization. Most of the time, this issue was especially evident while watching movies. Fortunately, the solution is within easy reach.

Manual solution

The solution is based on simple, self-explanatory Auto-switching Bluetooth profiles to re-initialize the PulseAudio shell script listed in the references section.

List available Bluetooth devices

$ pactl list cards short | awk '$2 ~ /^bluez_card/'
8       bluez_card.D0_8A_55_0B_0D_2C    module-bluez5-device.c

Inspect available profiles.

$ LANG=C pactl list cards | awk -v card="#8" -v ORS="\n" -v FS="\n" -v RS="" 'split($1,var," ")  var[1] ~ /Card/ && var[2] == card {print}'
Card #8
        Name: bluez_card.D0_8A_55_0B_0D_2C
        Driver: module-bluez5-device.c
        Owner Module: 32
        Properties:
                device.description = "Hesh 2 Wireless"
                device.string = "D0:8A:55:0B:0D:2C"
                device.api = "bluez"
                device.class = "sound"
                device.bus = "bluetooth"
                device.form_factor = "headset"
                bluez.path = "/org/bluez/hci0/dev_D0_8A_55_0B_0D_2C"
                bluez.class = "0x240404"
                bluez.alias = "Hesh 2 Wireless"
                device.icon_name = "audio-headset-bluetooth"
                device.intended_roles = "phone"
        Profiles:
                headset_head_unit: Jednostka główna słuchawek z mikrofonem (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
                a2dp_sink: Odtwarzanie o wysokiej dokładności (odpływ A2DP) (sinks: 1, sources: 0, priority: 10, available: yes)
                off: Wyłączone (sinks: 0, sources: 0, priority: 0, available: yes)
        Active Profile: a2dp_sink
        Ports:
                headset-output: Słuchawki z mikrofonem (priority: 0, latency offset: 0 usec)
                        Part of profile(s): headset_head_unit, a2dp_sink
                headset-input: Słuchawki z mikrofonem (priority: 0, latency offset: 0 usec)
                        Part of profile(s): headset_head_unit

Set profile to Headset Head Unit (HSP/HFP).

$ pactl set-card-profile 8 headset_head_unit

Set profile to Advanced Audio Distribution Profile (A2DP).

$ pactl set-card-profile 8 a2dp_sink

Automated solution

Use bt-sync-sound.sh shell script.

#!/bin/bash
# fix bluetooth sound synchronization
# Source: https://sleeplessbeastie.eu/2016/05/09/how-to-fix-bluetooth-sound-synchronization/
# References: http://askubuntu.com/questions/145935/get-rid-of-0-5s-latency-when-playing-audio-over-bluetooth-with-a2d

LANG=C

for card in $(pactl list cards short | awk '$2 ~ /^bluez_card/ { print $1 }'); do
  # Print device name
  echo -n "Found device: "
  pactl list cards  | awk -v card="#${card}" -v ORS="\n" -v FS="\n" -v RS=""  'split($1,var," ")  var[1] ~ /Card/ && var[2] == card { print }' | awk -v FS=" = " '/device.description/ { print $2}' | tr -d \"

  # Print profiles 
  pactl list cards | awk -v card="#${card}" -v ORS="\n" -v FS="\n" -v RS="" -e 'split($1,var," ")  var[1] ~ /Card/ && var[2] == card { print }'  | awk '/Profiles/,/Active/ {gsub(/^\t/,"",$0); print}'

  echo "Set profile: Headset Head Unit (HSP/HFP)" 
  pactl set-card-profile ${card} headset_head_unit

  echo "Set profile: Advanced Audio Distribution Profile (A2DP)"
  pactl set-card-profile ${card} a2dp_sink
done

Sample output.

$ sh bt-sync-sound.sh
Found device: Hesh 2 Wireless
Profiles:
        headset_head_unit: Jednostka główna słuchawek z mikrofonem (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
        a2dp_sink: Odtwarzanie o wysokiej dokładności (odpływ A2DP) (sinks: 1, sources: 0, priority: 10, available: yes)
        off: Wyłączone (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: a2dp_sink
Set profile: Headset Head Unit (HSP/HFP)
Set profile: Advanced Audio Distribution Profile (A2DP)

Execute this shell script manually or assign it to a custom keyboard shortcut.

Use pacmd list-cards and pacmd list-sinks commands to get more information (like ports, current latency, and volume).

References

Get rid of 0.5s latency when playing audio over Bluetooth with A2DP – Auto-switching Bluetooth profiles to re-initialize PulseAudio shell script