WebThingsIO / onvif-adapter

ONVIF Profile S video camera adapter
Mozilla Public License 2.0
10 stars 6 forks source link

Failed to initialize device #4

Open atirage opened 5 years ago

atirage commented 5 years ago

I'm getting the following error while loading a configured camera:

INFO   : onvif: Opening database: /home/pi/.mozilla-iot/config/db.sqlite3
INFO   : onvif: Loading add-on for onvif-adapter from /home/pi/.mozilla-iot/addons/onvif-adapter
ERROR  : onvif: TypeError: profiles.forEach is not a function
ERROR  : onvif:     at Camera.parseProfiles (/home/pi/.mozilla-iot/addons/onvif-adapter/node_modules/onvif-nvt/lib/camera.js:645:14)
ERROR  : onvif:     at media.getProfiles.then.results (/home/pi/.mozilla-iot/addons/onvif-adapter/node_modules/onvif-nvt/lib/camera.js:631:34)
ERROR  : onvif:     at <anonymous>
ERROR  : onvif:     at process._tickCallback (internal/process/next_tick.js:189:7)
ERROR  : onvif: TypeError: profiles.forEach is not a function
ERROR  : onvif:     at Camera.parseProfiles (/home/pi/.mozilla-iot/addons/onvif-adapter/node_modules/onvif-nvt/lib/camera.js:645:14)
ERROR  : onvif:     at media.getProfiles.then.results (/home/pi/.mozilla-iot/addons/onvif-adapter/node_modules/onvif-nvt/lib/camera.js:631:34)
ERROR  : onvif:     at <anonymous>
ERROR  : onvif:     at process._tickCallback (internal/process/next_tick.js:189:7)
ERROR  : onvif: Failed to initialize device at undefined: TypeError: profiles.forEach is not a function

The camera is Pi camera made ONVIF compatible using https://github.com/BreeeZe/rpos.

mrstegeman commented 5 years ago

I'm sorry to hear you're having issues. It looks like there is an error in the connect() function in the onvif-nvt library. Could you file an issue there? This adapter doesn't interact with the camera at all until connect() finishes.

https://github.com/hawkeye64/onvif-nvt

atirage commented 5 years ago

Will do, thanks for the reply.

mrstegeman commented 5 years ago

References https://github.com/hawkeye64/onvif-nvt/issues/12

atirage commented 4 years ago

I've made some progress on this issue and now I can add my device in the Things GUI, but even before I open it, the log shows the following error:

INFO : onvif-adapter: !!!!!!!!!!!!!! INFO : onvif-adapter: http://192.168.0.178:8081/onvif/device_service INFO : onvif-adapter: !!!!!!!!!!!!!! INFO : getValue for property streamActive for: PI returning false INFO : getValue for property profile for: PI returning CurrentProfile INFO : getValue for property highQuality for: PI returning false INFO : onvif-adapter: Unhandled Rejection ERROR : onvif-adapter: { Error: connect ECONNREFUSED 192.168.0.178:80 ERROR : onvif-adapter: at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14) ERROR : onvif-adapter: errno: 'ECONNREFUSED', ERROR : onvif-adapter: code: 'ECONNREFUSED', ERROR : onvif-adapter: syscall: 'connect', ERROR : onvif-adapter: address: '192.168.0.178', ERROR : onvif-adapter: port: 80 }

Here the obvious observation is that the port is incorrectly showing 80 as I configured it as 8081. @mrstegeman, I'm not able to find the reference to this connect call, since it doesn't seem to be the one from onvif-nvt . Could you please give me some hints to debug this issue? Thanks!

mrstegeman commented 4 years ago

I wonder if you might have multiple devices configured. In the UI, navigate to Settings -> Add-ons, then click Configure on the ONVIF entry and see if you have multiple entries for that IP address.

atirage commented 4 years ago

Unfortunately not, at least in the GUI I have only one device, the one on port 8081.

mrstegeman commented 4 years ago

Hmm, ok. I wish that stack trace was bigger.

The adapter never chooses port 80 on its own, at least not that I'm aware of. The URLs are all pulled directly from the SSDP broadcast on the ONVIF XML data that the device returns.

