Repository: streamlink/streamlink

Issue:
No audio stream is parsed from some hlsvariant playlists
*Thanks for reporting an issue!*
*Please read the contribution guidelines first!*

*Feel free to use the following template. Be as detailed as possible.*
*Don't forget to remove this text before submitting.*

----

### Checklist

- [x] This is a bug report.
- [ ] This is a plugin request.
- [ ] This is a feature request.
- [x] I used the search function to find already opened/closed issues or pull requests.

### Description
streamlink parses a playlist but only identifies the video streams. It does not identify or list the audio streams from the playlist
...

### Expected / Actual behavior
When passing an m3u8 playlist to streamlink, I would expect it to do 1 of 2 things.
1. Identify the relevant audio stream and pass both the video and audio through
2. If it is incapable of passing 2 individual streams, then the audio stream should be selectable separately from the video so we can pull and mux them manually
...

### Reproduction steps / Stream URLs to test

1. This requires you to be in Canada or be on a VPN in Canada. 

streamlink "hlsvariant://http://v.watch.cbc.ca/p//38e815a-0099a76a62b//CBC_MR_D_SEASON_01_S01E01-8626003/CBC_MR_D_SEASON_01_S01E01-8626003__desktop.m3u8?cbcott=st=1486012428~exp=1486098828~acl=/*~hmac=a4adc1fd286adec16084a193e0317a92699f71ba23afae73543675eb8e9262dd"

streamlink only identifies the video streams. If you select one, no audio will be passed through.

### Environment details (operating system, python version, etc.)
Windows 10 64bit
Utilizing the latest windows installer build
...

### Comments, logs, screenshots, etc.
Attached is the actual m3u8 playlist from the website.

[CBC_MR_D_SEASON_01_S01E02-8626777__desktop.txt](https://github.com/streamlink/streamlink/files/751328/CBC_MR_D_SEASON_01_S01E02-8626777__desktop.txt)



Discussion:
Are you using 0.3.1? It should support separate audio streams, what if you run it with `-l debug` and report the output here? 
When I was testing this last night 0.3.0 was the latest. I see the new 0.3.1 release but I don't see the windows installer available. Does someone build that and add it later? Can I use the portable tool to build the .exe automatically and just replace the one I have?
The installer will be fixed soon :-) Can you get the debug log an post it here? 
`streamlink -l debug "hlsvariant://http://v.watch.cbc.ca/p//38e815a-0099a76a62b//CBC_MR_D_SEASON_01_S01E01-8626003/CBC_MR_D_SEASON_01_S01E01-8626003__desktop.m3u8?cbcott=st=1486012428~exp=1486098828~acl=/*~hmac=a4adc1fd286adec16084a193e0317a92699f71ba23afae73543675eb8e9262dd"`
I just finished building the newest release from source and it now recognizes the audio tracks! Unfortunately, the stream ends after only a few seconds of playback. Debug logging below.

