docs: def start_playing(self, on_exit, args):
          """
          Runs the given args in subprocess.Popen, and then calls the function
          on_exit when the subprocess completes.
          on_exit is a callable object, and args is a lists/tuple of args
          that would give to subprocess.Popen.
          """
          # log.debug("%s,%s,%s" % (args['song_id'], args['song_name'], args['mp3_url']))
          if "cache" in args.keys() and os.path.isfile(args["cache"]):
              thread = threading.Thread(
                  target=self.run_mpg123, args=(on_exit, args["cache"])
              )
          else:
              new_url = NetEase().songs_url([args["song_id"]])[0]["url"]  #使用新地址
              if  not new_url:    #如果没有获得新地址
                  new_url = args["mp3_url"]  #使用老地址传给mpg123
              thread = threading.Thread(
                  target=self.run_mpg123,
                  args=(on_exit, new_url, args["expires"], args["get_time"]),
              )
              cache_thread = threading.Thread(
                  target=self.download_song,
                  args=(
                      args["song_id"],
                      args["song_name"],
                      args["artist"],
                      args["mp3_url"],
                  ),
              )
              cache_thread.start()
  
          thread.start()
          lyric_download_thread = threading.Thread(target=self.download_lyric)
          lyric_download_thread.start()
          tlyric_download_thread = threading.Thread(
              target=self.download_lyric, args=(True,)
          )
          tlyric_download_thread.start()
          # returns immediately after the thread starts
          return thread