Repository: streamlink/streamlink

Issue:
Delay in closing of Muxed Streams
<!--
Thanks for reporting a bug!
USE THE TEMPLATE. Otherwise your bug report may be rejected.

First, see the contribution guidelines:
https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink

Also check the list of open and closed bug reports:
https://github.com/streamlink/streamlink/issues?q=is%3Aissue+label%3A%22bug%22

Please see the text preview to avoid unnecessary formatting errors.
-->


## Bug Report

<!-- Replace [ ] with [x] in order to check the box -->
- [x] This is a bug report and I have read the contribution guidelines.


### Description

<!-- Explain the bug as thoroughly as you can. Don't leave out information which is necessary for us to reproduce and debug this issue. -->


### Expected / Actual behavior
**Expected:** 
Muxed Streams to close as fast as other streams.
**Actual:**
Muxed Streams take much longer to close than other stream-types.
Muxed Streams takes around 9 seconds to close on average in my system, whereas other streams close almost instantly when the player is closed or when terminated from the command line.


### Reproduction steps / Explicit stream URLs to test

<!-- How can we reproduce this? Please note the exact steps below using the list format supplied. If you need more steps please add them. -->

1. Stream a supported video using the --stream-type: muxed-stream parameter or simply play a 1080p Youtube video.
2. Close the stream using Command C.
3. Note how long the close operation takes.


### Log output

<!--
TEXT LOG OUTPUT IS REQUIRED for a bug report!
Use the `--loglevel debug` parameter and avoid using parameters which suppress log output.
https://streamlink.github.io/cli.html#cmdoption-l

Make sure to **remove usernames and passwords**
You can copy the output to https://gist.github.com/ or paste it below.
-->

```
> streamlink https://www.youtube.com/watch?v=ET9HeSFYlEs 480p --stream-type muxed-stream
[cli][info] Found matching plugin youtube for URL https://www.youtube.com/watch?v=ET9HeSFYlEs
[cli][info] Opening stream: 480p (muxed-stream)
[cli][info] Starting player: "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"
[cli][info] Stream ended
Interrupted! Exiting...
[cli][info] Closing currently open stream...
```


### Additional comments, screenshots, etc.

The lines
```
[cli][info] Stream ended
Interrupted! Exiting...
[cli][info] Closing currently open stream...
```
only appear after the delay period.
I've figured this to be because of the need to close named pipes in muxed-streams.
```python
def close(self):
    if self.pipe:
         windll.kernel32.DisconnectNamedPipe(self.pipe)
    else:
         self.fifo.close()
         os.unlink(self.path)
```
The above code is likely the cause of the delay.

Can this delay be reduced?

### Environments

Windows 10 v. 1909
Python 3.8.3
MSVSC 1.47.3



Discussion:

Resolving patch:
diff --git a/src/streamlink/stream/ffmpegmux.py b/src/streamlink/stream/ffmpegmux.py
--- a/src/streamlink/stream/ffmpegmux.py
+++ b/src/streamlink/stream/ffmpegmux.py
@@ -1,3 +1,4 @@
+import concurrent.futures
 import logging
 import subprocess
 import sys
@@ -183,10 +184,13 @@ def close(self):
             self.process.stdout.close()
 
             # close the streams
+            futures = []
+            executor = concurrent.futures.ThreadPoolExecutor()
             for stream in self.streams:
                 if hasattr(stream, "close") and callable(stream.close):
-                    stream.close()
+                    futures.append(executor.submit(stream.close))
 
+            concurrent.futures.wait(futures, return_when=concurrent.futures.ALL_COMPLETED)
             log.debug("Closed all the substreams")
 
         if self.close_errorlog:


Test patch: