motioneye-project / motioneye

A web frontend for the motion daemon.
GNU General Public License v3.0
4.01k stars 662 forks source link

MJPEG netcam is always shown in 640x480 #2693

Open kingkingyyk opened 1 year ago

kingkingyyk commented 1 year ago

motioneye/extra/linux_init always install latest motion, but motioneye doesn't necessarily support it.

For example, in 4.4.0 introduced new configuration options that causes this issue where motion doesn't support writing the new configuration yet.

MichaIng commented 1 year ago

motionEye does support motion v4.4, which is why this change was done: https://github.com/motioneye-project/motioneye/pull/2462

Did you run into any specific issue with latest motion and motionEye? Probably we missed migration for a specific config key.

kingkingyyk commented 1 year ago

I have 1920x1080 mjpeg stream added via Network Camera, but the preview / video from motion becomes 640x480. This issue is not reproducible with 4.3.2

MichaIng commented 1 year ago

You mean a simple MJPEG stream? That is not passed through motion at all, is it? Or do you mean an RTSP or RTMP stream? In this case you should be able to use the resolution option in camera settings.

Do you use custom motion arguments? We just internally translate those which are used by the options in UI, while for custom parameters you need to assure those do match the motion version.

Lastly, does motion, if used at all for this stream, report any warning about unknown config keys?

kingkingyyk commented 1 year ago
MichaIng commented 1 year ago

Does the URL to the network camera start with rtsp:// or rtmp://? Because only in this case the width/height from the resolution input is used, otherwise it is ignored (not sure whether still displayed?). This is and was the same, regardless which motion version is used. See here:

If I see it right, the resolution is not set anywhere for netcams with other URL schemes. Can you show the related camera config?

cat /etc/motioneye/camera-1.conf

Adjust the number to match the netcam. And if you find time, doing the same with motion v4.3.2 would be great.

kingkingyyk commented 1 year ago

It starts with HTTP.

This is how it looks like in v4.3.2

threshold_maximum 0
stream_quality 40
threshold 30720
noise_level 31
smart_mask_speed 0
pre_capture 10
movie_codec mp4:h264_omx
noise_tune on
stream_maxrate 25
netcam_url http://172.17.0.1:8764/
stream_localhost on
text_changes on
movie_filename %Y-%m-%d/%H-%M-%S
movie_max_time 30
lightswitch_percent 50
movie_passthrough off
auto_brightness off
stream_port 8081
rotate 0
stream_auth_method 0
threshold_tune off
framerate 20
emulate_motion off
movie_output off
picture_quality 50
snapshot_filename %Y-%m-%d/%H-%M-%S
despeckle_filter
snapshot_interval 0
minimum_motion_frames 5
stream_motion off
target_dir /var/lib/motioneye/Camera1
movie_output_motion off
post_capture 10
on_picture_save /usr/local/lib/python3.9/dist-packages/motioneye/scripts/relayevent.sh "/etc/motioneye/motioneye.conf" picture_save %t %f
on_movie_end /usr/local/lib/python3.9/dist-packages/motioneye/scripts/relayevent.sh "/etc/motioneye/motioneye.conf" movie_end %t %f
text_left Camera1
picture_output_motion off
picture_filename %Y-%m-%d/%H-%M-%S
text_scale 4
locate_motion_style redbox
locate_motion_mode on
netcam_keepalive off
movie_quality 50
picture_output on
on_event_end /usr/local/lib/python3.9/dist-packages/motioneye/scripts/relayevent.sh "/etc/motioneye/motioneye.conf" stop %t
text_right %Y-%m-%d\n%T
on_event_start /usr/local/lib/python3.9/dist-packages/motioneye/scripts/relayevent.sh "/etc/motioneye/motioneye.conf" start %t
camera_name Camera1
event_gap 10
netcam_tolerant_check on
mask_file
MichaIng commented 1 year ago

So as expected no resolution/width/height is defined at all. With motion 4.5.1, when accessing the stream directly at port 8081 has 640x480 resolution applied as well, or is it full HD there?

kingkingyyk commented 1 year ago

It is 640x480, downsized from full HD, so the image looks compressed horizontally as the aspect ratio becomes tighter.

MichaIng commented 1 year ago

Then it seems to be a bug in motion itself, since the config does not enforce any resolution. In this case I'd expect it to show the stream unmodified. Reading the docs, however, it seems the default is (now) 640x480 and enforced for the output stream, even if the original stream has a different resolution and is not actually rescaled: https://motion-project.github.io/motion_config.html#width

This seems dumb to me. The default, if nothing enforced, should be the input stream. Can you test with motion v4.4 to narrow down here the change happened? https://github.com/Motion-Project/motion/releases/tag/release-4.4.0

If this is somehow a wanted change, we'd need to expose the width/height setting for all camera types, but in case of a netcam stream obtain the original resolution and apply this when the camera is created (as default). But I'm not sure how to obtain the original resolution.

kingkingyyk commented 1 year ago

I've actually tested on 4.4.0 as well, it does have the same issue. It should be easy to obtain the resolution by just reading a single frame the moment the stream url is added, but if someone decided to change the source without readding, then the resolution would remain unchanged.

MichaIng commented 1 year ago

I've actually tested on 4.4.0 as well, it does have the same issue.

