No tests for this change, because the test for FFMPEGMuxer.open currently doesn't touch the pipe_threads, and I don't want to mess with this.
The fix is simple, just break out of the while loop instead of returning, so that the pipe.close() call always gets made.
$ streamlink -l debug 'https://www.youtube.com/watch?v=xcJtL7QggTI' best
[cli][debug] OS: Linux-5.13.13-1-git-x86_64-with-glibc2.33
[cli][debug] Python: 3.9.6
[cli][debug] Streamlink: 2.3.0+49.g830c5ec
[cli][debug] Requests(2.26.0), Socks(1.7.1), Websocket(1.1.0)
[cli][debug] Arguments:
[cli][debug] url=https://www.youtube.com/watch?v=xcJtL7QggTI
[cli][debug] stream=['best']
[cli][debug] --loglevel=debug
[cli][debug] --player=mpv
[cli][info] Found matching plugin youtube for URL https://www.youtube.com/watch?v=xcJtL7QggTI
[plugins.youtube][debug] Using video ID: xcJtL7QggTI
[plugins.youtube][debug] MuxedStream: v 137 a 251 = 1080p
[plugins.youtube][debug] MuxedStream: v 135 a 251 = 480p
[plugins.youtube][debug] MuxedStream: v 133 a 251 = 240p
[plugins.youtube][debug] MuxedStream: v 160 a 251 = 144p
[cli][info] Available streams: audio_mp4a, audio_opus, 144p (worst), 240p, 360p, 480p, 720p, 1080p (best)
[cli][info] Opening stream: 1080p (muxed-stream)
[stream.ffmpegmux][debug] Opening http substream
[stream.ffmpegmux][debug] Opening http substream
[utils.named_pipe][info] Creating pipe streamlinkpipe-70962-1-1164
[utils.named_pipe][info] Creating pipe streamlinkpipe-70962-2-4705
[stream.ffmpegmux][debug] ffmpeg command: ffmpeg -nostats -y -i /tmp/streamlinkpipe-70962-1-1164 -i /tmp/streamlinkpipe-70962-2-4705 -c:v copy -c:a copy -map 0 -map 1 -f matroska pipe:1
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-70962-1-1164
[stream.ffmpegmux][debug] Starting copy to pipe: /tmp/streamlinkpipe-70962-2-4705
[cli][debug] Pre-buffering 8192 bytes
[cli][info] Starting player: mpv
[cli.output][debug] Opening subprocess: mpv --force-media-title=https://www.youtube.com/watch?v=xcJtL7QggTI -
[cli][debug] Writing stream to output
[cli][info] Player closed
[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.ffmpegmux][error] Pipe copy aborted: /tmp/streamlinkpipe-70962-1-1164
[stream.ffmpegmux][error] Pipe copy aborted: /tmp/streamlinkpipe-70962-2-4705
[stream.ffmpegmux][debug] Pipe copy complete: /tmp/streamlinkpipe-70962-1-1164
[stream.ffmpegmux][debug] Pipe copy complete: /tmp/streamlinkpipe-70962-2-4705
[stream.ffmpegmux][debug] Closed all the substreams
[cli][info] Stream ended
[cli][info] Closing currently open stream...
$ ls /tmp/streamlinkpipe-*
fish: No matches for wildcard โ/tmp/streamlinkpipe-*โ. See `help expand`.
ls /tmp/streamlinkpipe-*
^