```[cli][info] Found matching plugin stream for URL hlsvariant://http://v.watch.cbc.ca/p//38e815a-0099a76a62b//CBC_MR_D_SEASON_01_S01E01-8626003/CBC_MR_D_SEASON_01_S01E01-8626003__desktop.m3u8?cbcott=st=1486012428~exp=1486098828~acl=/*~hmac=a4adc1fd286adec16084a193e0317a92699f71ba23afae73543675eb8e9262dd
[hls.parse_variant_playlist][debug] Using external audio track for stream 720p (language=eng)
[hls.parse_variant_playlist][debug] Using external audio track for stream 720p_alt (language=eng)
[hls.parse_variant_playlist][debug] Using external audio track for stream 540p (language=eng)
[hls.parse_variant_playlist][debug] Using external audio track for stream 360p (language=eng)
[hls.parse_variant_playlist][debug] Using external audio track for stream 360p_alt (language=eng)
[hls.parse_variant_playlist][debug] Using external audio track for stream 234p (language=eng)
[cli][info] Available streams: 720p_alt, 360p_alt, 234p (worst), 360p, 540p, 720p (best)
[cli][info] Opening stream: 720p (hls-multi)
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Segments in this playlist are encrypted
[stream.hls][debug] Adding segment 0 to queue
[stream.hls][debug] Reloading playlist
[stream.hls][debug] Adding segment 1 to queue
[stream.hls][debug] Adding segment 2 to queue
[stream.hls][debug] Adding segment 3 to queue
[stream.hls][debug] Adding segment 4 to queue
[stream.hls][debug] Adding segment 5 to queue
[stream.hls][debug] Adding segment 6 to queue
[stream.hls][debug] Adding segment 7 to queue
[stream.hls][debug] Adding segment 8 to queue
[stream.hls][debug] Adding segment 9 to queue
[stream.hls][debug] Adding segment 10 to queue
[stream.hls][debug] Adding segment 11 to queue
[stream.hls][debug] Adding segment 12 to queue
[stream.hls][debug] Adding segment 13 to queue
[stream.hls][debug] Adding segment 14 to queue
[stream.hls][debug] Adding segment 15 to queue
[stream.hls][debug] Adding segment 16 to queue
[stream.hls][debug] Adding segment 17 to queue
[stream.hls][debug] Adding segment 18 to queue
[stream.hls][debug] Adding segment 19 to queue
[stream.hls][debug] Adding segment 20 to queue
[stream.hls][debug] Adding segment 21 to queue
[stream.hls][debug] Adding segment 0 to queue
[stream.hls][debug] Adding segment 1 to queue
[stream.hls][debug] Adding segment 2 to queue
[stream.hls][debug] Adding segment 3 to queue
[stream.hls][debug] Adding segment 4 to queue
[stream.hls][debug] Adding segment 5 to queue
[stream.hls][debug] Adding segment 6 to queue
[stream.hls][debug] Adding segment 7 to queue
[stream.hls][debug] Adding segment 8 to queue
[stream.hls][debug] Adding segment 9 to queue
[stream.hls][debug] Adding segment 10 to queue
[stream.hls][debug] Adding segment 11 to queue
[stream.hls][debug] Adding segment 12 to queue
[stream.hls][debug] Adding segment 13 to queue
[stream.hls][debug] Adding segment 14 to queue
[stream.hls][debug] Adding segment 15 to queue
[stream.hls][debug] Adding segment 16 to queue
[stream.hls][debug] Adding segment 17 to queue
[stream.hls][debug] Adding segment 18 to queue
[stream.hls][debug] Adding segment 19 to queue
[stream.hls][debug] Adding segment 20 to queue
[stream.hls][debug] Adding segment 21 to queue
[stream.mp4mux-ffmpeg][debug] ffmpeg command: C:\Program Files (x86)\Streamlink\ffmpeg\ffmpeg.exe -nostats -y -i \\.\pipe\foo-7432-561 -i \\.\pipe\foo-7432-79 -c:v copy -c:a copy -f matroska pipe:1
[stream.mp4mux-ffmpeg][debug] Starting copy to pipe: \\.\pipe\foo-7432-561
[stream.mp4mux-ffmpeg][debug] Starting copy to pipe: \\.\pipe\foo-7432-79
[cli][debug] Pre-buffering 8192 bytes
[stream.hls][debug] Download of segment 0 complete
[stream.hls][debug] Adding segment 22 to queue
[cli][debug] Checking file output
[stream.hls][debug] Download of segment 1 complete
[stream.hls][debug] Adding segment 23 to queue
[stream.hls][debug] Download of segment 2 complete
[stream.hls][debug] Adding segment 24 to queue
[stream.hls][debug] Download of segment 0 complete
[stream.hls][debug] Adding segment 22 to queue
[stream.hls][debug] Download of segment 3 complete
[stream.hls][debug] Adding segment 25 to queue
[stream.hls][debug] Download of segment 4 complete
[stream.hls][debug] Adding segment 26 to queue
[stream.hls][debug] Download of segment 5 complete
[stream.hls][debug] Adding segment 27 to queue
[stream.hls][debug] Download of segment 6 complete
[stream.hls][debug] Adding segment 28 to queue
[stream.hls][debug] Download of segment 7 complete
[stream.hls][debug] Adding segment 29 to queue
[stream.hls][debug] Download of segment 8 complete
[stream.hls][debug] Adding segment 30 to queue
[stream.hls][debug] Download of segment 9 complete
[stream.hls][debug] Adding segment 31 to queue
[stream.hls][debug] Download of segment 10 complete
[stream.hls][debug] Adding segment 32 to queue
[stream.hls][debug] Download of segment 11 complete
[stream.hls][debug] Adding segment 33 to queue
[stream.hls][debug] Download of segment 12 complete
[stream.hls][debug] Adding segment 34 to queue
[stream.hls][debug] Download of segment 13 complete
[stream.hls][debug] Adding segment 35 to queue
[stream.hls][debug] Download of segment 14 complete
[stream.hls][debug] Adding segment 36 to queue
[stream.hls][debug] Download of segment 15 complete
[stream.hls][debug] Adding segment 37 to queue
[cli][debug] Writing stream to output
[stream.mp4mux-ffmpeg][debug] Closing ffmpeg thread
[stream.hls][debug] Closing worker thread
[stream.hls][debug] Closing writer thread
[stream.mp4mux-ffmpeg][debug] Pipe copy complete: \\.\pipe\foo-7432-561
[stream.hls][debug] Download of segment 16 complete
[stream.hls][debug] Adding segment 38 to queue
[stream.hls][debug] Download of segment 17 complete
[stream.hls][debug] Adding segment 39 to queue
[stream.hls][debug] Download of segment 18 complete
[stream.hls][debug] Adding segment 40 to queue
[stream.hls][debug] Download of segment 19 complete
[stream.hls][debug] Adding segment 41 to queue
[stream.hls][debug] Download of segment 20 complete
[stream.hls][debug] Adding segment 42 to queue
[stream.hls][debug] Download of segment 21 complete
[stream.hls][debug] Adding segment 43 to queue
[stream.hls][debug] Download of segment 22 complete
[stream.hls][debug] Adding segment 44 to queue
[stream.hls][debug] Download of segment 23 complete
[stream.hls][debug] Adding segment 45 to queue
[stream.hls][debug] Download of segment 24 complete
[stream.hls][debug] Adding segment 46 to queue
[stream.hls][debug] Download of segment 25 complete
[stream.hls][debug] Adding segment 47 to queue
[stream.hls][debug] Download of segment 26 complete
[stream.hls][debug] Adding segment 48 to queue
[stream.hls][debug] Download of segment 27 complete
[stream.hls][debug] Adding segment 49 to queue
[stream.hls][debug] Download of segment 28 complete
[stream.hls][debug] Adding segment 50 to queue
[stream.hls][debug] Download of segment 29 complete
[stream.hls][debug] Adding segment 51 to queue
[stream.hls][debug] Download of segment 30 complete
[stream.hls][debug] Adding segment 52 to queue
[stream.hls][debug] Download of segment 31 complete
[stream.hls][debug] Adding segment 53 to queue
[stream.hls][debug] Download of segment 32 complete
[stream.hls][debug] Adding segment 54 to queue
[stream.hls][debug] Download of segment 33 complete
[stream.hls][debug] Adding segment 55 to queue
[stream.hls][debug] Download of segment 34 complete
[stream.hls][debug] Adding segment 56 to queue
[stream.hls][debug] Download of segment 35 complete
[stream.hls][debug] Adding segment 57 to queue
[stream.hls][debug] Download of segment 36 complete
[stream.hls][debug] Adding segment 58 to queue
[stream.hls][debug] Download of segment 37 complete
[stream.hls][debug] Adding segment 59 to queue
[stream.hls][debug] Download of segment 38 complete
[stream.hls][debug] Adding segment 60 to queue
[stream.hls][debug] Download of segment 39 complete
[stream.hls][debug] Adding segment 61 to queue
[stream.hls][debug] Download of segment 40 complete
[stream.hls][debug] Adding segment 62 to queue
[stream.hls][debug] Download of segment 41 complete
[stream.hls][debug] Adding segment 63 to queue
[stream.hls][debug] Download of segment 42 complete
[stream.hls][debug] Adding segment 64 to queue
[stream.hls][debug] Download of segment 43 complete
[stream.hls][debug] Adding segment 65 to queue
[stream.hls][debug] Download of segment 44 complete
[stream.hls][debug] Adding segment 66 to queue
[stream.hls][debug] Download of segment 45 complete
[stream.hls][debug] Adding segment 67 to queue
[stream.hls][debug] Download of segment 46 complete
[stream.hls][debug] Adding segment 68 to queue
[stream.hls][debug] Download of segment 47 complete
[stream.hls][debug] Adding segment 69 to queue
[stream.hls][debug] Download of segment 48 complete
[stream.hls][debug] Adding segment 70 to queue
[stream.hls][debug] Download of segment 49 complete
[stream.hls][debug] Adding segment 71 to queue
[stream.hls][debug] Download of segment 50 complete
[stream.hls][debug] Adding segment 72 to queue
[stream.hls][debug] Download of segment 51 complete
[stream.hls][debug] Adding segment 73 to queue
[stream.hls][debug] Download of segment 1 complete
[stream.hls][debug] Closing worker thread
[stream.hls][debug] Closing writer thread
[stream.mp4mux-ffmpeg][debug] Pipe copy complete: \\.\pipe\foo-7432-79
[stream.hls][debug] Download of segment 52 complete
[stream.mp4mux-ffmpeg][debug] Closed all the substreams
[cli][info] Stream ended
[cli][info] Closing currently open stream...
[stream.mp4mux-ffmpeg][debug] Closing ffmpeg thread
[stream.mp4mux-ffmpeg][debug] Closed all the substreams
[stream.mp4mux-ffmpeg][debug] Closing ffmpeg thread
[stream.mp4mux-ffmpeg][debug] Closed all the substreams```
Interesting, I will take a look. What page did you extract through stream URL from? 
This is the URL.
http://watch.cbc.ca/mr-d/season-1/episode-1/38e815a-0099a76a62b
OK, thanks. I'll take a look at it in next couple of days :-)

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
@@ -5,6 +5,8 @@
 import subprocess
 
 import sys
