Stream Component: Confirmed Cameras and Configurations

This is the plugin I used that was able to get my camera streams up and running: GitHub - gihad/streamer: Converting Streams into HLS for playback on Chromecast devices using FFMPEG + NGINX

Thanks but my understanding is this exactly what the stream component should be doing. From Stream - Home Assistant

The integration currently only supports proxying H.264 source streams to the HLS format and requires at least FFmpeg >= 3.2.

One thing I realized might be an issue is I have an nginx reverse proxy, protected by oauth, in front of my Home Assistant instance. Im guessing the chromecast may be hitting Home Assistant to get the stream and failing due to requiring oauth. However, there is no documentation of what endpoints its needs. I “unprotected” /api/hls/ which it seems to use to provide the stream, but it still isnt working.

Does anyone else have oauth in front of their Home Assistant and successfully using streams? Would you mind sharing your nginx config if so?

hello
i have a escam g02… i cannot make PTZ work with HA but it works with all the apps available on internet.
how can i discover the commands to make ptz work on HA?
thanks a lot

After more research and experimenting, I don’t think the proxy is the issue. I configured ngnix to allow all traffic from my local networks but the behavior is still the same.

I’m going to have to give up on this feature unless someone can provide guidance on how to debug. I still am seeing nothing in the logs

hello
someone had apparently made escam G02 with the following script
how can it be adapted for homeassistant?

# ==========================================================================
#
# ZoneMinder IPCAM2MP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0003 $
# Copyright (C) 2001-2008  Philip Coombes
#
# Modified for China 2MP NetIpCam camera by Radmilo Feliox n 2015-05-05 00:03:00
# Modified for ESCAM G02 / IPCAMERA / C9F0SeZ0N0P2L0 / FW: V9.1.6.1.24-20170925 BY PETER ZARGLIS n 2018-06-09 13:45:00
# For more information/cgi-bin commands see https://www.themadhermit.net/wp-content/uploads/2013/03/FI9821W-CGI-Commands.pdf
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the China 2MP NetIpCam camera
# control protocol.
#
# ==========================================================================
package ZoneMinder::Control::IPCAM2MP;

use 5.006;
use strict;
use warnings;

require ZoneMinder::Base;
require ZoneMinder::Control;

our @ISA = qw(ZoneMinder::Control);

our $VERSION = $ZoneMinder::Base::VERSION;

# ==========================================================================
#
# China 2MP NetIpCam Control Protocol
#
# ==========================================================================

use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );

my $loopfactor=100000;

sub new
{
    my $class = shift;
    my $id = shift;
    my $self = ZoneMinder::Control->new( $id );
    my $logindetails = "";
    bless( $self, $class );
    srand( time() );
    return $self;
}

our $AUTOLOAD;

sub AUTOLOAD
{
    my $self = shift;
    my $class = ref($self) || croak( "$self not object" );
    my $name = $AUTOLOAD;
    $name =~ s/.*://;
    if ( exists($self->{$name}) )
    {
    return( $self->{$name} );
    }
    Fatal( "Can't access $name member of object of class $class" );
}

sub open
{
    my $self = shift;

    $self->loadMonitor();

    use LWP::UserAgent;
    $self->{ua} = LWP::UserAgent->new;
#    $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION );
    $self->{ua}->agent( "ZoneMinder Control Agent" );


    $self->{state} = 'open';
}

sub close
{
    my $self = shift;
    $self->{state} = 'closed';
}

sub sendCmd
{
    my $self = shift;
    my $cmd = shift;
    my $result = undef;
    my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
    my $res = $self->{ua}->request($req);
    if ( $res->is_success )
    {
        $result = $res->decoded_content;
    }
    else
    {
        Error( "Error check failed: '".$res->status_line()."'" );
    }
    return( $result );
}

# Reboot camera
sub reset
{
    my $self = shift;
    Debug( "Camera Reset" );
    my $cmd = "cgi-bin/hi3510/sysreboot.cgi";
    $self->sendCmd( $cmd );
}

# Flip image on vertically
sub wake
{
    my $self = shift;
    Debug( "Flip on" );
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-flip=on";
    $self->sendCmd( $cmd );
}


# Flip image off vertically
sub sleep
{
    my $self = shift;
    Debug( "Flip off" );
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-flip=off";
    $self->sendCmd( $cmd );
}

sub moveConUp
{
    my $self = shift;
    my $params = shift;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
    else
    {
    $self->moveStop( $params );
    }
}

sub moveConDown
{
    my $self = shift;
    my $params = shift;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
    else
    {
    $self->moveStop( $params );
    }
}

