diff --git a/homeassistant/components/media_extractor/__init__.py b/homeassistant/components/media_extractor/__init__.py index 39ce1f7a3bd..b657caceaff 100644 --- a/homeassistant/components/media_extractor/__init__.py +++ b/homeassistant/components/media_extractor/__init__.py @@ -1,6 +1,7 @@ """Decorator service for the media_player.play_media service.""" from collections.abc import Callable import logging +from pathlib import Path from typing import Any, cast import voluptuous as vol @@ -106,7 +107,20 @@ class MediaExtractor: def get_stream_selector(self) -> Callable[[str], str]: """Return format selector for the media URL.""" - ydl = YoutubeDL({"quiet": True, "logger": _LOGGER}) + cookies_file = Path( + self.hass.config.config_dir, "media_extractor", "cookies.txt" + ) + ydl_params = {"quiet": True, "logger": _LOGGER} + if cookies_file.exists(): + ydl_params["cookiefile"] = str(cookies_file) + _LOGGER.debug( + "Media extractor loaded cookies file from: %s", str(cookies_file) + ) + else: + _LOGGER.debug( + "Media extractor didn't find cookies file at: %s", str(cookies_file) + ) + ydl = YoutubeDL(ydl_params) try: all_media = ydl.extract_info(self.get_media_url(), process=False) diff --git a/tests/components/media_extractor/test_init.py b/tests/components/media_extractor/test_init.py index c60f67031cf..d32ad90d87c 100644 --- a/tests/components/media_extractor/test_init.py +++ b/tests/components/media_extractor/test_init.py @@ -1,4 +1,6 @@ """The tests for Media Extractor integration.""" +import os +import os.path from typing import Any from unittest.mock import patch @@ -209,3 +211,60 @@ async def test_query_error( await hass.async_block_till_done() assert len(calls) == 0 + + +async def test_cookiefile_detection( + hass: HomeAssistant, + mock_youtube_dl: MockYoutubeDL, + empty_media_extractor_config: dict[str, Any], + calls: list[ServiceCall], + snapshot: SnapshotAssertion, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test cookie file detection.""" + + await async_setup_component(hass, DOMAIN, empty_media_extractor_config) + await hass.async_block_till_done() + + cookies_dir = os.path.join(hass.config.config_dir, "media_extractor") + cookies_file = os.path.join(cookies_dir, "cookies.txt") + + if not os.path.exists(cookies_dir): + os.makedirs(cookies_dir) + + f = open(cookies_file, "w+", encoding="utf-8") + f.write( + """# Netscape HTTP Cookie File + + .youtube.com TRUE / TRUE 1701708706 GPS 1 + """ + ) + f.close() + + await hass.services.async_call( + DOMAIN, + SERVICE_PLAY_MEDIA, + { + "entity_id": "media_player.bedroom", + "media_content_type": "VIDEO", + "media_content_id": YOUTUBE_PLAYLIST, + }, + ) + await hass.async_block_till_done() + + assert "Media extractor loaded cookies file" in caplog.text + + os.remove(cookies_file) + + await hass.services.async_call( + DOMAIN, + SERVICE_PLAY_MEDIA, + { + "entity_id": "media_player.bedroom", + "media_content_type": "VIDEO", + "media_content_id": YOUTUBE_PLAYLIST, + }, + ) + await hass.async_block_till_done() + + assert "Media extractor didn't find cookies file" in caplog.text