mirror of
https://github.com/home-assistant/core
synced 2024-08-02 23:40:32 +02:00
Use executor to finish stream recording (#75776)
This commit is contained in:
parent
89493f2d7f
commit
5e6217f20c
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import av
|
import av
|
||||||
|
|
||||||
@ -16,6 +17,9 @@ from .const import (
|
|||||||
)
|
)
|
||||||
from .core import PROVIDERS, IdleTimer, Segment, StreamOutput, StreamSettings
|
from .core import PROVIDERS, IdleTimer, Segment, StreamOutput, StreamSettings
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import deque
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +143,25 @@ class RecorderOutput(StreamOutput):
|
|||||||
|
|
||||||
source.close()
|
source.close()
|
||||||
|
|
||||||
|
def finish_writing(
|
||||||
|
segments: deque[Segment], output: av.OutputContainer, video_path: str
|
||||||
|
) -> None:
|
||||||
|
"""Finish writing output."""
|
||||||
|
# Should only have 0 or 1 segments, but loop through just in case
|
||||||
|
while segments:
|
||||||
|
write_segment(segments.popleft())
|
||||||
|
if output is None:
|
||||||
|
_LOGGER.error("Recording failed to capture anything")
|
||||||
|
return
|
||||||
|
output.close()
|
||||||
|
try:
|
||||||
|
os.rename(video_path + ".tmp", video_path)
|
||||||
|
except FileNotFoundError:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Error writing to '%s'. There are likely multiple recordings writing to the same file",
|
||||||
|
video_path,
|
||||||
|
)
|
||||||
|
|
||||||
# Write lookback segments
|
# Write lookback segments
|
||||||
while len(self._segments) > 1: # The last segment is in progress
|
while len(self._segments) > 1: # The last segment is in progress
|
||||||
await self._hass.async_add_executor_job(
|
await self._hass.async_add_executor_job(
|
||||||
@ -153,20 +176,7 @@ class RecorderOutput(StreamOutput):
|
|||||||
await self._hass.async_add_executor_job(
|
await self._hass.async_add_executor_job(
|
||||||
write_segment, self._segments.popleft()
|
write_segment, self._segments.popleft()
|
||||||
)
|
)
|
||||||
# Write remaining segments
|
# Write remaining segments and close output
|
||||||
# Should only have 0 or 1 segments, but loop through just in case
|
await self._hass.async_add_executor_job(
|
||||||
while self._segments:
|
finish_writing, self._segments, output, self.video_path
|
||||||
await self._hass.async_add_executor_job(
|
)
|
||||||
write_segment, self._segments.popleft()
|
|
||||||
)
|
|
||||||
if output is None:
|
|
||||||
_LOGGER.error("Recording failed to capture anything")
|
|
||||||
else:
|
|
||||||
output.close()
|
|
||||||
try:
|
|
||||||
os.rename(self.video_path + ".tmp", self.video_path)
|
|
||||||
except FileNotFoundError:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Error writing to '%s'. There are likely multiple recordings writing to the same file",
|
|
||||||
self.video_path,
|
|
||||||
)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user