sub moveConRight
{
    my $self = shift;
    my $params = shift;
    Debug( "Move Right" );
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
    else
    {
    $self->moveStop( $params );
    }
}

sub moveConLeft
{
    my $self = shift;
    my $params = shift;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
    $self->sendCmd( $cmd );
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        usleep( $self->{Monitor}->{AutoStopTimeout} );
        $self->moveStop( $params );
    }
    else
    {
    $self->moveStop( $params );
    }
}

# The camera can not move diagonally, so we will implement those movements in the next 4 subroutines:
sub moveConUpLeft
{
    my $self = shift;
    my $params = shift;
    my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        while ( $loopcount  )
        {
             $loopcount--;
             my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
             $self->sendCmd( $cmd );
             my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
             $self->sendCmd( $cmd );

         }
        $self->moveStop( $params );
    }
}

sub moveConUpRight
{
   my $self = shift;
   my $params = shift;
   my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
   my $autostop = $self->getParam( $params, 'autostop', 0 );
   if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
   {
         while ( $loopcount  )
         {
             $loopcount--;
             my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=up";
             $self->sendCmd( $cmd );
             my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
             $self->sendCmd( $cmd );
         }
            $self->moveStop( $params );
  }
}

sub moveConDownRight
{
    my $self = shift;
    my $params = shift;
    my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        while ( $loopcount  )
        {
            $loopcount--;
            my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
            $self->sendCmd( $cmd );
            my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=right";
            $self->sendCmd( $cmd );
        }
        $self->moveStop( $params );
    }
}

sub moveConDownLeft
{
    my $self = shift;
    my $params = shift;
    my $loopcount=int($self->{Monitor}->{AutoStopTimeout}/$loopfactor);
    my $autostop = $self->getParam( $params, 'autostop', 0 );
    if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
    {
        while ( $loopcount  )
        {
            $loopcount--;
            my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=down";
            $self->sendCmd( $cmd );
            my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=left";
            $self->sendCmd( $cmd );
        }
        $self->moveStop( $params );
    }
}

sub moveStop
{
    my $self = shift;
    print("autostop\n");
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=ptzctrl&-step=0&-speed=10&-act=stop";
    $self->sendCmd( $cmd );
}

sub getDisplayAttr
{
    my $self = shift;
    my $param = shift;
    my $cmdget = "cgi-bin/hi3510/param.cgi?cmd=getvdisplayattr&-brightness";
    my $resp = $self->sendCmd( $cmdget );
    my @buffer=split(';',$resp);
    my $response=$buffer[$param];
    my @buffer=split('"',$response);
    my $response=$buffer[1];
    return ($response);
}

# presetHome is used to normalize the brightness/contrast/hue/saturation values
sub presetHome
{
    my $self = shift;
    Debug( "Home Preset" );
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=50&-contrast=50&-saturation=50&-hue=50";
    $self->sendCmd( $cmd );
}

sub presetSet
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Set Preset $preset " );
    my $cmd = "cgi-bin/hi3510/preset.cgi?-act=set&-status=1&-number=$preset";
    $self->sendCmd( $cmd );
}

sub presetGoto
{
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Goto Preset $preset" );
    my $cmd = "/cgi-bin/hi3510/preset.cgi?-act=goto&-number=$preset";
    $self->sendCmd( $cmd );
}

