gmdfalk/blockify

Blockify kills sound in Chromium

der-daniel opened this issue · 34 comments

Hello,

somehow Blockify kills my sound in Chromium.
I got my sound back by somewhat using this answer: http://askubuntu.com/questions/677056/ubuntu-15-04-google-chrome-45-0-2454-93-no-sound.

How is sound, blockify and Chromium related?

They can all carry music. Is that the right answer?

If you want help you'll need to provide more information, see the troubleshooting section of the README.
What's the content of your blocklist?

I have the same problem. Blockify works great but since installing I have no sound in chromium (youtube etc). I haven't had the same problem in the past. Whether that's because I was using a previous version of blockify, or chromium, or something else, I don't know...

System:

blockify 3.3.1
chromium 48.0.2564.116
Ubuntu 15.10

contents of ~/.config/blockify/blocklist.txt

empty

list of sinks:

date: 2016-03-20T14:16:26.629411+00:00
digest: 98166168b6dfd8b0c83038239b88287063959f73
long: AJgWYWi239iwyDA4I5uIKHBjlZ9z
short: lZ9z
size: 2154
status: created
url: https://ptpb.pw/lZ9z
uuid: 93380729-3927-4a85-b28f-bd3d99312a46

debug log (some repetitive lines removed):

2016-03-20 15:00:03 DEBUG    util     Added logging file handler: /home/ry/logfile.
2016-03-20 15:00:03 INFO     util     Loading configuration.
2016-03-20 15:00:03 INFO     util     Configuration file loaded from /home/ry/.config/blockify/blockify.ini.
2016-03-20 15:00:03 INFO     list     Blocklist loaded from /home/ry/.config/blockify/blocklist.txt.
2016-03-20 15:00:03 INFO     player   InterludePlayer initialized.
2016-03-20 15:00:03 ERROR    player   Could not parse playlist source: [Errno 2] No such file or directory: '/home/ry/.config/blockify/playlist.m3u'
2016-03-20 15:00:03 DEBUG    player   Loading playlist.
2016-03-20 15:00:03 DEBUG    player   Stop: State is (<enum GST_STATE_CHANGE_SUCCESS of type GstStateChangeReturn>, <enum GST_STATE_NULL of type GstState>, <enum GST_STATE_VOID_PENDING of type GstState>).
2016-03-20 15:00:03 INFO     player   Playlist loaded (Length: 0).
2016-03-20 15:00:03 INFO     player   Playlist: []
2016-03-20 15:00:03 DEBUG    cli      Mute method is pulse sink.
2016-03-20 15:00:03 INFO     cli      Blockify initialized.
2016-03-20 15:00:03 INFO     cli      Blockify started.
2016-03-20 15:00:03 WARNING  dbus     Cannot get song artist: list index out of range
2016-03-20 15:00:03 WARNING  dbus     Cannot get song artist: list index out of range
2016-03-20 15:00:04 WARNING  dbus     Cannot get song artist: list index out of range
2016-03-20 15:00:04 WARNING  dbus     Cannot get song artist: list index out of range
2016-03-20 15:00:04 WARNING  dbus     Cannot get song artist: list index out of range
2016-03-20 15:00:11 DEBUG    cli      2 received. Exiting safely.
2016-03-20 15:00:11 INFO     cli      Exiting safely. Bye.
2016-03-20 15:00:11 WARNING  dbus     Cannot get song artist: list index out of range

Thanks for the detailed report. I cannot reproduce it though.
What is the output of blockify-dbus get all?

output of blockify-dbus get all

artUrl      = 
length      = 0
trackid = 
album       = 
albumArtist = dbus.Array([], signature=dbus.Signature('s'), variant_level=1)
Traceback (most recent call last):
  File "/usr/local/bin/blockify-dbus", line 9, in <module>
    load_entry_point('blockify==3.3.1', 'console_scripts', 'blockify-dbus')()
  File "/usr/local/lib/python3.4/dist-packages/blockify/dbusclient.py", line 269, in main
    dbus.print_info()
  File "/usr/local/lib/python3.4/dist-packages/blockify/dbusclient.py", line 223, in print_info
    print("{0}\t\t= {1}".format(d, metadata[k][0]))
IndexError: list index out of range

Might also be important that I have ad blockers running in chromium. The apps I have installed in chromium are as follows:

  • AdBlock 2.53
  • Adblock for Youtub 4.1.0
  • Any.do 3.1.1
  • Dewey Bookmarks 4.0.0
  • Google Docs Offline 1.4
  • WebRTC Block 2.0.1
  • Wunderlist for Chrome 3.19.1
  • Zotero Connector 4.0.29.1

