Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

headless mode should be able to play audio #2999

Closed
demian85 opened this issue Jul 31, 2018 · 12 comments
Closed

headless mode should be able to play audio #2999

demian85 opened this issue Jul 31, 2018 · 12 comments

Comments

@demian85
Copy link

  • Puppeteer version: 1.6.1
  • Platform / OS version: MacOS High Sierra
  • URLs (if applicable):
  • Node.js version: 10.7

Let's face it, Puppeteer is not just for testing purposes. People come up with weird and useful ideas for automating stuff too.
In my case, I'm trying to build a Spotify CLI client, and Chrome is the only way to play a song, as it is encrypted media (is there another way?)

The problem is that when setting headless mode, I get the following screen. Otherwise, the song plays as expected.

screenshot-test

Why features available in headless mode are not the same as in normal mode? Is the hard-coded option --mute-audio the problem here? I tried removing it manually but nothing happens, so it seems that Spotify is checking for something that is not available. Any ideas what could it be?

Thanks.

@ebidel
Copy link
Contributor

ebidel commented Aug 1, 2018

Keep in mind that puppeteer uses Chromium, which does not necessarily play all types of media. See https://github.com/GoogleChrome/puppeteer#q-what-features-does-puppeteer-not-support. That may be at least one of your issues.

@demian85
Copy link
Author

demian85 commented Aug 1, 2018

Sorry. I did not specify that I'm using Chrome instead of Chromium. Player works when not in headless mode!

@demian85
Copy link
Author

I've just just tried puppeteer v1.7 with Chrome Canary and the problem is still there.
The only difference I can tell between headless and normal mode by logging default arguments is the option --mute-audio and --hide-scrollbars.
I tried excluding those options with no luck. Spotify still thinks my browser is not able to play audio!

@aslushnikov
Copy link
Contributor

Spotify still thinks my browser is not able to play audio!

@demian85 any script I can play with that reproduces the issue?

@demian85
Copy link
Author

demian85 commented Sep 9, 2018

Yes, you can try the actual spotify-cli module: https://github.com/demian85/spotify-cli
It does not work, but it takes a screenshot of the playlist view right before trying to play it.

@aslushnikov
Copy link
Contributor

aslushnikov commented Sep 9, 2018

@demian85 ok I played with it; there are a few things that might happen:

  1. Spotify seems to figure that I'm using automated browser (there are many ways to figure that out, see headless-cat-n-mouse) and makes it hard to log in. It took me a while (and maybe 5-7 solved captchas) to login on the headful browser
  2. Once I logged in in headful, I was able to successfully play sound using your script. This is unsurprising though. (i was in headful)
  3. I can't just launch in headless to see if it will work; auth will get lost due to the current incompatibilities between headless/headful profiles
  4. I was able to separately validate that headless can play mp3, running the following script:
const puppeteer = require('puppeteer');
(async() => {
  const browser = await puppeteer.launch({
    ignoreDefaultArgs: ['--mute-audio'],
  });
  const page = await browser.newPage();
  await page.goto('http://www.noiseaddicts.com/free-samples-mp3/?id=2544');
  await page.click('span.map_play');
})();

So all in all, there's no problem with headless not playing audio. However, it might be spotify that detects automation and prevents you from doing so.

Hope this helps.

@LukasBombach
Copy link

Thanks for the work @aslushnikov !!

@LukasBombach
Copy link

LukasBombach commented Nov 6, 2018

It seems Spotify isn't blocking Puppeteer, it's just that it throws an error:

Exception: DOMException
code: 9
message: "Unsupported keySystem or supportedConfigurations."
name: "NotSupportedError"

when calling Navigator.requestMediaKeySystemAccess

you can see that in headful mode

The problem might be that chromium does not support a DRM system: #720

@edospadoni
Copy link

Hi, try to execute puppeteer with headless: false but in a fake display env. It's a trick to exec the web player in background without using a real display.

