1
mirror of https://github.com/home-assistant/core synced 2024-07-12 07:21:24 +02:00

Use executor to finish stream recording (#75776)

This commit is contained in:
uvjustin 2022-07-27 14:13:38 +08:00 committed by GitHub
parent 89493f2d7f
commit 5e6217f20c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,6 +4,7 @@ from __future__ import annotations
from io import BytesIO
import logging
import os
from typing import TYPE_CHECKING
import av
@ -16,6 +17,9 @@ from .const import (
)
from .core import PROVIDERS, IdleTimer, Segment, StreamOutput, StreamSettings
if TYPE_CHECKING:
import deque
_LOGGER = logging.getLogger(__name__)
@ -139,6 +143,25 @@ class RecorderOutput(StreamOutput):
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
while len(self._segments) > 1: # The last segment is in progress
await self._hass.async_add_executor_job(
@ -153,20 +176,7 @@ class RecorderOutput(StreamOutput):
await self._hass.async_add_executor_job(
write_segment, self._segments.popleft()
)
# Write remaining segments
# Should only have 0 or 1 segments, but loop through just in case
while self._segments:
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,
)
# Write remaining segments and close output
await self._hass.async_add_executor_job(
finish_writing, self._segments, output, self.video_path
)