Hi,

I though this may be a common problem..
On my machine, the output of $ blockify-dbus get all is:

2016-03-21 23:19:53 ERROR    dbus     Failed to get DBus property: org.freedesktop.DBus.Error.UnknownMethod: Method "Get" with signature "ss" on interface "org.freedesktop.DBus.Properties" doesn't exist

2016-03-21 23:19:53 ERROR    dbus     Could not get properties: 'NoneType' object has no attribute 'keys'

Isn't Spotify just a chromium fork? Does this mess up the sound bus system?

So, I've set up to virtual machine to test this.
I believe what you are experiencing is what happens when dbus/pulse isn't initialized when blockify is started.
Try starting spotify and playing a song before starting blockify.
If you can confirm, i might be inclined to fix it.

I just tried your proposal and YouTube is able to play sound. This may be the cause. :)

What might work is just letting blockify automatically start Spotify. You can enable that behaviour by changing start_spotify = False to start_spotify = True in ~/.config/blockify/blockify.ini.

Please install the new version of blockify (3.4.0), delete the old configuration and try again!
git clone https://github.com/mikar/blockify && cd blockify && sudo pip3 install . && rm ~/.config/blockify/blockify.ini && blockify-ui

thanks for your suggestions, I tried playing a song in spotify before starting blockify. I also tried installing the new version of blockify and updating chromium, but I still have no sound in chromium with these solutions...

Could you check if the problem occurs with a fresh Chromium profile?
https://support.google.com/chrome/answer/142059

Thanks for the suggestion, I just tried but there is still no sound in Chromium with a fresh profile.

I have tried and failed once more to reproduce this issue.

For comparison, here is my sink info when simultaneously playing music in chromium and spotify with blockify blocking the current song.
pacmd list-sink-inputs: https://ptpb.pw/QWzy
spotify --version; chromium-browser --version: https://ptpb.pw/fLot
blockify --version: 3.4.0

Current blockify version is 3.6.0. A couple of things changed between 3.4.0 and 3.6.0 that affect ad detection so feel free to try again.

This is caused by the stream restore module of pulseaudio. Some ads in spotify are started inside a chromium process which gives them the module-stream-restore.id "sink-input-by-application-name:Chromium". This ad is then muted. When the ad is over the process exits and pulseaudio stores the settings (including it being muted) somewhere. Afterwards when chromium starts it has the same restore.id property and pulseaudio loads the settings (including it being muted).

To fix this write a small wrapper around the chromium process as follows:

#!/bin/bash

export PULSE_PROP="module-stream-restore.id=real-chromium"
exec /usr/bin/chromium "$@"

I have the exact same error, but for me it's origin is here:

markus@markus-pc:~$ pacmd list-sink-inputs
3 sink input(s) available.
index: 377
driver: <protocol-native.c>
flags: DONT_MOVE START_CORKED FIX_RATE
state: RUNNING
sink: 4 <alsa_output.pci-0000_00_1b.0.analog-stereo>
volume: front-left: 46396 / 71% / -9,00 dB, front-right: 46396 / 71% / -9,00 dB
balance 0,00
muted: no
current latency: 57,51 ms
requested latency: 23,22 ms
sample spec: float32le 2ch 44100Hz
channel map: front-left,front-right
Stereo
resample method: copy
module: 10
client: 987498
properties:
media.role = hex:
phonon.streamid = hex:
media.name = "Playback Stream"
application.name = "java"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "30"
application.process.id = "1276"
application.process.user = "markus"
application.process.host = "markus-pc"
application.process.binary = "java"
application.language = "en_US.UTF-8"
window.x11.display = ":1"
application.process.machine_id = "6f8fc0b2d4d84361b1bb62117c1af741"
application.process.session_id = "c3"
module-stream-restore.id = "sink-input-by-application-name:java"
index: 422
driver: <protocol-native.c>
flags: START_CORKED
state: RUNNING
sink: 4 <alsa_output.pci-0000_00_1b.0.analog-stereo>
volume: front-left: 45421 / 69% / -9,55 dB, front-right: 45421 / 69% / -9,55 dB
balance 0,00
muted: no
current latency: 899,82 ms
requested latency: 980,00 ms
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
resample method: (null)
module: 10
client: 1084466
properties:
media.role = "music"
media.name = "Spotify"
application.name = "Spotify"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "30"
application.process.id = "23553"
application.process.user = "markus"
application.process.host = "markus-pc"
application.process.binary = "spotify"
window.x11.display = ":1"
application.language = "en_US.UTF-8"
application.process.machine_id = "6f8fc0b2d4d84361b1bb62117c1af741"
application.process.session_id = "c3"
application.icon_name = "spotify-client"
module-stream-restore.id = "sink-input-by-media-role:music"
index: 423
driver: <protocol-native.c>
flags: START_CORKED
state: RUNNING
sink: 4 <alsa_output.pci-0000_00_1b.0.analog-stereo>
volume: front-left: 65536 / 100% / 0,00 dB, front-right: 65536 / 100% / 0,00 dB
balance 0,00
muted: no
current latency: 64,76 ms
requested latency: 23,22 ms
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
resample method: (null)
module: 10
client: 1084471
properties:
application.icon_name = "chromium-browser"
media.name = "Playback"
application.name = "Chromium"
native-protocol.peer = "UNIX socket client"
native-protocol.version = "30"
application.process.id = "23553"
application.process.user = "markus"
application.process.host = "markus-pc"
application.process.binary = "spotify"
window.x11.display = ":1"
application.language = "en_US.UTF-8"
application.process.machine_id = "6f8fc0b2d4d84361b1bb62117c1af741"
application.process.session_id = "c3"
module-stream-restore.id = "sink-input-by-application-name:Chromium"