xvfb-run-safe.sh /usr/bin/node index.js

xvfb deps:

<yum | dnf | apt-get> install xvfb

xvfb-run-safe.sh:

#!/bin/bash

: "${xvfb_lockdir:=$HOME/.xvfb-locks}"
: "${xvfb_display_min:=99}"
: "${xvfb_display_max:=599}"

mkdir -p -- "$xvfb_lockdir" || exit

i=$xvfb_display_min
while (( i < xvfb_display_max )); do
  if [ -f "/tmp/.X$i-lock" ]; then
    (( ++i )); continue
  fi
  exec 5>"$xvfb_lockdir/$i" || continue
  if flock -x -n 5; then
    exec /usr/bin/xvfb-run --server-num="$i" "$@" || exit 
  fi
  (( i++ ))
done

puppeteer conf:

this.browser = await puppeteer.launch({
    headless: false,
    defaultViewport: {
      width: 1280,
      height: 768
    },
    executablePath: "/usr/bin/google-chrome",
    ignoreDefaultArgs: ["--mute-audio", "--hide-scrollbars"]
});

@vitalspace
Copy link

vitalspace commented Dec 17, 2019

Hi, try to execute puppeteer with headless: false but in a fake display env. It's a trick to exec the web player in background without using a real display.

xvfb-run-safe.sh /usr/bin/node index.js

xvfb deps:

<yum | dnf | apt-get> install xvfb

xvfb-run-safe.sh:

#!/bin/bash

: "${xvfb_lockdir:=$HOME/.xvfb-locks}"
: "${xvfb_display_min:=99}"
: "${xvfb_display_max:=599}"

mkdir -p -- "$xvfb_lockdir" || exit

i=$xvfb_display_min
while (( i < xvfb_display_max )); do
  if [ -f "/tmp/.X$i-lock" ]; then
    (( ++i )); continue
  fi
  exec 5>"$xvfb_lockdir/$i" || continue
  if flock -x -n 5; then
    exec /usr/bin/xvfb-run --server-num="$i" "$@" || exit 
  fi
  (( i++ ))
done

puppeteer conf:

this.browser = await puppeteer.launch({
    headless: false,
    defaultViewport: {
      width: 1280,
      height: 768
    },
    executablePath: "/usr/bin/google-chrome",
    ignoreDefaultArgs: ["--mute-audio", "--hide-scrollbars"]
});

Is there a way to execute your code with node xvfb?

@edospadoni
Copy link

Hi, try to execute puppeteer with headless: false but in a fake display env. It's a trick to exec the web player in background without using a real display.
xvfb-run-safe.sh /usr/bin/node index.js
xvfb deps:

<yum | dnf | apt-get> install xvfb

xvfb-run-safe.sh:

#!/bin/bash

: "${xvfb_lockdir:=$HOME/.xvfb-locks}"
: "${xvfb_display_min:=99}"
: "${xvfb_display_max:=599}"

mkdir -p -- "$xvfb_lockdir" || exit

i=$xvfb_display_min
while (( i < xvfb_display_max )); do
  if [ -f "/tmp/.X$i-lock" ]; then
    (( ++i )); continue
  fi
  exec 5>"$xvfb_lockdir/$i" || continue
  if flock -x -n 5; then
    exec /usr/bin/xvfb-run --server-num="$i" "$@" || exit 
  fi
  (( i++ ))
done

puppeteer conf:

this.browser = await puppeteer.launch({
    headless: false,
    defaultViewport: {
      width: 1280,
      height: 768
    },
    executablePath: "/usr/bin/google-chrome",
    ignoreDefaultArgs: ["--mute-audio", "--hide-scrollbars"]
});

Is there a way to execute your code with node xvfb?

The way is described above: xvfb-run-safe.sh /usr/bin/node index.js

@xxx59
Copy link

xxx59 commented Nov 26, 2020

Hi please dose the above method work on Spotify headless chrome mode?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants