title: Python vlc errors when running script with multiprocessing on RPi 3B+
body: <p>I have a python script (sound_play.py) on a Raspberry Pi 3B+ that plays mp3 files and a webradio stream using vlc.
  It can either be run on its own (for testing purposes) or started as a module in a process by another script (clock.py) using multiprocessing.</p>
  <p>When I run sound_play.py on its own, everything works fine, but if the script is started as a subprocess, I get the error messages down below when a file/the webradio should play.
  I tried it with ALSA as well as PulseAudio, but the behaviour is the same, on its own it works, with multiprocessing it does not.</p>
  <p>A bit of background information: I just reinstalled Raspbian (to solve an unrelated problem), so now I have Bullseye. Before that I had some version of Buster, and the script worked fine, both on its own and in the subprocess. I only get the errors since I reinstalled Raspbian.</p>
  <p>What could cause this? How can I fix it? Thank you in advance.</p>
  <p>Errors using ALSA:</p>
  <pre><code>17:29:42 playing https://orf-live.ors-shoutcast.at/oe1-q2a
  [6d691318] prefetch stream error: unimplemented query (264) in control
  [025e28a8] alsa audio output error: cannot open ALSA device &quot;default&quot;: Input/output error
  [025e28a8] main audio output error: Audio output failed
  [025e28a8] main audio output error: The audio device &quot;default&quot; could not be used:
  Input/output error.
  [025e28a8] main audio output error: module not functional
  [71f45f68] main decoder error: failed to create audio output
  </code></pre>
  <p>Errors using PulseAudio:</p>
  <pre><code>17:46:26 playing https://orf-live.ors-shoutcast.at/oe1-q2a
  [4cd97a68] prefetch stream error: unimplemented query (264) in control
  [02019030] vlcpulse audio output error: stream creation failure: Client forked
  [02019030] main audio output error: module not functional
  [71f4c390] main decoder error: failed to create audio output
  </code></pre>
  <p>sound_play.py</p>
  <pre><code>#!/usr/bin/env python3
  &quot;&quot;&quot;
  sound_play.py
  play sounds at certain times
  &quot;&quot;&quot;
  
  #IMPORTS
  import time
  from datetime import datetime, timedelta
  import vlc
  
  #CONSTANTS
  DEBUG = True
  VOLUME = 80 #in percent
  DUR_SUNRISE = 5 #min
  DUR_AFTERGLOW = 5 #min
  MUSIC_PATH = &quot;./alarms/&quot;
  HOURBELL = &quot;./hourbell.mp3&quot;
  RADIO_NAME = &quot;Radio Österreich Eins&quot;
  RADIO_URL = &quot;https://orf-live.ors-shoutcast.at/oe1-q2a&quot;
  
  #GLOBALS
  config = None
  temp = None
  instance = vlc.Instance('--aout=alsa')
  player = instance.media_player_new()
  
  def start(source):
      media = instance.media_new(source) 
      player.set_media(media)
      player.play()
      if DEBUG: print(time.strftime(&quot;%T&quot;), &quot;playing &quot; + str(source))
  
  def stop():
      player.stop()
      if DEBUG: print(time.strftime(&quot;%T&quot;), &quot;stopped playing&quot;)
  
  def main(*args):
      global DEBUG, config, temp
      if args:
          (debug, config, temp) = args
          if debug == True:
              DEBUG = True
  
      global instance
  
      radio_active = False
      radio_start = 0.0
      music_active = False
      music_start = 0.0
      hourbell_active = False
      hourbell_start = 0.0
      hourbell_last = &quot;&quot;
          
      vlc.libvlc_audio_set_volume(player, VOLUME)
      if not DEBUG: instance.log_unset()
      
      while True:
          if not config == None:
              #radio
              if temp[&quot;button_new&quot;] and temp[&quot;read_button&quot;] == &quot;*&quot;:
                  temp[&quot;button_new&quot;] = False
                  if (music_active and not radio_active) or radio_active:
                      radio_active = False
                      music_active = False
                      stop()
                      
                  else:
                      start(RADIO_URL)
                      radio_active = True
                      music_active = False
                      radio_start = time.time()
  
              if radio_active and time.time() &gt;= radio_start + (60 * 60):
                  radio_active = False
                  stop()
  
              #alarm
              if config[&quot;alarm_music&quot;] and time.strftime(&quot;%H%M&quot;) == config[&quot;alarm_time&quot;] and time.time() &gt;= music_start + 60:           
                  if config[&quot;alarm_song&quot;] != RADIO_NAME and not music_active:
                      if not radio_active: start(MUSIC_PATH + config[&quot;alarm_song&quot;] + &quot;.mp3&quot;)
                      music_active = True
  
                  elif config[&quot;alarm_song&quot;] == RADIO_NAME:
                      if not radio_active: start(RADIO_URL)
                      radio_active = True
                      music_active = True
                      radio_start = time.time()
                  
                  music_start = time.time()
              
              elif music_active and not radio_active and time.time() &gt;= music_start + 1.5:
                  if time.time() &gt;= music_start + player.get_length() / 1000 + 1.5:
                      music_active = False
                      stop()
  
              elif music_active and radio_active and time.time() &gt;= music_start + (5 * 60):
                  music_active = False
  
              #hourbell
              if time.strftime(&quot;%M&quot;) == &quot;00&quot; and not time.strftime(&quot;%H&quot;) == hourbell_last:
                  hourbell_last = time.strftime(&quot;%H&quot;)
  
                  if config[&quot;alarm_hourbell&quot;] and not hourbell_active and not music_active and not radio_active \
                      and (time.time() - temp[&quot;afterglow_start&quot;] &lt; DUR_AFTERGLOW * 60 or temp[&quot;light_on&quot;]):
                      start(HOURBELL)
                      hourbell_active = True
                      hourbell_start = time.time()
                      
              elif hourbell_active and time.time() &gt;= hourbell_start + 1.5:
                  if time.time() &gt;= hourbell_start + player.get_length() / 1000 + 1.5:
                      hourbell_active = False
                      stop()
  
              #sunrise
              time_after_duration = time.strftime(&quot;%H%M&quot;, time.localtime((datetime.now() + timedelta(minutes=DUR_SUNRISE)).timestamp()))
              if time_after_duration == config[&quot;alarm_time&quot;] and config[&quot;alarm_sunrise&quot;] and not temp[&quot;sunrise_active&quot;]: 
                  temp[&quot;sunrise_active&quot;] = True
  
              elif time.strftime(&quot;%H%M&quot;) &gt;= config[&quot;alarm_time&quot;] and temp[&quot;sunrise_active&quot;] and not music_active:
                  temp[&quot;sunrise_active&quot;] = False
  
              time.sleep(0.01)
          
          else:
              source = input(&quot;source: &quot;)
              if source == &quot;r&quot;: start(RADIO_URL)
              else: start(MUSIC_PATH + source + &quot;.mp3&quot;)
              input(&quot;stop&quot;)
              stop()
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>
  <p>clock.py</p>
  <pre><code>#!/usr/bin/env python3
  &quot;&quot;&quot;
  clock.py
  main script, manage module threads
  &quot;&quot;&quot;
  
  #IMPORTS
  import os
  from multiprocessing import Process, Manager
  import json
  import time
  import RPi.GPIO as GPIO
  
  #import time_sync
  import weather_fetch
  import arduino_talk
  import room_measure
  import hands_move
  import sound_play
  import gui_show
  
  #CONSTANTS
  debug = False #debug for all modules
  DEBUG = False #debug for this script
  NICENESS = -5
  CONFIG_FILE = &quot;./config.json&quot;
  PIN_STEPPER = {
      &quot;hour&quot;: {
          &quot;A&quot;: 4,
          &quot;B&quot;: 17,
          &quot;C&quot;: 27,
          &quot;D&quot;: 22,
      },
      &quot;minute&quot;: {
          &quot;A&quot;: 5,
          &quot;B&quot;: 6,
          &quot;C&quot;: 13,
          &quot;D&quot;: 19,
      }
  }
  
  def main():
      def store_clock(config):
          while True:
              with open(CONFIG_FILE, &quot;w&quot;) as config_file:
                  json.dump(config.copy(), config_file)
  
              if debug: print(time.strftime(&quot;%T&quot;), &quot;Configuration stored&quot;)
              time.sleep(20)
  
      global DEBUG
      
      if debug:
          DEBUG = True
  
      config_reset = {
          #hands_move
          &quot;calibration&quot;: {'first': {'hour': 1926, 'minute': 1920}, 'second': {'hour': 1915, 'minute': 1920}},
          
          #gui_show
          &quot;alarm_time&quot;: &quot;0000&quot;,
          &quot;alarm_sunrise&quot;: False,
          &quot;alarm_music&quot;: False,
          &quot;alarm_hourbell&quot;: False,
          &quot;alarm_song&quot;: &quot;&quot;,
          &quot;weather_location&quot;: &quot;Lessach&quot;,  
      }
      temp_reset = {
          #weather_fetch
          &quot;weather_current&quot;: &quot;&quot;,
          &quot;weather_forecast&quot;: &quot;&quot;,
  
          #arduino_talk
          &quot;light_on&quot;: True,
          &quot;read_button&quot;: &quot;&quot;,
          &quot;button_new&quot;: False,
  
          #room_measure
          &quot;room_climate&quot;: &quot;&quot;,
  
          #gui_show
          &quot;sunrise_active&quot;: False,
          &quot;afterglow_start&quot;: 0.0,
      }
      
      os.system(&quot;sudo renice -n &quot; + str(NICENESS) + &quot; -p &quot; + str(os.getpid()) + &quot;&gt;/dev/null&quot;)
      
      print(&quot;MULTIFUNKTIONS-DESIGNUHR&quot;)
      print(&quot;Michael Matthias Jesner&quot;)
      print(&quot;WSH Gesellenstück 2020&quot;)
      print(&quot;Zum Beenden Enter drücken\n&quot;)
  
      if not os.path.exists(CONFIG_FILE):
          with open(CONFIG_FILE, &quot;w&quot;) as config_file:
              json.dump(config_reset, config_file)
          
          if debug: print(time.strftime(&quot;%T&quot;), &quot;Reset config.json&quot;)
  
      with open(CONFIG_FILE, &quot;r&quot;) as config_file:
          config = Manager().dict(json.load(config_file))
          
      temp = Manager().dict(temp_reset)
  
      store_process = Process(target = store_clock, args = (config,))
      process = [
          #Process(target = time_sync.main, args = (debug, config, temp)),
          Process(target = weather_fetch.main, args = (debug, config, temp)),
          Process(target = arduino_talk.main, args = (debug, config, temp)),
          Process(target = room_measure.main, args = (debug, config, temp)),
          Process(target = hands_move.main, args = (debug, config, temp)),
          Process(target = sound_play.main, args = (debug, config, temp)),
          Process(target = gui_show.main, args = (debug, config, temp)),
          ]
  
      for x in range(len(process)):
          process[x].start()
  
      store_process.start()
  
      input(&quot;&quot;)
  
      store_process.terminate()
      with open(CONFIG_FILE, &quot;w&quot;) as config_file:
          json.dump(config.copy(), config_file)
  
      for x in range(len(process)):
          process[x].terminate()
  
      GPIO.setmode(GPIO.BCM)
      for x in PIN_STEPPER:
          for y in PIN_STEPPER[x]:
              GPIO.setup(PIN_STEPPER[x][y],GPIO.OUT)
              GPIO.output(PIN_STEPPER[x][y], GPIO.LOW)
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>
  <p><strong>Minimal reproducible example:</strong></p>
  <p>test1.py</p>
  <pre><code>from multiprocessing import Process, Manager
  import test2
  
  def main():
      p = Process(target = test2.main)
      p.start()
      input()
      p.terminate()
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>
  <p>test2.py</p>
  <pre><code>#!/usr/bin/env python3
  import vlc
  import time
  
  VOLUME = 100
  URL = &quot;https://orf-live.ors-shoutcast.at/oe1-q2a&quot;
  
  instance = vlc.Instance('--aout=alsa')
  player = instance.media_player_new()
  
  vlc.libvlc_audio_set_volume(player, VOLUME)
  
  def main():
      media = instance.media_new(URL) 
      player.set_media(media)
  
      while True:
          player.play()
          time.sleep(5)
          player.pause()
          time.sleep(5)
  
  if __name__ == &quot;__main__&quot;:
      main()
  </code></pre>