The next logical step would be to dump out the data from the SSDP broadcast and from the ONVIF profile. If you're interested in doing that, here are some instructions that you'll do on your RPi or wherever you're running the gateway.

  1. mkdir -p ~/.mozilla-iot/addons/onvif-adapter/.git
  2. Edit ~/.mozilla-iot/addons/onvif-adapter/lib/onvif-adapter.js.
    • Around here, add console.log(device).
  3. Edit ~/.mozilla-iot/addons/onvif-adapter/lib/onvif-device.js.
    • Around here, add console.log(info).
    • Around here, add console.log(profile).
  4. In the UI, restart the add-on by navigating to Settings -> Add-ons, click Disable, then click Enable.
atirage commented 4 years ago

I've made the changes you suggested, here's the output:

INFO   : Loading add-on: onvif-adapter
INFO   : onvif-adapter: Opening database: /home/pi/.mozilla-iot/config/db.sqlite3
INFO   : onvif-adapter: Loading add-on onvif-adapter from /home/pi/.mozilla-iot/addons/onvif-adapter
INFO   : onvif-adapter: !!!!!!!!!!!!!!
INFO   : onvif-adapter: http://192.168.0.178:8081/onvif/device_service
INFO   : onvif-adapter: !!!!!!!!!!!!!!
INFO   : onvif-adapter: { urn: 'urn:uuid:09949e91-34cb-5074-a40d-61c9423321b0',
INFO   : onvif-adapter:   name: 'PI',
INFO   : onvif-adapter:   address: '192.168.0.178',
INFO   : onvif-adapter:   service: 'http://192.168.0.178:8081/onvif/device_service',
INFO   : onvif-adapter:   hardware: 'RaspberryPI',
INFO   : onvif-adapter:   location: '',
INFO   : onvif-adapter:   types: [ 'dn:NetworkVideoTransmitter' ],
INFO   : onvif-adapter:   xaddrs: [ 'http://192.168.0.178:8081/onvif/device_service' ],
INFO   : onvif-adapter:   scopes: 
INFO   : onvif-adapter:    [ 'onvif://www.onvif.org/type/video_encoder',
INFO   : onvif-adapter:      'onvif://www.onvif.org/type/ptz',
INFO   : onvif-adapter:      'onvif://www.onvif.org/hardware/RaspberryPI',
INFO   : onvif-adapter:      'onvif://www.onvif.org/name/PI',
INFO   : onvif-adapter:      'onvif://www.onvif.org/location/' ] }
INFO   : onvif-adapter: { '$': 
INFO   : onvif-adapter:    { 'xmlns:tds': 'http://www.onvif.org/ver10/device/wsdl',
INFO   : onvif-adapter:      xmlns: 'http://www.onvif.org/ver10/device/wsdl' },
INFO   : onvif-adapter:   Manufacturer: 'RPOS Raspberry Pi',
INFO   : onvif-adapter:   Model: 'Model_B_PI_3',
INFO   : onvif-adapter:   FirmwareVersion: '2.0.4',
INFO   : onvif-adapter:   SerialNumber: '00000000bbcd405e',
INFO   : onvif-adapter:   HardwareId: '',
INFO   : onvif-adapter:   Ptz: false,
INFO   : onvif-adapter:   Hardware: 'Model_B_PI_3',
INFO   : onvif-adapter:   Name: 'RPOS Raspberry Pi' }
INFO   : onvif-adapter: { '$': 
INFO   : onvif-adapter:    { token: 'profile_token',
INFO   : onvif-adapter:      'xmlns:tt': 'http://www.onvif.org/ver10/schema' },
INFO   : onvif-adapter:   Name: 'CurrentProfile',
INFO   : onvif-adapter:   VideoSourceConfiguration: 
INFO   : onvif-adapter:    { '$': { token: 'video_src_config_token' },
INFO   : onvif-adapter:      Name: 'Primary Source',
INFO   : onvif-adapter:      UseCount: '0',
INFO   : onvif-adapter:      SourceToken: 'video_src_token',
INFO   : onvif-adapter:      Bounds: { '$': [Object] } },
INFO   : onvif-adapter:   VideoEncoderConfiguration: 
INFO   : onvif-adapter:    { '$': { token: 'encoder_config_token' },
INFO   : onvif-adapter:      Name: 'PiCameraConfiguration',
INFO   : onvif-adapter:      UseCount: '0',
INFO   : onvif-adapter:      Encoding: 'H264',
INFO   : onvif-adapter:      Resolution: { Width: '1280', Height: '720' },
INFO   : onvif-adapter:      Quality: '1',
INFO   : onvif-adapter:      RateControl: 
INFO   : onvif-adapter:       { FrameRateLimit: '25',
INFO   : onvif-adapter:         EncodingInterval: '1',
INFO   : onvif-adapter:         BitrateLimit: '10000' },
INFO   : onvif-adapter:      H264: { GovLength: '60', H264Profile: 'High' },
INFO   : onvif-adapter:      Multicast: { Address: [Object], Port: '0', TTL: '1', AutoStart: 'false' },
INFO   : onvif-adapter:      SessionTimeout: 'PT1000S' },
INFO   : onvif-adapter:   PTZConfiguration: 
INFO   : onvif-adapter:    { '$': { token: 'ptz_config_token_0' },
INFO   : onvif-adapter:      Name: 'PTZ Configuration',
INFO   : onvif-adapter:      UseCount: '1',
INFO   : onvif-adapter:      NodeToken: 'ptz_node_token_0',
INFO   : onvif-adapter:      DefaultAbsolutePantTiltPositionSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
INFO   : onvif-adapter:      DefaultAbsoluteZoomPositionSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
INFO   : onvif-adapter:      DefaultRelativePanTiltTranslationSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
INFO   : onvif-adapter:      DefaultRelativeZoomTranslationSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
INFO   : onvif-adapter:      DefaultContinuousPanTiltVelocitySpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
INFO   : onvif-adapter:      DefaultContinuousZoomVelocitySpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
INFO   : onvif-adapter:      DefaultPTZSpeed: { PanTilt: [Object], Zoom: [Object] },
INFO   : onvif-adapter:      DefaultPTZTimeout: 'PT5S' },
INFO   : onvif-adapter:   StreamUri: 
INFO   : onvif-adapter:    { Uri: { _: 'rtsp://192.168.0.178:8554/h264', '$': [Object] },
INFO   : onvif-adapter:      InvalidAfterConnect: { _: 'false', '$': [Object] },
INFO   : onvif-adapter:      InvalidAfterReboot: { _: 'false', '$': [Object] },
INFO   : onvif-adapter:      Timeout: { _: 'PT30S', '$': [Object] } },
INFO   : onvif-adapter:   SnapshotUri: 
INFO   : onvif-adapter:    { Uri: 'http://192.168.0.178:8081[object Object]',
INFO   : onvif-adapter:      InvalidAfterConnect: { _: 'false', '$': [Object] },
INFO   : onvif-adapter:      InvalidAfterReboot: { _: 'false', '$': [Object] },
INFO   : onvif-adapter:      Timeout: { _: 'PT30S', '$': [Object] } } }
INFO   : getValue for property streamActive for: PI returning false
INFO   : getValue for property profile for: PI returning CurrentProfile
INFO   : getValue for property highQuality for: PI returning false
INFO   : onvif-adapter: Unhandled Rejection
ERROR  : onvif-adapter: { Error: connect ECONNREFUSED 192.168.0.178:80
ERROR  : onvif-adapter:     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
ERROR  : onvif-adapter:   errno: 'ECONNREFUSED',
ERROR  : onvif-adapter:   code: 'ECONNREFUSED',
ERROR  : onvif-adapter:   syscall: 'connect',
ERROR  : onvif-adapter:   address: '192.168.0.178',
ERROR  : onvif-adapter:   port: 80 }