Do you see the line in chromium where it says application.process.binary = "spotify"? This is simply wrong. This might be the chromium render engine spotify uses (wild guess...).
Making merge request with fix...

This is not wrong. Spotify uses an embedded chromium that creates its own connection to pulseaudio under the chromium name. Which does not change that the name of the binary is spotify.

Okay, blockify currently mutes this chromium renderer sink, which is incorrect

It's not because some ads are played over this sink-input.

It is, because it then does not unmute this sink, which is used system wide for all chromium instances

There is no such thing as a chromium sink. Such a thing does not exist in pulseaudio. What you are talking about are sink inputs and each audio stream is its own sink input.

I already explained the real reason for this phenomenon and the simple fix above.

Writing a wrapper around chromium is not a "fix" it is circumventing a Problem that needs to be fixed.

You're right. The correct solution is to instead write the same wrapper around spotify:

#!/bin/bash

export PULSE_PROP="module-stream-restore.id=spotify"
exec /usr/bin/spotify "$@"

This way other programs that embed chromium are also fixed.

I think, we should address this in this current piece of software, because it is a compatibility issue and we should not make the users do anything :)

And how do you propose this should be addressed?

I would like to do it in the following steps:

  1. verify the chromium stuff is actually playing ads.
    if no -> simple solution

if yes -> mute both sinks when spotify is playing an ad and afterwards unmuting them. This assumes that you are not listening to something in chromium and in spotify simultaneously.

if yes

It is easy to check that it does. Here:

2016-06-24-095317_1366x768_scrot

As you can see, an ad is playing (you cannot see the sound but I assure you it's there), and it's playing inside a chromium process as you can see on the right.

mute both sinks when spotify is playing a ad and afterwards unmuting them.

It is impossible from the MPRIS (dbus) data provided by spotify to tell when those embedded instances play ads because spotify does not update the data for those kinds of ads. This is also racy because spotify kills the stream immediately after the ad is over. Hence you might not get the chance to unmute it.

This assumes that you are not listening to something in chromium

As I already said multiple times: This has no effect on running music inside chromium. Only instances created after the muting has started will be affected. And those again might overwrite the muted state of the restore module.

This assumes that you are not listening to something in chromium

As I already said multiple times: This has no effect on running music inside chromium. >Only instances created after the muting has started will be affected. And those again >might overwrite the muted state of the restore module.

For me the sink stays and is muted. So there is a good chance for unmuteing :)
And starting chromium after that does reattach to the sink but keeps it muted.

You do not seem to understand how pulseaudio works and in particular how the stream-restore module works which is what causes this problem in the first place. For example you still seem to think that there is only one state (muted or unmuted) for all chromium streams. But this is incorrect as you can already see from the screenshot I posted above which shows two chromium streams, one muted and one unmuted. You're also talking about sinks in a context in which this makes no sense. What you mean are streams or sink-inputs.

I'm sorry to be so direct but please read up on the internals of pulseaudio.

I mean sink-inputs, I am sorry for my lazyness. Apparently spotify and chromium share this specific sink-input.

Apparently spotify and chromium share this specific sink-input.

No, they don't. The only thing they share is the module-stream-restore.id property.

Okay, got it.
I tried my version for the last 11 days and there was no ad playing.

As there is a proposed workaround, i am closing this.

It seems that electron-powered apps are also affected by this muting (whatsie for example), because spotify is also electron-powered (not exactly electron, but it uses a part of chrome).
Just to let people know that the problem is related.