# Contrast control
sub whiteAbsIn
{
    my $self = shift;
    my $params = shift;
    Debug( "Contrast up" );
    my $dvalue=$self->getDisplayAttr(6);
    if ( $dvalue < 100 )
    {
    $dvalue=$dvalue+5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-contrast=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Contrast control
sub whiteAbsOut
{
    my $self = shift;
    my $params = shift;
    Debug( "Contrast down" );
    my $dvalue=$self->getDisplayAttr(6);
    if ( $dvalue > 0 )
    {
    $dvalue=$dvalue-5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-contrast=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Brightness control
sub irisAbsOpen
{
    my $self = shift;
    my $params = shift;
    Debug( "Brightness up" );
    my $dvalue=$self->getDisplayAttr(4);
    if ( $dvalue < 100 )
    {
    $dvalue=$dvalue+5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Brightness control
sub irisAbsClose
{
    my $self = shift;
    my $params = shift;
    Debug( "Brightness down" );
    my $dvalue=$self->getDisplayAttr(4);
    if ( $dvalue > 0 )
    {
    $dvalue=$dvalue-5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-brightness=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Saturation control
sub zoomAbsTele
{
    my $self = shift;
    my $params = shift;
    Debug( "Saturation up" );
    my $dvalue=$self->getDisplayAttr(5);
    if ( $dvalue < 100 )
    {
    $dvalue=$dvalue+5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-saturation=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Saturation control
sub zoomAbsWide
{
    my $self = shift;
    my $params = shift;
    Debug( "Saturation down" );
    my $dvalue=$self->getDisplayAttr(5);
    if ( $dvalue > 0 )
    {
    $dvalue=$dvalue-5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-saturation=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Hue control
sub focusAbsNear
{
    my $self = shift;
    my $params = shift;
    Debug( "Hue up" );
    my $dvalue=$self->getDisplayAttr(7);
    if ( $dvalue < 100 )
    {
    $dvalue=$dvalue+5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-hue=$dvalue";
    $self->sendCmd( $cmd );
    }
}

# Hue control
sub focusAbsFar
{
    my $self = shift;
    my $params = shift;
    Debug( "Hue down" );
    my $dvalue=$self->getDisplayAttr(7);
    if ( $dvalue > 0 )
    {
    $dvalue=$dvalue-5;
    my $cmd = "cgi-bin/hi3510/param.cgi?cmd=setvdisplayattr&-hue=$dvalue";
    $self->sendCmd( $cmd );
    }
}

1;

I have a bunch of these errors to. Did you manage to understand what they are. Do they affect HASS?

It’s awesome that the “stream” component allows live streaming and visibility to Chromecasts and Google Smart Displays, however when it enabled it crashes my Home Assistant.

This problem appears widespread based on the thread below. Any ideas for a fix?

nope. see 0.92.2 locks up? and then https://github.com/home-assistant/home-assistant/issues/22999 and then https://github.com/MagicStack/uvloop/issues/118 - assuming this the same underlying issue, there is no fix as yet.

Same issue as @Peter_Iliev and @Fernando_Castro but i am using 2 different brand camera’s.
"google cast blue icon changed and a blue vertical bar started to move. However, I never see anything. "
VLC and HA just working fine, but no stream in google chromecast. using the chromecast 4k.

Running four cameras; back garden, side entrance, front drive & porch.
I’ve currently also got all four cameras running through MotionEye with motion detection, with plans at a later date to use the stream from MotionEye with this component (however first attempts were unsuccessful and haven’t got around to playing with it again).

CPU load idles at around 2.0-2.4 on an AMD Turion II Neo N40L Dual Core with 4GB RAM. (Looking at upgrading, but there’s also a bit of a clean up on the server needed.)

I got the cameras to show in Front end of HA, with 10 second screen update. How did you present yours? I click and get nothing.

Also everytime I ask Google for the stream it keeps saying its not available, I can see the device in the list of google home devices though

I was originally using the Lovelace picture entity as below (commented out now as I’m now using MotionEye):

#      - type: picture-entity
#        title: Porch
#        entity: camera.porch_ffmpeg
#      - type: picture-entity
#        title: Front Drive
#        entity: camera.front_drive_ffmpeg
#      - type: picture-entity
#        title: Rear Garden
#        entity: camera.rear_garden_ffmpeg
#      - type: picture-entity
#        title: Side Entrance
#        entity: camera.side_entrance_ffmpeg

This would provide a screenshot of the camera that would periodically update.
Clicking this would bring up the livestream and the option to pre-load the stream for quicker switchover to the livestream. Normally takes a couple of seconds to load the livestream.

As for Google streaming, I’ve exposed them via Nabu Casa and then added them in Google Home to the relevant rooms. I ask the Google Home Hub to “show me the porch camera” and after a few seconds it pops up.

For live streaming you need to add your camera using Lovelace picture entity.

Hello to all
can this camera be used with HA and zigbee2mqtt?
Xiaomi Aqara 1080 P

thanks a lot

zigbee2mqtt: zigbee
Xiaomi Agara camera = wifi

It has nothing to do with each other, so I don’t know why it would not work?

because this camera is wifi with zigbee hub included

hello what cameras are working with homeassistant from Xiaomi?

I experienced exactly this issue with hassio on a tinkerboard s and also later in a virtualbox install. I removed stream: and it has been rock solid since then. I won’t be adding the stream: option back to my config until I see a specific confirmation of a fix in a future release. I rely on hassio too much for the heating system, security, lights etc to risk it hanging every 0.5 to 4 days.

I have been away for a while but would like to revisit this project. Has anyone been able to stream a Blue Iris h264 feed to a Chromecast device using the generic camera component and HA HLS stream?

I made it work once, but it was extremely unstable and like the post above yours kept crashing/hanging homeassistant.

Thanks for your reply. I’ll keep an eye on this thread and future HA releases. It would be nice to have a homemade camera stream to Chromecast without replacing perfectly good Hikvision cameras with Nest cameras