scottlamb / moonfire-nvr

Moonfire NVR, a security camera network video recorder
Other
1.2k stars 138 forks source link

Unable to play recording on Chrome on Android, Trendnet camera, mirrored image #197

Closed robin-thoni closed 2 years ago

robin-thoni commented 2 years ago

Describe the bug I just setup 2 instances on moonfire on two premises, w/ 2 cameras on each:

For only one of those, I can't play the main recordings. See the first video below. Firefox can play them fine on the same device. Chrome on Ubuntu can also play everything w/o any problem.

To Reproduce Not sure what's causing the issue.

Expected behavior Chrome should be able to play those recordings fine, like the others.

Screenshots

https://user-images.githubusercontent.com/9640353/154278186-56407083-6f92-43fa-9653-6f87d2bce747.mp4

Server (please complete the following information):

$ docker ps | grep moonfire
ddfdaeb31c49        scottlamb/moonfire-nvr:v0.7.1                     "/usr/local/bin/moon…"    2 days ago          Up 35 minutes           127.0.0.1:35280->8080/tcp                                                                             docker-moonfire-server_moonfire_1

$ docker images | grep moonfire
scottlamb/moonfire-nvr                          v0.7.1                  d124dc9d87cc        3 months ago        755MB

Camera (please complete the following information): Model: Trendnet TV-IP311PI Firmware Version: V5.0.1 140303 (Same for both cameras on the impacted prem)

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context

scottlamb commented 2 years ago

Hmm. I don't know what's wrong, but I have some ideas for learning more:

  1. look through the logfiles for reports of dropped frames or other problems talking with that camera
  2. see if running Moonfire with --rtsp-library=ffmpeg makes any difference. If it does, this suggests a problem in/incompatibility with my own RTSP library called Retina.
  3. try playing the video file in other players (e.g. VLC, Firefox, QuickTime) to see if they can do any better. [edit: I see you already did this.]
  4. compare that camera's settings to the working ones. Maybe even try resetting it to factory settings and see if it works then. Typically cameras have a bunch of settings that control the encoded video, and I can imagine one of them making the difference.
scottlamb commented 2 years ago

If you're willing to send me the actual video file, I'd also be happy to look and see if I can spot anything weird about it.

robin-thoni commented 2 years ago

Thanks for your quick answer!

  1. That's the only abnormal thing I can see, however, it sounds unrelated.
    moonfire_1  | W20220216 17:44:29.186 s-cam01-rt02-main moonfire_nvr::streamer] cam01-rt02-main: sleeping for PT1S after error: stream ended
    moonfire_1  | I20220216 17:44:30.179 s-cam01-rt02-sub moonfire_nvr::streamer] cam01-rt02-sub: Opening input: rtsp://cam01.lesse.rthoni.com/streaming/channels/1
    moonfire_1  | I20220216 17:44:30.186 s-cam01-rt02-main moonfire_nvr::streamer] cam01-rt02-main: Opening input: rtsp://cam01.lesse.rthoni.com/streaming/channels/1
  2. Same behavior w/ ffmpeg
  3. Yeah, as you saw, it seems to be working everywhere else
  4. The only difference I can see is it has, for some reason, variable FPS which seem to correlate w/ time: 30 during day, 15 during dawn and dusk, then 8 during night. I have no idea why. Both cameras in that prem (the two 311s) have the same settings, EXCEPT that one (the "non-working" one) has night vision disabled, exposure time set to 1/6, while the default is 1/30, and is mirrored horizontally and vertically. Screenshot from 2022-02-16 22-42-27 Screenshot from 2022-02-16 22-43-53 "non-working": Screenshot from 2022-02-16 22-47-20 "working": Screenshot from 2022-02-16 22-48-16 Screenshot from 2022-02-16 22-48-51

Here's a sample: /deleted/

scottlamb commented 2 years ago

The only difference I can see is it has, for some reason, variable FPS which seem to correlate w/ time:

That sort of makes sense. The frame rate can't exceed the inverse of the exposure time (1/6 s => 6 fps), or you'd get duplicate frames. I guess the configured exposure time must be an upper bound and the camera decreases it when there's enough light, allowing the frame rate to be higher. The other cameras presumably are switching into night mode before letting the exposure time get long enough to limit the frame rate.

I don't know why the difference in frame rate would break playback on mobile Chrome, but you might try temporarily making it match the other cameras and see if that's it or not.

