Speed up ffmpeg setup (#113496)
* Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * Speed up ffmpeg setup Only check for old versions of ffmpeg if is_official_image is False * adjust * adjust * twea * Update homeassistant/components/ffmpeg/__init__.py * forgot about the mock in conftest for compspull/113540/head
parent
1c938f6422
commit
c69ab425c5
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
|
||||
import asyncio
|
||||
import re
|
||||
from typing import Generic, TypeVar
|
||||
from typing import TYPE_CHECKING, Generic, TypeVar
|
||||
|
||||
from haffmpeg.core import HAFFmpeg
|
||||
from haffmpeg.tools import IMAGE_JPEG, FFVersion, ImageFrame
|
||||
|
@ -24,9 +24,16 @@ from homeassistant.helpers.dispatcher import (
|
|||
async_dispatcher_send,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.system_info import is_official_image
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.loader import bind_hass
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from functools import cached_property
|
||||
else:
|
||||
from homeassistant.backports.functools import cached_property
|
||||
|
||||
|
||||
_HAFFmpegT = TypeVar("_HAFFmpegT", bound=HAFFmpeg)
|
||||
|
||||
DOMAIN = "ffmpeg"
|
||||
|
@ -49,6 +56,12 @@ CONF_OUTPUT = "output"
|
|||
|
||||
DEFAULT_BINARY = "ffmpeg"
|
||||
|
||||
# Currently we only care if the version is < 3
|
||||
# because we use a different content-type
|
||||
# It is only important to update this version if the
|
||||
# content-type changes again in the future
|
||||
OFFICIAL_IMAGE_VERSION = "6.0"
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
|
@ -142,26 +155,28 @@ class FFmpegManager:
|
|||
self._version: str | None = None
|
||||
self._major_version: int | None = None
|
||||
|
||||
@property
|
||||
@cached_property
|
||||
def binary(self) -> str:
|
||||
"""Return ffmpeg binary from config."""
|
||||
return self._bin
|
||||
|
||||
async def async_get_version(self) -> tuple[str | None, int | None]:
|
||||
"""Return ffmpeg version."""
|
||||
|
||||
ffversion = FFVersion(self._bin)
|
||||
self._version = await ffversion.get_version()
|
||||
|
||||
self._major_version = None
|
||||
if self._version is not None:
|
||||
result = re.search(r"(\d+)\.", self._version)
|
||||
if result is not None:
|
||||
self._major_version = int(result.group(1))
|
||||
if self._version is None:
|
||||
if is_official_image():
|
||||
self._version = OFFICIAL_IMAGE_VERSION
|
||||
self._major_version = int(self._version.split(".")[0])
|
||||
elif (
|
||||
(version := await FFVersion(self._bin).get_version())
|
||||
and (result := re.search(r"(\d+)\.", version))
|
||||
and (major_version := int(result.group(1)))
|
||||
):
|
||||
self._version = version
|
||||
self._major_version = major_version
|
||||
|
||||
return self._version, self._major_version
|
||||
|
||||
@property
|
||||
@cached_property
|
||||
def ffmpeg_stream_content_type(self) -> str:
|
||||
"""Return HTTP content type for ffmpeg stream."""
|
||||
if self._major_version is not None and self._major_version > 3:
|
||||
|
|
|
@ -8,6 +8,7 @@ from homeassistant.components.ffmpeg import (
|
|||
SERVICE_RESTART,
|
||||
SERVICE_START,
|
||||
SERVICE_STOP,
|
||||
get_ffmpeg_manager,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
|
@ -251,3 +252,40 @@ async def test_async_get_image_with_extra_cmd_width_height(hass: HomeAssistant)
|
|||
assert get_image_mock.call_args_list == [
|
||||
call("rtsp://fake", output_format="mjpeg", extra_cmd="-vf any -s 640x480")
|
||||
]
|
||||
|
||||
|
||||
async def test_modern_ffmpeg(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test modern ffmpeg uses the new ffmpeg content type."""
|
||||
with assert_setup_component(1):
|
||||
await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}})
|
||||
|
||||
manager = get_ffmpeg_manager(hass)
|
||||
assert "ffmpeg" in manager.ffmpeg_stream_content_type
|
||||
|
||||
|
||||
async def test_legacy_ffmpeg(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test legacy ffmpeg uses the old ffserver content type."""
|
||||
with assert_setup_component(1), patch(
|
||||
"homeassistant.components.ffmpeg.FFVersion.get_version", return_value="3.0"
|
||||
), patch("homeassistant.components.ffmpeg.is_official_image", return_value=False):
|
||||
await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}})
|
||||
|
||||
manager = get_ffmpeg_manager(hass)
|
||||
assert "ffserver" in manager.ffmpeg_stream_content_type
|
||||
|
||||
|
||||
async def test_ffmpeg_using_official_image(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test ffmpeg using official image is the new ffmpeg content type."""
|
||||
with assert_setup_component(1), patch(
|
||||
"homeassistant.components.ffmpeg.is_official_image", return_value=True
|
||||
):
|
||||
await async_setup_component(hass, ffmpeg.DOMAIN, {ffmpeg.DOMAIN: {}})
|
||||
|
||||
manager = get_ffmpeg_manager(hass)
|
||||
assert "ffmpeg" in manager.ffmpeg_stream_content_type
|
||||
|
|
Loading…
Reference in New Issue