I'm not seeing anything obviously incorrect, except maybe the fact that

INFO   : onvif-adapter:   address: '192.168.0.178',

does not contain a port number.

mrstegeman commented 4 years ago

Yeah, nothing looks obviously wrong there. Can you run this on the Pi and post the output here?

sqlite3 ~/.mozilla-iot/config/db.sqlite3 \
    "SELECT value FROM settings WHERE key = 'addons.config.onvif-adapter'" | \
    python3 -m json.tool

You'll probably want to redact the username/password info.

atirage commented 4 years ago

See below:

{
    "enablePTZ": false,
    "devices": [
        {
            "address": "http://192.168.0.178:8081/onvif/device_service",
            "username": "pi",
            "password": "*******"
        }
    ]
}
mrstegeman commented 4 years ago

Just for reference while I'm looking into things, here is the data from my Foscam R2:

Device info via console.log(info)
{
  Manufacturer: 'FOSCAM',
  Model: 'R2 V5',
  FirmwareVersion: '2.71.1.73',
  SerialNumber: '00626E892658',
  HardwareId: '1.11.1.13',
  Ptz: true,
  VideoEncoder: true,
  AudiooEncoder: true,
  Hardware: 'R2 V5',
  Name: 'Foscam',
  Country: 'china'
}
Device info via console.log(device)
{
  urn: 'urn:uuid:88d87a05-d7f7-7e45-b1e9-00626E892658',
  name: 'IPC-model',
  address: '192.168.86.26',
  service: 'http://192.168.86.26:888/onvif/device_service',
  hardware: 'IPC-model',
  location: 'china',
  types: [ 'tdn:NetworkVideoTransmitter' ],
  xaddrs: [ 'http://192.168.86.26:888/onvif/device_service' ],
  scopes: [
    'onvif://www.onvif.org/type/Network_Video_Transmitter',
    'onvif://www.onvif.org/type/video_encoder',
    'onvif://www.onvif.org/type/audio_encoder',
    'onvif://www.onvif.org/hardware/IPC-model',
    'onvif://www.onvif.org/name/IPC-model',
    'onvif://www.onvif.org/type/ptz',
    'onvif://www.onvif.org/location/country/china'
  ]
}
Profile info via console.log(profile)
{
  '$': { 'xsi:type': 'tt:Profile', fixed: 'true', token: 'prof0' },
  Name: 'prof0_name',
  VideoSourceConfiguration: {
    '$': {
      'xsi:type': 'tt:VideoSourceConfiguration',
      token: 'videosource_token0'
    },
    Name: 'videosource_name0',
    UseCount: '1',
    SourceToken: 'videosource_sourcetoken0',
    Bounds: { '$': [Object] }
  },
  VideoEncoderConfiguration: {
    '$': {
      'xsi:type': 'tt:VideoEncoderConfiguration',
      token: 'videoencoder_token0'
    },
    Name: 'videoencoder_name0',
    UseCount: '1',
    Encoding: 'H264',
    Resolution: { '$': [Object], Width: '1280', Height: '720' },
    Quality: '3',
    RateControl: {
      '$': [Object],
      FrameRateLimit: '15',
      EncodingInterval: '1',
      BitrateLimit: '512'
    },
    H264: { '$': [Object], GovLength: '45', H264Profile: 'Baseline' },
    Multicast: {
      '$': [Object],
      Address: [Object],
      Port: '88',
      TTL: '10',
      AutoStart: 'true'
    },
    SessionTimeout: 'PT0S'
  },
  PTZConfiguration: {
    '$': { 'xsi:type': 'tt:PTZConfiguration', token: 'ptzconf0' },
    Name: 'ptzname0',
    UseCount: '0',
    NodeToken: 'ptz0',
    DefaultAbsolutePantTiltPositionSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
    DefaultAbsoluteZoomPositionSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
    DefaultRelativePanTiltTranslationSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
    DefaultRelativeZoomTranslationSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
    DefaultContinuousPanTiltVelocitySpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
    DefaultContinuousZoomVelocitySpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
    DefaultPTZSpeed: { '$': [Object], PanTilt: [Object], Zoom: [Object] },
    DefaultPTZTimeout: 'PT0H0M5S'
  },
  StreamUri: {
    '$': { 'xsi:type': 'tt:MediaUri' },
    Uri: 'rtsp://192.168.86.26:88/videoMain',
    InvalidAfterConnect: 'false',
    InvalidAfterReboot: 'false',
    Timeout: 'PT0S'
  },
  SnapshotUri: {
    '$': { 'xsi:type': 'tt:MediaUri' },
    Uri: 'http://192.168.86.26:88/cgi-bin/CGIProxy.fcgi?usr=XXX&pwd=XXXXXXXXX&cmd=snapPicture2',
    InvalidAfterConnect: 'false',
    InvalidAfterReboot: 'false',
    Timeout: 'PT0H0M0.005S'
  }
}
mrstegeman commented 4 years ago

