lakeinchina / librestreaming

Android real-time effect filter rtmp streaming library.using Mediacodec HWencoding&librtmp stream.
GNU Lesser General Public License v2.1
942 stars 317 forks source link

Camera preview in the AspectTextureView is stretched #211

Closed jsfan3 closed 4 years ago

jsfan3 commented 4 years ago

Thank you for your so great library! It works fine, my only issue is that the camera preview in the AspectTextureView is stretched.

I suspect that there is something simple in my code that I can fix, but I don't know what is wrong. Could you help me please? To be more clear: if AspectTextureView is square (width = height) the camera preview is correct, instead if AspectTextureView has full screen dimensions the camera preview is stretched. In both cases, however, the live streaming is broadcasted correctly, with the right proportion of width and height.

I tried to change in several ways resConfig.setTargetVideoSize(new Size(720, 480)); and txv_preview.setAspectRatio(AspectTextureView.MODE_FITXY, ((double) s.getWidth()) / s.getHeight()); without solving this issue.

Thank you for your support.

Relevant code:

private AspectTextureView txv_preview = new AspectTextureView(AndroidNativeUtil.getContext());
    private RESClient resClient = new RESClient();
    protected int filtermode = RESConfig.FilterMode.SOFT;
    private RESConfig resConfig = RESConfig.obtain();

    public android.view.View getCameraPreview(String param) {

        if(!AndroidNativeUtil.checkForPermission(Manifest.permission.CAMERA, "Permission required to use live streaming")){
            return null;
        }
        if(!AndroidNativeUtil.checkForPermission(Manifest.permission.RECORD_AUDIO, "Permission required to use live streaming")){
            return null;
        }
        if(!AndroidNativeUtil.checkForPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, "Permission required to use live streaming")){
            return null;
        }

        //txv_preview.setKeepScreenOn(true);
        txv_preview.setSurfaceTextureListener(this);
        resConfig.setFilterMode(filtermode);
        resConfig.setTargetVideoSize(new Size(720, 480));
        resConfig.setBitRate(750 * 1024);
        resConfig.setVideoFPS(20);
        resConfig.setVideoGOP(1);
        resConfig.setRenderingMode(RESConfig.RenderingMode.OpenGLES);
        resConfig.setDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
        int frontDirection, backDirection;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, cameraInfo);
        frontDirection = cameraInfo.orientation;
        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, cameraInfo);
        backDirection = cameraInfo.orientation;
        if (AndroidNativeUtil.getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            resConfig.setFrontCameraDirectionMode((frontDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_270 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_90) | RESConfig.DirectionMode.FLAG_DIRECTION_FLIP_HORIZONTAL);
            resConfig.setBackCameraDirectionMode((backDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_90 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_270));
        } else {
            resConfig.setBackCameraDirectionMode((backDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_0 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_180));
            resConfig.setFrontCameraDirectionMode((frontDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_180 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_0) | RESConfig.DirectionMode.FLAG_DIRECTION_FLIP_HORIZONTAL);
        }
        resConfig.setRtmpAddr(param);
        if (!resClient.prepare(resConfig)) {
            resClient = null;
            Log.p("Prepare failed!", Log.ERROR);
            ToastBar.showErrorMessage( "RESClient prepare failed", 5000);
            return null;
        }
        Size s = resClient.getVideoSize();
        txv_preview.setAspectRatio(AspectTextureView.MODE_FITXY, ((double) s.getWidth()) / s.getHeight());
        Log.p("version = " + resClient.getVertion());
        resClient.setConnectionListener(this);
        resClient.setVideoChangeListener(this);
        resClient.setSoftAudioFilter(new SetVolumeAudioFilter());

        return txv_preview;
    }
lakeinchina commented 4 years ago

This Is weird..any screenshot? Does this issue occur on a specific device?Is the sample working properly? try AspectTextureView.MODE_INSIDE

jsfan3 commented 4 years ago

Thank you for your reply.

I attach two screenshot. The following one is the desired result (obtained by a live streaming from my iPhone device to my Android device):

Instead this one is the stretched camera preview (obtained by a live streaming from my Android device using your library):

Said that, I've already tried AspectTextureView.MODE_INSIDE, but it didn't solve.

Do you know Codename One? https://www.codenameone.com/ I'm using your library inside a Codename One application through a native interface: https://www.codenameone.com/blog/tutorial-native-interfaces.html

lakeinchina commented 4 years ago

if MODE_INSIDE behaves exactly like MODE_FITXY,This may indicate that CodenameOne layout is different from android native layout Process. You can use the official TextureView,then manually adjust the view size to match the video ratio

jsfan3 commented 4 years ago

Thanks for your suggestion. I solved the issue in this way:

  1. In the Java file of Codename One, I made sure that the PeerComponent is always inserted in a Container with 9:16 proportions.

  2. The PeerComponent mentioned in the previous point, returned from the Codename One's native interface, is an instance of AutoFitTextureView, whose source code can be found here: https://github.com/googlearchive/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/AutoFitTextureView.java

  3. In the code reported at the beginning of this thread, I replaced AspectTextureView with AutoFitTextureView

  4. I changed the rendering mode to: resConfig.setRenderingMode(RESConfig.RenderingMode.NativeWindow);

  5. I commented the line resConfig.setTargetVideoSize(new Size(720, 200)); -> In my case this line is not necessary, in fact, with Codename One it creates problems.

Finished, now it works correctly. I also tried streaming from one mobile phone to another and it's fine. Thanks again for this library.