edit: in fact, I'd disable the mirroring thing, too, to rule out everything.

Here's a sample:

No smoking gun jumps out at me, but I see it too. Playback of this file doesn't work on my phone either (Pixel 6 with Chrome 98.0.47568.101). No logs on console or anything; that'd be too helpful.

I've had problems before where one client didn't like some quirk of how Moonfire writes the .mp4 container format (478323e comes to mind) so I tried re-muxing its H.264 into a fresh .mp4 file with ffmpeg and gpac:

Those files wouldn't play either.

Maybe the H.264 parameters in the file promise a fixed 30 fps and Chrome is upset that it's lying. I don't see an easy way to dump the full parameters with ffmpeg or gpac. I could write a tool to pull them out and feed them into the h264-reader crate to get the full dump if we run out of other ideas.

If you grab a .mp4 file from this camera with say ffmpeg, does it work? e.g. ffmpeg -fflags nobuffer -rtsp_transport tcp -t 30 -i 'rtsp://user:pass@camera.ip/path' -c copy direct-with-ffmpeg.mp4

scottlamb commented 2 years ago

btw, I wouldn't recommend an exposure time that long anyway. I'd think anything moving would be too blurry to be recognizable.

robin-thoni commented 2 years ago

btw, I wouldn't recommend an exposure time that long anyway. I'd think anything moving would be too blurry to be recognizable.

Unfortunately, the placement of the camera makes the IR completely useless, so I have to keep it on day mode all time and rely on public lights, but with 1/30, it just doesn't get enough light, but w/ 1/6, it's okay-ish. I just compared day vs night recordings, and you're right, it's 30 FPS no blurry on day, and low FPS blurry on night. I'll see what I can do... Thanks for the advice!

If you grab a .mp4 file from this camera with say ffmpeg, does it work?

I just realized the camera has an FPS settings, set by default to 30. I tried w/:

None of this worked. Chrome still flashes the play logo and nothing plays. I'll try in the following days to set to 1/30, 30 FPS and reboot the camera, just in case...

scottlamb commented 2 years ago

None of this worked. Chrome still flashes the play logo and nothing plays. I'll try in the following days to set to 1/30, 30 FPS and reboot the camera, just in case...

Did you make any progress? I want to make my own RTSP library Retina fully obsolete ffmpeg in Moonfire NVR, so I'm eager to figure out out for any camera incompatibilities like this that may be Retina bugs.

robin-thoni commented 2 years ago

I've just setup the camera w/ fixed 6 FPS; 1/30 and rebooted the camera. Same result on Android.

I completely reset the camera, and it worked fine after. I then proceeded to put back custom parameters one by one, and the guilty one is the horizontal/vertical mirror. Setting it, restarting moonfire and trying to play on Android makes it crash, as described above. Reseting mirror to default and restarting moonfire makes it work again. Even playing w/ FPS and exposure time has no impact at all. Are you interested in working and non-working samples?

scottlamb commented 2 years ago

Are you interested in working and non-working samples?

Yes. I'm not sure I'll be able to fix that (might just be a Chrome-on-Android bug), but I'm happy to take a look.

robin-thoni commented 2 years ago

Here they are: https://owncloud.rthoni.com/s/Cr2XyJbxZbNy78p Us6UtZWvCYd9dspBfGdM. But yeah, that sounds like a Chrome bug... Feel free to close.

Anyway, thanks for your support!

scottlamb commented 2 years ago

I took a look but don't have any ideas to fix it in Moonfire NVR. :-( I'm indeed going to close this. But if you can find any software that can successfully go from camera with this option set to a video file that Chrome-on-Android can play [edit: without the CPU cost of completely re-encoding the H.264], I'm happy to try to figure out how.

Here's what I do know:

Your experimentation seems pretty conclusive in that there's an incompatibility between your camera's mirror option and Chrome on Android. (and iirc Chrome on Android is based on different AV libraries than Chrome on desktop platforms so that makes some sense.) But I'm not even sure which is at fault:

I took a look at the H.264 data and didn't see much. There's a small difference in the video parameters (SPS). H.264 video streams are always multiples of 16x16 and then (when the stream is supposed to be an uneven size) cropped down. One says to crop at the top, the other to crop at the bottom. I wouldn't expect this difference to be significant. I don't see any difference in the video slice headers. I don't know H.264 well enough to dig into the content of the video slices.

robin-thoni commented 9 months ago

For the record, I just filled a Chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1487267