Michael, your suggested code does work fine, and it has been what I’m using.
I had been updating the volume upon every cycle of loop(), which would cause MP3player.pauseDataStream() to resume immediately. Now I store the paused state in a global variable and check against it, as follows:
if (!time_paused && MP3player.isPlaying()) volumeChange();
(where volumeChange() is a private function that reads data and calls MP3player.SetVolume())