async def start_stream(self, session_info, stream_config):
        """Start a new stream with the given configuration."""
        _LOGGER.debug(
            "[%s] Starting stream with the following parameters: %s",
            session_info["id"],
            stream_config,
        )
        input_source = await self._async_get_stream_source()
        if not input_source:
            _LOGGER.error("Camera has no stream source")
            return False
        if "-i " not in input_source:
            input_source = "-i " + input_source
        video_profile = ""
        if self.config[CONF_VIDEO_CODEC] != "copy":
            video_profile = (
                "-profile:v " + VIDEO_PROFILE_NAMES[int.from_bytes(
                    stream_config["v_profile_id"], byteorder="big")] + " ")
        audio_application = ""
        if self.config[CONF_AUDIO_CODEC] == "libopus":
            audio_application = "-application lowdelay "
        output_vars = stream_config.copy()
        output_vars.update({
            "v_profile": video_profile,
            "v_bufsize": stream_config["v_max_bitrate"] * 4,
            "v_map": self.config[CONF_VIDEO_MAP],
            "v_pkt_size": self.config[CONF_VIDEO_PACKET_SIZE],
            "v_codec": self.config[CONF_VIDEO_CODEC],
            "a_bufsize": stream_config["a_max_bitrate"] * 4,
            "a_map": self.config[CONF_AUDIO_MAP],
            "a_pkt_size": self.config[CONF_AUDIO_PACKET_SIZE],
            "a_encoder": self.config[CONF_AUDIO_CODEC],
            "a_application": audio_application,
        })
        output = VIDEO_OUTPUT.format(**output_vars)
        if self.config[CONF_SUPPORT_AUDIO]:
            output = output + " " + AUDIO_OUTPUT.format(**output_vars)
        _LOGGER.debug("FFmpeg output settings: %s", output)
        stream = HAFFmpeg(self._ffmpeg.binary)
        opened = await stream.open(cmd=[],
                                   input_source=input_source,
                                   output=output,
                                   stdout_pipe=False)
        if not opened:
            _LOGGER.error("Failed to open ffmpeg stream")
            return False

        _LOGGER.info(
            "[%s] Started stream process - PID %d",
            session_info["id"],
            stream.process.pid,
        )

        session_info["stream"] = stream
        session_info[FFMPEG_PID] = stream.process.pid

        async def watch_session(_):
            await self._async_ffmpeg_watch(session_info["id"])

        session_info[FFMPEG_WATCHER] = async_track_time_interval(
            self.hass,
            watch_session,
            FFMPEG_WATCH_INTERVAL,
        )

        return await self._async_ffmpeg_watch(session_info["id"])
Esempio n. 2
0
                "v_bufsize": stream_config["v_max_bitrate"] * 4,
                "v_map": self.config[CONF_VIDEO_MAP],
                "v_pkt_size": self.config[CONF_VIDEO_PACKET_SIZE],
                "v_codec": self.config[CONF_VIDEO_CODEC],
                "a_bufsize": stream_config["a_max_bitrate"] * 4,
                "a_map": self.config[CONF_AUDIO_MAP],
                "a_pkt_size": self.config[CONF_AUDIO_PACKET_SIZE],
                "a_encoder": self.config[CONF_AUDIO_CODEC],
                "a_application": audio_application,
            }
        )
        output = VIDEO_OUTPUT.format(**output_vars)
        if self.config[CONF_SUPPORT_AUDIO]:
            output = output + " " + AUDIO_OUTPUT.format(**output_vars)
        _LOGGER.debug("FFmpeg output settings: %s", output)
        stream = HAFFmpeg(self._ffmpeg.binary)
        opened = await stream.open(
            cmd=[],
            input_source=input_source,
            output=output,
            extra_cmd="-hide_banner -nostats",
            stderr_pipe=True,
            stdout_pipe=False,
        )
        if not opened:
            _LOGGER.error("Failed to open ffmpeg stream")
            return False

        _LOGGER.info(
            "[%s] Started stream process - PID %d",
            session_info["id"],