And your info, cleaned up:

Device info via console.log(info)
{
  Manufacturer: 'RPOS Raspberry Pi',
  Model: 'Model_B_PI_3',
  FirmwareVersion: '2.0.4',
  SerialNumber: '00000000bbcd405e',
  HardwareId: '',
  Ptz: false,
  Hardware: 'Model_B_PI_3',
  Name: 'RPOS Raspberry Pi'
}
Device info via console.log(device)
{
  urn: 'urn:uuid:09949e91-34cb-5074-a40d-61c9423321b0',
  name: 'PI',
  address: '192.168.0.178',
  service: 'http://192.168.0.178:8081/onvif/device_service',
  hardware: 'RaspberryPI',
  location: '',
  types: [ 'dn:NetworkVideoTransmitter' ],
  xaddrs: [ 'http://192.168.0.178:8081/onvif/device_service' ],
  scopes: [
    'onvif://www.onvif.org/type/video_encoder',
    'onvif://www.onvif.org/type/ptz',
    'onvif://www.onvif.org/hardware/RaspberryPI',
    'onvif://www.onvif.org/name/PI',
    'onvif://www.onvif.org/location/'
  ]
}
Profile info via console.log(profile)
{
  '$': {
    token: 'profile_token',
    'xmlns:tt': 'http://www.onvif.org/ver10/schema'
  },
  Name: 'CurrentProfile',
  VideoSourceConfiguration: {
    '$': { token: 'video_src_config_token' },
     Name: 'Primary Source',
     UseCount: '0',
     SourceToken: 'video_src_token',
     Bounds: { '$': [Object] }
  },
  VideoEncoderConfiguration: {
    '$': { token: 'encoder_config_token' },
    Name: 'PiCameraConfiguration',
    UseCount: '0',
    Encoding: 'H264',
    Resolution: { Width: '1280', Height: '720' },
    Quality: '1',
    RateControl: {
      FrameRateLimit: '25',
      EncodingInterval: '1',
      BitrateLimit: '10000'
    },
    H264: { GovLength: '60', H264Profile: 'High' },
    Multicast: {
      Address: [Object],
      Port: '0',
      TTL: '1',
      AutoStart: 'false'
    },
    SessionTimeout: 'PT1000S'
  },
  PTZConfiguration: {
    '$': { token: 'ptz_config_token_0' },
    Name: 'PTZ Configuration',
    UseCount: '1',
    NodeToken: 'ptz_node_token_0',
    DefaultAbsolutePantTiltPositionSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
    DefaultAbsoluteZoomPositionSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
    DefaultRelativePanTiltTranslationSpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
    DefaultRelativeZoomTranslationSpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
    DefaultContinuousPanTiltVelocitySpace: 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
    DefaultContinuousZoomVelocitySpace: 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
    DefaultPTZSpeed: { PanTilt: [Object], Zoom: [Object] },
    DefaultPTZTimeout: 'PT5S'
  },
  StreamUri: {
    Uri: { _: 'rtsp://192.168.0.178:8554/h264', '$': [Object] },
    InvalidAfterConnect: { _: 'false', '$': [Object] },
    InvalidAfterReboot: { _: 'false', '$': [Object] },
    Timeout: { _: 'PT30S', '$': [Object] }
  },
  SnapshotUri: {
    Uri: 'http://192.168.0.178:8081[object Object]',
    InvalidAfterConnect: { _: 'false', '$': [Object] },
    InvalidAfterReboot: { _: 'false', '$': [Object] },
    Timeout: { _: 'PT30S', '$': [Object] }
  }
}
mrstegeman commented 4 years ago