+
+from streamlink import StreamError
 from streamlink.stream import Stream
 from streamlink.stream.stream import StreamIO
 from streamlink.utils import NamedPipe
@@ -61,7 +63,7 @@ def __init__(self, session, *streams, **options):
         self.logger = session.logger.new_module("stream.mp4mux-ffmpeg")
         self.streams = streams
 
-        self.pipes = [NamedPipe("foo-{}-{}".format(os.getpid(), random.randint(0, 1000))) for _ in self.streams]
+        self.pipes = [NamedPipe("ffmpeg-{0}-{1}".format(os.getpid(), random.randint(0, 1000))) for _ in self.streams]
         self.pipe_threads = [threading.Thread(target=self.copy_to_pipe, args=(self, stream, np))
                              for stream, np in
                              zip(self.streams, self.pipes)]
diff --git a/src/streamlink/stream/hls.py b/src/streamlink/stream/hls.py
--- a/src/streamlink/stream/hls.py
+++ b/src/streamlink/stream/hls.py
@@ -226,7 +226,7 @@ def __init__(self, session, video, audio, force_restart=False, ffmpeg_options=No
         substreams = map(lambda url: HLSStream(session, url, force_restart=force_restart, **args), [video, audio])
         ffmpeg_options = ffmpeg_options or {}
 
-        super(MuxedHLSStream, self).__init__(session, *substreams, **ffmpeg_options)
+        super(MuxedHLSStream, self).__init__(session, *substreams, format="mpegts", **ffmpeg_options)
 
 
 class HLSStream(HTTPStream):
@@ -297,6 +297,7 @@ def parse_variant_playlist(cls, session_, url, name_key="name",
         streams = {}
         for playlist in filter(lambda p: not p.is_iframe, parser.playlists):
             names = dict(name=None, pixels=None, bitrate=None)
+            fallback_audio = None
             default_audio = None
             preferred_audio = None
 
@@ -304,15 +305,16 @@ def parse_variant_playlist(cls, session_, url, name_key="name",
                 if media.type == "VIDEO" and media.name:
                     names["name"] = media.name
                 elif media.type == "AUDIO":
-                    if media.default:
-                        default_audio = media
+                    if not fallback_audio and media.default:
+                        fallback_audio = media
+
                     # if the media is "audoselect" and it better matches the users preferences, use that
                     # instead of default
-                    if media.autoselect and locale.equivalent(language=media.language):
+                    if not default_audio and (media.autoselect and locale.equivalent(language=media.language)):
                         default_audio = media
 
                     # select the first audio stream that matches the users explict language selection
-                    if not preferred_audio and locale.explicit and locale.equivalent(language=media.language):
+                    if (not preferred_audio or media.default) and locale.explicit and locale.equivalent(language=media.language):
                         preferred_audio = media
 
             if playlist.stream_info.resolution:
@@ -350,11 +352,11 @@ def parse_variant_playlist(cls, session_, url, name_key="name",
                 except Exception:
                     continue
 
-            external_audio = preferred_audio or default_audio
+            external_audio = preferred_audio or default_audio or fallback_audio
             if external_audio and external_audio.uri and FFMPEGMuxer.is_usable(session_):
-                logger.debug("Using external audio track for stream {0} (language={1})".format(
+                logger.debug("Using external audio track for stream {0} (language={1}, name={2})".format(
                     name_prefix + stream_name,
-                    external_audio.language))
+                    external_audio.language, external_audio.name or "N/A"))
 
                 stream = MuxedHLSStream(session_,
                                         video=playlist.uri,


Test patch: