janusw / Camera.Maui

A CameraView Control for .NET Maui
MIT License
18 stars 3 forks source link

It would be ideal to have available the FPS and Bitrate parameters to be configured #8

Closed tpgalan closed 7 months ago

tpgalan commented 8 months ago

At least in Android, FPS and Bitrate is fixed by default:

mediaRecorder.SetVideoEncodingBitRate(10000000); mediaRecorder.SetVideoFrameRate(30);

This means FPS is set to 30 and Bitrate is set to be something unrealistic. Is there any way to have the supported FPS/Bitrate parameters by the camera before start recording or selecting the device?

janusw commented 7 months ago

At least in Android, FPS and Bitrate is fixed by default:

mediaRecorder.SetVideoEncodingBitRate(10000000); mediaRecorder.SetVideoFrameRate(30);

This means FPS is set to 30 and Bitrate is set to be something unrealistic.

Well, 10Mbps is rather high, but not necessarily unrealistic. Strongly depends on the resolution etc. This page lists 10Mbps as the recommended bitrate for 1080p resolution with the VP8 codec: https://developer.android.com/media/platform/supported-formats

Is there any way to have the supported FPS/Bitrate parameters by the camera before start recording or selecting the device?

For the FPS, this might do it: https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES

The bitrate, I suppose, is not so much a camera property, but rather depends on the codec, see e.g.: https://developer.android.com/reference/android/media/MediaCodecInfo.VideoCapabilities#getBitrateRange()

janusw commented 7 months ago

One could certainly make these things parameters of StartRecordingAsync:

Would that help you?

(I'm not sure if I have the time to look into this myself anytime soon, but if someone is willing to prepare a PR for this, I could certainly review it.)

mancda commented 7 months ago

That would be very helpful. Could I pay you to add these params to your fork? BTW thanks for fixing the permissions problem on newer versions of Android. :)

tpgalan commented 7 months ago

One could certainly make these things parameters of StartRecordingAsync:

  • the format
  • the frame rate
  • the bitrate

Would that help you?

(I'm not sure if I have the time to look into this myself anytime soon, but if someone is willing to prepare a PR for this, I could certainly review it.)

That would be great, but it will be needed a method to retrieve the available resolutions and available FPS outside the CameraView element. For now, only is supported the available resolutions, but it needs to be combined with the FPSs if it is something fixed. When I was debugging from @hjam40 repo, I noticed there was no effect on the mediaRecorder.SetVideoFrameRate(30);

Anyway, StartRecordingAsync using these parameters will be great! And even having the resolution as an optional parameter. CameraView knows from its Camera property what available resolutions are admitted.

Just some ideas...

Thanks!

janusw commented 7 months ago

Could I pay you to add these params to your fork?

That might possibly increase my motivation to implement this :) (let's discuss this in private)

BTW thanks for fixing the permissions problem on newer versions of Android. :)

You're welcome, but actually the fix was contributed by someone else (I only reviewed and merged it) 😉

janusw commented 7 months ago

When I was debugging from @hjam40 repo, I noticed there was no effect on the mediaRecorder.SetVideoFrameRate(30);

What do you mean? You get a different frame rate, although you request 30 fps? Or you get 30 fps anyway, even if you don't specify it?

Anyway, StartRecordingAsync using these parameters will be great! And even having the resolution as an optional parameter.

An optional resolution parameter already exists, right?

mancda commented 7 months ago

<That might possibly increase my motivation to implement this :) (let's discuss this in private>

Thanks for being willing to consider this option. Please send me an email at dmanchester@gochronicle.com so we can discuss this further.

tpgalan commented 7 months ago

When I was debugging from @hjam40 repo, I noticed there was no effect on the mediaRecorder.SetVideoFrameRate(30);

What do you mean? You get a different frame rate, although you request 30 fps? Or you get 30 fps anyway, even if you don't specify it?

I never got 30FPS, it's limited by either the simulator or the real device. But I believe the camera itself should "offer" some kind of FPS as presets, so you can select them specifically, since there are specific resolutions and specific FPS (I believe).

Anyway, StartRecordingAsync using these parameters will be great! And even having the resolution as an optional parameter.

An optional resolution parameter already exists, right?

Yes, but there's no good way to check if the desired resolution exists.

janusw commented 7 months ago

PR #11 makes the frameRate and bitRate configurable, but there are no checks (yet) if the chosen values are actually supported (and no way to list supported values or ranges).

janusw commented 7 months ago

Closing (as suggested by @tpgalan).

tpgalan commented 7 months ago

Hi,

I have had enough time to test this. I tested it in a real device, with the following configurations:

CameraResult res = await App.Camera.StartRecordingAsync(RecordingFile, App.SelectedSize,App.FPS, App.Bitrate);

        public const int FPS = 30;
        public const int Bitrate = 1000000;

And

        public const int FPS = 25;
        public const int Bitrate = 1000000;

And

        public const int FPS = 1;
        public const int Bitrate = 1000000;

And

        public const int FPS = 25;
        public const int Bitrate = 100000;

But none of this took effect on the created files: all of them are recorded with around 2.5Mbps of bitrate and 30FPS:

image

I believe this is due to hardware/OS limitations. I mean, I believe the Android device only lets you use some specific set of configurations on FPS and bitrate. That could be listed using the API?

Anyway, I noticed your published version is merged on the hjam40 Nuget package? Is that correct?

image

Thanks