Okay, good to know. There is an issue/discussion about this, older than motion 4.4: https://github.com/Motion-Project/motion/discussions/1489 It actually sounds like auto-detection is already done if no "global values" are defined. Indeed the default /etc/motion/motion.conf does (and also did with motion 4.3.2) contain 640x480 as default values. motionEye uses its own config at /etc/motioneye/motion.conf. Currently not sure whether this sets width/height as well. If it does, a test would be to remove those and check whether the stream then has original size. The question remains why this changed with motion 4.4 since width/height values are obtained and applied by motionEye independent of the motion version.

by just reading a single frame the moment the stream url is added

Indeed, I mean that my Python and PIL knowledge is insufficient to know how to implement this. Would require some spare time to look into the code. I think the code around the masks already does this, so could be reused as basis to obtain and measure dimensions of a single frame when adding a new netcam.

I will test a bit as well so see what we can do our end and collect all info required to do a proper report at the motion repo.

kingkingyyk commented 1 year ago

motionEye writes a config file to /etc/motioneye/camera-1.conf and gets motion to read from the file, so I think the default /etc/motion/motion.conf should not be affecting.

Let's see if I can manage to do a pull request on this matter.

MichaIng commented 1 year ago

It creates an /etc/motioneye/motion.conf (within "motioneye" config dir, no "motion" config dir) as well, isn't it?

kingkingyyk commented 1 year ago

Indeed, and it doesn't contain resolution related config on my side. After all, it doesn't sound right to have the config here since we might be dealing with streams with different resolution.

MichaIng commented 1 year ago

After all, it doesn't sound right to have the config here since we might be dealing with streams with different resolution.

Okay, so motionEye does not enforce the 640x480 via its global and individual netcam configs. With motion 4.3.2 in this case, auto-detection seemed to have worked, since motion 4.4 it enforces 640x480 regardless, which actually matches the documentation. Also the v4.3.2 documentation says that 640x480 is the default and that motion tries to resize the output image (even without rescaling). Both docs match 100% for these settings: https://motion-project.github.io/4.3.2/motion_config.html#width

Now I see another section:

The changelog says: https://github.com/Motion-Project/motion/releases/tag/release-4.4.0

Change default processing for http cameras.

The docs have been changed here: https://github.com/Motion-Project/motion/pull/1367/files The code changes' result is that previously a http URL lead to CAMERA_TYPE_NETCAM being assigned, now it is CAMERA_TYPE_RTSP. In netcam.c, http has been removed, but not sure whether it is translated internally.

I think it has to do something with whether FFmpeg is used or not.

MartinLenord commented 11 months ago

I came across this issue and have come to somewhat of a workaround with a slight drawback.

tldr; set the netcam_high_url

My setup is that I have a bunch (5) of raspberry pi zero 2s with pi v3 cameras running motioneye, but only outputting a stream, not saving any data or doing any motion detection. Then I have a single raspberry pi 5 acting as a hub, running motioneye with all the pi zeros as netcams. I was seeing the same behaviour, all the pi zeros were streaming at 1024x768, but the hub was only processing the streams at 640x480. I was looking at the documentation posted above and noticed the netcam_high_url https://motion-project.github.io/motion_config.html#netcam_high_url The parameter is described as:

The network camera high resolution URL used in conjunction with the netcam_url parameter. Users may specify the normal resolution in the netcam_url and that will be used for the motion detection and then specify the high resolution url for this parameter.

This sounds like basically what we want, a high resolution version of the stream. The first drawback being:

Motion detection on the normal resolution will trigger the saving of images from the high resolution stream. Note that the ONLY overlay that will be present on the resulting high resolution pictures and movies is the privacy mask. The other overlays such as date/time, motion boxes, camera name, etc will not be included.

This is a bit of a pain, but not the end of the world with the setup I have, as I can simply add the name/time overlay on each of my zeros before the stream is passed to the hub. This may be a deal breaker for other setups.

The other drawback is:

If the netcam_url is not specified, this option is ignored.

Meaning there is no option to only set a high res url and the preview will continue to be 640x480 but recorded video is my full stream resolution.

Either way it's better than what I had before if still not perfect. To get it working I just added:

netcam_high_url http://<camera-ip>:9081/
netcam_high_params keepalive = on,tolerant_check = on

Hope this helps a little

zeekblitz commented 3 months ago

@MartinLenord Hi, I have a very similar setup as yours and have run into this issue. I am wondering where exactly should I add the two lines you provided, and do you have to add them for each camera stream?

MartinLenord commented 3 months ago

Hey @zeekblitz, you have to add the config to each camera configuration on the hub that is consuming the streams (in my case my RPi 5). You can either add it directly to each /etc/motioneye/camera-X.conf file, or through the motioneye interface for each camera go to Video Device -> Extra Options and paste the two lines in there

mark4mike commented 4 weeks ago

@kingkingyyk I was able to get the resolution to display correctly on the dashboard of my motioneye "hub" from a MJPEG network cam by just specifying the height and width parameters in the Extra Options field for the added camera.

So in my case, I have a couple Raspberry Pi Zero 2 Ws with Arducam 12MP IMX708 Module 3 cameras and a Raspberry Pi 4B as the hub. When adding the Zeros as network cams, the dashboard always had the resolution defaulted down. I have them set at 1280x720 resolution so in the Extra Options field on the hub dashboard for that camera I just added:

height 720
width 1280

Which after applying made the dashboard stream preview the correct resolution.