I'm guessing the issue is this bit:

  SnapshotUri: {
    Uri: 'http://192.168.0.178:8081[object Object]',

There should not be an embedded object in that URI, so it's probably getting parsed wrong and leaving off the port.

If you edit onvif-device.js and comment out the following line, do things work?

    setInterval(this.snapshot.bind(this), SNAPSHOT_INTERVAL);
mrstegeman commented 4 years ago

I believe the URI is generated here: https://github.com/BreeeZe/rpos/blob/ebec4df2b7fad42821924b0e878589c87d2415bc/services/media_service.ts#L338

I think that config options comes from here: https://github.com/BreeeZe/rpos/blob/c91c59a3374de0e868f4366aedb058799270af17/rposConfig.json#L4

Perhaps you have an invalid configuration or something?

atirage commented 4 years ago

Thanks for the detailed analysis. If I comment out that line, the ECONNREFUSED is gone, but I'm still not able to get a live stream in the camera's GUI but there's no error message in the log. Anyway, I'll review my rpos config based on your Foscam config.

mrstegeman commented 4 years ago

Great! Glad we got one issue figured out.

Sorry if this is a silly question, but have you checked the "Streaming" box? The stream will not start until that is checked, and it will take roughly 30-60 seconds for the stream to actually start working. Also, can you make sure there is an ffmpeg process running in the background?

atirage commented 4 years ago

The following in my profile object has a different structure than yours:

StreamUri: { Uri: { _: 'rtsp://192.168.0.178:8554/h264', '$': [Object] },

so I had to make a change in the startTrancode() function:

const streamUrl = new URL(profile.StreamUri.Uri._);

I know it's not a generic solution, but I don't know the onvif standard to be able to determine if what rpos generates is a valid object or not. Anyway, the stream is not really working, best I get is an initial snapshot, which is then frozen. I can see that ffmpeg is started with:

onvif-adapter: !!!!start ffmpeg onvif-adapter: [ '-y', onvif-adapter: '-i', onvif-adapter: 'rtsp://**@192.168.0.178:8554/h264', onvif-adapter: '-fflags', onvif-adapter: 'nobuffer', onvif-adapter: '-vsync', onvif-adapter: '0', onvif-adapter: '-copyts', onvif-adapter: '-probesize', onvif-adapter: '200000', onvif-adapter: '-window_size', onvif-adapter: '5', onvif-adapter: '-extra_window_size', onvif-adapter: '10', onvif-adapter: '-use_template', onvif-adapter: '1', onvif-adapter: '-use_timeline', onvif-adapter: '1', onvif-adapter: '-remove_at_exit', onvif-adapter: '1', onvif-adapter: '-loglevel', onvif-adapter: 'quiet', onvif-adapter: '-c:v', onvif-adapter: 'libx264', onvif-adapter: '-b : v : 0', onvif-adapter: '400k', onvif-adapter: '-profile : v : 0', onvif-adapter: 'high', onvif-adapter: '-f', onvif-adapter: 'dash', onvif-adapter: '/home/pi/.mozilla-iot/media/onvif/onvif-00000000bbcd405e/index.mpd' ]

If I open the stream with VLC, everything is running smoothly.

Could this be a browser issue? I'm using Firefox 74.0.

mrstegeman commented 4 years ago

It does seem like rpos may be generating an invalid ONVIF description.

As for the streaming issue, can you try this:

  1. Make sure the "Streaming" property is checked.
  2. Try accessing your gateway locally, if you're not already, via http://gateway.local or by IP address.

A lot of stuttering and such seems to happen when accessing video streams through the tunneling service, as it's quite a large amount of traffic. You can also try playing with the "High quality" toggle.

atirage commented 4 years ago

@mrstegeman, I played around with the options(toggling "High quality", accessing locally, etc) and unfortunately this setup is pretty much unusable. ffmpeg is completely starving the CPU(checked with top), temperature goes up to ~80°C and the stream is still not continuous, only a few FPS at best. The piCamera has a nice Python module, so wouldn't be more lightweight to write an adapter/webThing for it?

mrstegeman commented 4 years ago

Yeah, the biggest issue here is that we wanted something that was web-compatible, which meant transcoding to DASH and/or HLS. Ideally, we'd be able to directly pipe the RTSP stream to the browser, but that's not really practical.

Somebody made a web thing for the Pi Camera a couple years ago: https://github.com/infincia/picamera-webthing

The custom gateway build should no longer be necessary, but the web thing code does need to be updated to take advantage of new gateway features (such as ImageProperty, VideoProperty, and enums). I'd be happy to help if you'd like, but I don't have a Pi Camera to test anything with.

atirage commented 4 years ago

Ok, thanks for the tip. I'll check that out. Btw, feel free to close the issue, I think there wasn't any issue with the gateway code itself, except for the onvif-nvt, but for that there's a PR now.

atirage commented 3 years ago

@mrstegeman, I've forked and reworked the picamera webthing project you suggested and I'm getting the following error in the gateway:

ERROR  : Error getting thing description for thing with id http---gateway.local-8900-: Error: Unable to find thing with id: http---gateway.local-8900-
    at /home/pi/mozilla-iot/gateway/build/webpack:/src/models/things.js:268:1

This comes after the WebThing has been added:

INFO   : Successfully created new thing My PiCamera Thing

From this state, if I do a GET on http://gateway.local/things/http---gateway.local-8900, I get the following:

{
  "title": "My PiCamera Thing",
  "@context": "https://iot.mozilla.org/schemas",
  "@type": ["Camera"],
  "description": "A web connected Pi Camera",
  "href": "/things/http---gateway.local-8900",
  "properties": {
    "snapshot": {
      "title": "Snapshot",
      "@type": "ImageProperty",
      "readOnly": true,
      "links": [{
        "rel": "alternate",
        "href": "/proxy/http---gateway.local-8900/home/pi/picamera-webthing/screenshots/snapshot.jpg",
        "mediaType": "image/jpeg"
      }, {
        "rel": "property",
        "href": "/things/http---gateway.local-8900/properties/snapshot"
      }]
    }
  },
  "actions": {},
  "events": {},
  "links": [{
    "rel": "properties",
    "href": "/things/http---gateway.local-8900/properties"
  }, {
    "rel": "actions",
    "href": "/things/http---gateway.local-8900/actions"
  }, {
    "rel": "events",
    "href": "/things/http---gateway.local-8900/events"
  }, {
    "rel": "alternate",
    "mediaType": "text/html",
    "href": "/things/http---gateway.local-8900"
  }, {
    "rel": "alternate",
    "href": "ws://gateway.local/things/http---gateway.local-8900"
  }],
  "layoutIndex": 6,
  "selectedCapability": "Camera",
  "iconHref": null,
  "id": "http://gateway.local/things/http---gateway.local-8900",
  "base": "http://gateway.local/",
  "securityDefinitions": {
    "oauth2_sc": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "http://gateway.local/oauth/authorize",
      "token": "http://gateway.local/oauth/token",
      "scopes": ["/things/http---gateway.local-8900:readwrite", "/things/http---gateway.local-8900", "/things:readwrite", "/things"]
    }
  },
  "security": "oauth2_sc"
}

I've noticed that there's an extra - in the id in the error message, is that expected? Could you please help me pinpoint what is the issue here? Thanks!

mrstegeman commented 3 years ago

If you go into the settings for the Web Thing add-on, is your device added there twice, with slightly different URLs?

atirage commented 3 years ago

No, I even tried to add the Thing URL manually, but nothing changed.

mrstegeman commented 3 years ago

When you add the thing manually, try putting the trailing / on the URL and see if that helps.

atirage commented 3 years ago

Actually, when I enter the URL manually, the extra - is not there in the error message any more, but the error is the same. Could you please tell me what does this error message means? I have other WebThings (one is running on the same Pi, on a different port) and I never faced this issue. I tried to look in the things.js file, but I think I'm missing some puzzle pieces to understand what's going on, especially that I don't really "speak" js. :)

mrstegeman commented 3 years ago

Could you share your web thing code with me so that I can take a look?

atirage commented 3 years ago

Sure, here's the code: https://github.com/atirage/picamera-webthing/blob/master/picamera-webthing.py Currently it just has an ImageProperty, I used the onvif adapter for reference. The overall design is the same as for my other WebThings. Let me know if you see anything. Thanks!

mrstegeman commented 3 years ago

https://github.com/atirage/picamera-webthing/pull/1

atirage commented 3 years ago

Thanks a lot, that solved the not found issue! Currently, I'm trying to figure out why I'm getting:

WARNING:tornado.access:404 GET /media/screenshots/snapshot.jpg

It happens even if I directly access the WebThing, i.e. not through the Gateway.

mrstegeman commented 3 years ago

You need to make sure your image is accessible by the web thing server, and you'll have to add a custom path. For instance, see here:

atirage commented 3 years ago

That also did the trick! Next stop: video stream. :)

atirage commented 3 years ago

@mrstegeman, regarding the video property: what are the possible values for the mediaType in the link relations, that are supported by the Gateway?

mrstegeman commented 3 years ago

For images, we should be able to render anything of the form image/*. For videos, we can render application/dash+xml, which is MPEG-DASH, as well as application/vnd.apple.mpegurl, which is HLS.

atirage commented 3 years ago

It looks like there's no way around transcoding... I've found a hint that ffmpeg is usually not compiled with HW support, so I'll try that out with the original onvif adapter: https://www.jungledisk.com/blog/2017/07/03/live-streaming-mpeg-dash-with-raspberry-pi-3/

Just as a side question, is it a complete no-go to add mjpeg support for the gateway?

mrstegeman commented 3 years ago

Actually, mjpeg looks like it would be pretty straightforward to support. I may give that a shot next week.