Improve Google Cast detection of HLS playlists (#71564)
This commit is contained in:
parent
524920dd2e
commit
d284e579bb
2 changed files with 32 additions and 6 deletions
|
@ -237,12 +237,14 @@ def _is_url(url):
|
||||||
return all([result.scheme, result.netloc])
|
return all([result.scheme, result.netloc])
|
||||||
|
|
||||||
|
|
||||||
async def _fetch_playlist(hass, url):
|
async def _fetch_playlist(hass, url, supported_content_types):
|
||||||
"""Fetch a playlist from the given url."""
|
"""Fetch a playlist from the given url."""
|
||||||
try:
|
try:
|
||||||
session = aiohttp_client.async_get_clientsession(hass, verify_ssl=False)
|
session = aiohttp_client.async_get_clientsession(hass, verify_ssl=False)
|
||||||
async with session.get(url, timeout=5) as resp:
|
async with session.get(url, timeout=5) as resp:
|
||||||
charset = resp.charset or "utf-8"
|
charset = resp.charset or "utf-8"
|
||||||
|
if resp.content_type in supported_content_types:
|
||||||
|
raise PlaylistSupported
|
||||||
try:
|
try:
|
||||||
playlist_data = (await resp.content.read(64 * 1024)).decode(charset)
|
playlist_data = (await resp.content.read(64 * 1024)).decode(charset)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
|
@ -260,7 +262,16 @@ async def parse_m3u(hass, url):
|
||||||
|
|
||||||
Based on https://github.com/dvndrsn/M3uParser/blob/master/m3uparser.py
|
Based on https://github.com/dvndrsn/M3uParser/blob/master/m3uparser.py
|
||||||
"""
|
"""
|
||||||
m3u_data = await _fetch_playlist(hass, url)
|
# From Mozilla gecko source: https://github.com/mozilla/gecko-dev/blob/c4c1adbae87bf2d128c39832d72498550ee1b4b8/dom/media/DecoderTraits.cpp#L47-L52
|
||||||
|
hls_content_types = (
|
||||||
|
# https://tools.ietf.org/html/draft-pantos-http-live-streaming-19#section-10
|
||||||
|
"application/vnd.apple.mpegurl",
|
||||||
|
# Some sites serve these as the informal HLS m3u type.
|
||||||
|
"application/x-mpegurl",
|
||||||
|
"audio/mpegurl",
|
||||||
|
"audio/x-mpegurl",
|
||||||
|
)
|
||||||
|
m3u_data = await _fetch_playlist(hass, url, hls_content_types)
|
||||||
m3u_lines = m3u_data.splitlines()
|
m3u_lines = m3u_data.splitlines()
|
||||||
|
|
||||||
playlist = []
|
playlist = []
|
||||||
|
@ -301,7 +312,7 @@ async def parse_pls(hass, url):
|
||||||
|
|
||||||
Based on https://github.com/mariob/plsparser/blob/master/src/plsparser.py
|
Based on https://github.com/mariob/plsparser/blob/master/src/plsparser.py
|
||||||
"""
|
"""
|
||||||
pls_data = await _fetch_playlist(hass, url)
|
pls_data = await _fetch_playlist(hass, url, ())
|
||||||
|
|
||||||
pls_parser = configparser.ConfigParser()
|
pls_parser = configparser.ConfigParser()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -14,10 +14,25 @@ from homeassistant.components.cast.helpers import (
|
||||||
from tests.common import load_fixture
|
from tests.common import load_fixture
|
||||||
|
|
||||||
|
|
||||||
async def test_hls_playlist_supported(hass, aioclient_mock):
|
@pytest.mark.parametrize(
|
||||||
|
"url,fixture,content_type",
|
||||||
|
(
|
||||||
|
(
|
||||||
|
"http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_fourfm.m3u8",
|
||||||
|
"bbc_radio_fourfm.m3u8",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://rthkaudio2-lh.akamaihd.net/i/radio2_1@355865/master.m3u8",
|
||||||
|
"rthkaudio2.m3u8",
|
||||||
|
"application/vnd.apple.mpegurl",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def test_hls_playlist_supported(hass, aioclient_mock, url, fixture, content_type):
|
||||||
"""Test playlist parsing of HLS playlist."""
|
"""Test playlist parsing of HLS playlist."""
|
||||||
url = "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_low/ak/bbc_radio_fourfm.m3u8"
|
headers = {"content-type": content_type}
|
||||||
aioclient_mock.get(url, text=load_fixture("bbc_radio_fourfm.m3u8", "cast"))
|
aioclient_mock.get(url, text=load_fixture(fixture, "cast"), headers=headers)
|
||||||
with pytest.raises(PlaylistSupported):
|
with pytest.raises(PlaylistSupported):
|
||||||
await parse_playlist(hass, url)
|
await parse_playlist(hass, url)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue