EasyRTC EasyPusher 推送 视频画面旋转90度问题

今天用EasyRTC做了视频推拉流的应用,EasyRTC是横屏的,但是我需要做成竖屏的(类似微信视频那种的)。

旋转过来后,预览界面和播放界面的视频都是旋转了90度,顿时郁闷了。

经过一番资料查阅跟EasyPusher的源码分析,最后解决了这个头疼的问题。


首先我把预览界面的视频修改了,关键代码如下:


            if (Camera.getNumberOfCameras() < 2){
                mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
            }
            mCamera = Camera.open(mCameraId);

            Camera.Parameters parameters = mCamera.getParameters();
            int[] max = determineMaximumSupportedFramerate(parameters);
            Camera.CameraInfo camInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(mCameraId, camInfo);
            int cameraRotationOffset = camInfo.orientation;
            if (mCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT)
                cameraRotationOffset += 180;
            int rotate = (360 + cameraRotationOffset - mDgree) % 360;
            parameters.setRotation(rotate);
            previewFormat = colorFormat == COLOR_FormatYUV420SemiPlanar || colorFormat == COLOR_TI_FormatYUV420PackedSemiPlanar ? ImageFormat.NV21 : ImageFormat.YV12;
            parameters.setPreviewFormat(previewFormat);
            parameters.setPreviewSize(width, height);
            parameters.setPreviewFrameRate(20);
            mCamera.setParameters(parameters);
            //计算preview画面需要旋转的角度。目前木有做横竖屏切换的时候无缝旋转画面,后面再搞。
            int  displayRotation = (cameraRotationOffset - mDgree + 360) % 360;
            mCamera.setDisplayOrientation(displayRotation);//摄像图旋转90度---90
            SurfaceHolder holder = mSurfaceHolderRef.get();
            if (holder != null) {
                mCamera.setPreviewDisplay(holder);
            }

mCamera.setDisplayOrientation(displayRotation);//摄像图旋转90度---90


关键是这行代码,这种摄像头旋转90度


首选我查找到比较有用的资料 :http://blog.csdn.net/holo_easydarwin/article/details/51147379


按照这篇博客的说明,发现不仅没有将推送的视频流选择到90度,还导致了,推送出来的流出现重影




而且方向还是不对。


博客中的主要代码如下:


MediaFormat mediaFormat;
        if (mDgree == 0) {
            //dree==0的时候,需要将画面旋转90度,所以这里编码的时候需要将宽和高颠倒,
            //否则编码后的会面会出现四重画面并且花屏
            mediaFormat = MediaFormat.createVideoFormat("video/avc", height, width);
        } else {
            mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
        }



【这里我没有保留截图,就使用上篇博客的图(各位看官息怒)】


然后我就感觉不对了,然后去查阅EasyPusher的源码,因为EasyPusher 推送的视频流是正常的。经过一番查阅之后终于找到线索,在一番测试之后,解决了这个视频旋转的问题。


关键代码如下:


    Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {

        Camera.Size previewSize;
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if (data == null) {
                return;
            }
            if (previewSize == null){
                previewSize  = mCamera.getParameters().getPreviewSize();
            }
            int bufferIndex;
            do {

//                JNIUtil.nV21To420SP(data, previewSize.width, previewSize.height);

                if (mDgree == 0) {
                    Camera.CameraInfo camInfo = new Camera.CameraInfo();
                    Camera.getCameraInfo(mCameraId, camInfo);
                    int cameraRotationOffset = camInfo.orientation;
                    LogUtil.i("=====================PreviewCallback----onPreviewFrame ---cameraRotationOffset= " + cameraRotationOffset);
                    if (cameraRotationOffset % 180 != 0) {
                        if (previewFormat == ImageFormat.YV12) {
                            yuvRotate(data, 0, width, height, cameraRotationOffset);
                        } else {
                            yuvRotate(data, 1, width, height, cameraRotationOffset);
                        }
                    }
                    save2file(data, String.format("/sdcard/yuv_%d_%d.yuv", height, width));
                }

                JNIUtil.nV21To420SP(data, previewSize.width, previewSize.height);

                bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
                if (bufferIndex >= 0) {
                    inputBuffers[bufferIndex].clear();
                    inputBuffers[bufferIndex].put(data);
                    mMediaCodec.queueInputBuffer(bufferIndex, 0, inputBuffers[bufferIndex].position(), System.nanoTime() / 1000 , 0);
                } else {
                    Log.e(TAG, "No buffer available !");
                }
            } while (bufferIndex < 0 && mConsumer != null);
            mCamera.addCallbackBuffer(data);
        }

    };

    /**
     * 旋转YUV格式数据
     *
     * @param src    YUV数据
     * @param format 0,420P;1,420SP
     * @param width  宽度
     * @param height 高度
     * @param degree 旋转度数
     */
    private static void yuvRotate(byte[] src, int format, int width, int height, int degree) {
        int offset = 0;
        if (format == 0) {
            JNIUtil.rotateMatrix(src, offset, width, height, degree);
            offset += (width * height);
            JNIUtil.rotateMatrix(src, offset, width / 2, height / 2, degree);
            offset += width * height / 4;
            JNIUtil.rotateMatrix(src, offset, width / 2, height / 2, degree);
        } else if (format == 1) {
            JNIUtil.rotateMatrix(src, offset, width, height, degree);
            offset += width * height;
            JNIUtil.rotateShortMatrix(src, offset, width / 2, height / 2, degree);
        }
    }




如图上面标红的地方,这个是EasyPusher的源码,查看注释可以知道,这个方法是可以旋转视频角度的。加上这些代码,就开始测试了,发现视频都角度都正常了,也没有出现重影的问题了。


但是有个更蛋疼的问题,就是视频中人物的脸都是绿的 、 绿的 、 绿的。。。。。

这个不能接受, 

然后我又把之前的一个方法加上,就完美了


JNIUtil.nV21To420SP(data, previewSize.width, previewSize.height);

这个方法是本身自带的,我刚开始给去掉了。 






©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页