pinkfish / flutter_rtmppublisher

Publisher to rtmp using the camera plugin as a basis to do all the basic camera/record management.
BSD 3-Clause "New" or "Revised" License
95 stars 121 forks source link

Android front facing camera streams upside down in at least some cases #18

Open jmrboosties opened 4 years ago

jmrboosties commented 4 years ago

Hi,

I've successfully implemented this library into a test project. First of all, thanks for making this!

Broadcasting works fine, except there is an issue with the front facing camera, at least on the Android devices I am able to test on. The preview in the app looks correct, however the resulting stream has the front facing camera upside down. I did some digging and found that the issue doesn't stem from your library, but rather Android itself, however I thought it might be worth letting you know to see if we can brainstorm a fix.

Affected devices: Pixel 3a, Pixel 2XL (potentially more?)

The problem derives from an issue in the CameraManager class, part of Android's camera2 API, which this library uses. The CameraCharacteristics you get thinks the orientation of the front facing camera is 180 degrees off of the rear facing camera for some reason. I was able to log it here:

2020-06-29 21:50:24.707 29763-29763/com.example.rtmptest D/===RTMP Test===: name: 0; lens direction: back; orientation: 90
2020-06-29 21:50:24.710 29763-29763/com.example.rtmptest D/===RTMP Test===: name: 1; lens direction: front; orientation: 270

The method you can use to see this is this:

CameraCharacteristics characteristics = manager.getCameraCharacteristics(camera);
int sensorOrientationDegrees = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

Where sensorOrientationDegrees refers to 0, 90, 180, or 270. As you can see in the log above, the front facing camera is inverted (270) compared to the rear (90). What's interesting is that this only happens in portrait mode, in landscape, it works fine:

2020-06-29 21:50:22.152 29763-29763/fitness.classmate.rtmptest D/===RTMP Test===: name: 0; lens direction: back; orientation: 180
2020-06-29 21:50:22.154 29763-29763/fitness.classmate.rtmptest D/===RTMP Test===: name: 1; lens direction: front; orientation: 180

I've dug around for solutions to this but haven't had any luck with what little I've found. The library you derived the Android solution from also faces this same problem, so it's not just you. Given that I can use Hangouts and other video apps on this device without being upside down, I know there is a solution, I just can't find it yet. I just wanted to create this issue here so that others might be able to see that they're not crazy if they run into this wall like I did, and hopefully spark a conversation that can lead to a solution.

Thanks!

pinkfish commented 4 years ago

Ok, now that is a weird problem :). Let me see what I can find out. The android camera2 apis is one of the most frustrating apis I have ever worked with. It fails in the most obscure ways.

I have a pixel 2, not a 3a though.

On Tue, 30 Jun 2020 at 20:33, jmrboosties notifications@github.com wrote:

Hi,

I've successfully implemented this library into a test project. First of all, thanks for making this!

Broadcasting works fine, except there is an issue with the front facing camera, at least on the Android devices I am able to test on. The preview in the app looks correct, however the resulting stream has the front facing camera upside down. I did some digging and found that the issue doesn't stem from your library, but rather Android itself, however I thought it might be worth letting you know to see if we can brainstorm a fix.

Affected devices: Pixel 3a, Pixel 2XL (potentially more?)

The problem derives from an issue in the CameraManager class, part of Android's camera2 API, which this library uses. The CameraCharacteristics you get thinks the orientation of the front facing camera is 180 degrees off of the rear facing camera for some reason. I was able to log it here:

2020-06-29 21:50:24.707 29763-29763/com.example.rtmptest D/===RTMP Test===: name: 0; lens direction: back; orientation: 90

2020-06-29 21:50:24.710 29763-29763/com.example.rtmptest D/===RTMP Test===: name: 1; lens direction: front; orientation: 270

The method you can use to see this is this:

CameraCharacteristics characteristics = manager.getCameraCharacteristics(camera);

int sensorOrientationDegrees = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

Where sensorOrientationDegrees refers to 0, 90, 180, or 270. As you can see in the log above, the front facing camera is inverted (270) compared to the rear (90). What's interesting is that this only happens in portrait mode, in landscape, it works fine:

2020-06-29 21:50:22.152 29763-29763/fitness.classmate.rtmptest D/===RTMP Test===: name: 0; lens direction: back; orientation: 180

2020-06-29 21:50:22.154 29763-29763/fitness.classmate.rtmptest D/===RTMP Test===: name: 1; lens direction: front; orientation: 180

I've dug around for solutions to this but haven't had any luck with what little I've found. The library https://github.com/pedroSG94/rtmp-rtsp-stream-client-java you derived the Android solution from also faces this same problem, so it's not just you. Given that I can use Hangouts and other video apps on this device without being upside down, I know there is a solution, I just can't find it yet. I just wanted to create this issue here so that others might be able to see that they're not crazy if they run into this wall like I did, and hopefully spark a conversation that can lead to a solution.

Thanks!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pinkfish/flutter_rtmppublisher/issues/18, or unsubscribe https://github.com/notifications/unsubscribe-auth/AATOMMMUCMND5VOVKIUFWPLRZKVBRANCNFSM4OM7SFHA .

pinkfish commented 4 years ago

Ok, looking at this there is not much you can do by the looks. It should be putting the metadata into the stream, from what I can tell, giving the rotation. Can you see this in the metadata on the playback side? It might need to do the rotation there. If you use the opengl surface that should rotate for you (at a cost of cpu). Going to check that path now.

jmrboosties commented 4 years ago

I'm not very familiar with m3u8 beyond just consuming it, is there some kind of header that you can use to check rotation on the incoming video?