您的当前位置:首页直播推流 videoCore 实现镜像功能

直播推流 videoCore 实现镜像功能

2024-12-11 来源:哗拓教育

最近两个项目合并,有点混乱,接到一个镜像功能需求,开始以为是把自己的直播镜头翻转就好了,产品文档写的不清楚,浪费了我点时间,后来用了一下其他直播产品,镜像功能是:

镜像实际上直播端自己看自己永远是正的,切换的时候自己的镜头不动,但是观众的镜头看着是反转的。

一.我们推流用的是videoCore 所以冲从这里 入手,在VideoCore/videoCore/sources/iOS/MicSource.mm里面
加了一个属性bool m_bCameraFontFlag; 和一个方法 void setvideoMirrored(bool flag);
加方法作用就是为了让外面可以调用

public:
    /*! Used by Objective-C Capture Session */
    void bufferCaptured(CVPixelBufferRef pixelBufferRef);
    
    /*! Used by Objective-C Device/Interface Orientation Notifications */
    void reorientCamera();
    
    void setvideoMirrored(bool flag);
    

private:
    
    glm::mat4 m_matrix;
    struct { float x, y, w, h, vw, vh, a; } m_size, m_targetSize;
    
    std::weak_ptr<IOutput> m_output;
    
    void* m_captureSession;
    void* m_captureDevice;
    void* m_callbackSession;
    void* m_previewLayer;
    
    int  m_fps;
    bool m_torchOn;
    bool m_useInterfaceOrientation;
    bool m_orientationLocked;
    bool m_bCameraFontFlag;
};

二.然后.mm文件 CameraSource::reorientCamera() 做了如下修改,实际上核心代码就是
av.videoMirrored ,根据正反面和镜像开关设置是否翻转镜头

CameraSource::reorientCamera()
{
if(!m_captureSession) return;

    auto orientation = m_useInterfaceOrientation ? [[UIApplication sharedApplication] statusBarOrientation] : [[UIDevice currentDevice] orientation];
    
    // use interface orientation as fallback if device orientation is facedown, faceup or unknown
    if(orientation==UIDeviceOrientationFaceDown || orientation==UIDeviceOrientationFaceUp || orientation==UIDeviceOrientationUnknown) {
        orientation =[[UIApplication sharedApplication] statusBarOrientation];
    }
    
    //bool reorient = false;
    
    AVCaptureSession* session = (AVCaptureSession*)m_captureSession;
    // [session beginConfiguration];
    
    AVCaptureDevice *device = (AVCaptureDevice*)m_captureDevice;
    for (AVCaptureVideoDataOutput* output in session.outputs) {
        for (AVCaptureConnection * av in output.connections) {
            if(([device position] == AVCaptureDevicePositionFront)){
                //正
                if (m_bCameraFontFlag) {
                    av.videoMirrored = YES;
                }else{
                    av.videoMirrored = NO;
                }
            }else{
                //反
                av.videoMirrored = NO;
            }

            //---front capture mirror----

// av.videoMirrored = ([device position] == AVCaptureDevicePositionFront);
switch (orientation) {
// UIInterfaceOrientationPortraitUpsideDown, UIDeviceOrientationPortraitUpsideDown
case UIInterfaceOrientationPortraitUpsideDown:
if(av.videoOrientation != AVCaptureVideoOrientationPortraitUpsideDown) {
av.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
// reorient = true;
}
break;
// UIInterfaceOrientationLandscapeRight, UIDeviceOrientationLandscapeLeft
case UIInterfaceOrientationLandscapeRight:
if(av.videoOrientation != AVCaptureVideoOrientationLandscapeRight) {
av.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
// reorient = true;
}
break;
// UIInterfaceOrientationLandscapeLeft, UIDeviceOrientationLandscapeRight
case UIInterfaceOrientationLandscapeLeft:
if(av.videoOrientation != AVCaptureVideoOrientationLandscapeLeft) {
av.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
// reorient = true;
}
break;
// UIInterfaceOrientationPortrait, UIDeviceOrientationPortrait
case UIInterfaceOrientationPortrait:
if(av.videoOrientation != AVCaptureVideoOrientationPortrait) {
av.videoOrientation = AVCaptureVideoOrientationPortrait;
// reorient = true;
}
break;
default:
break;
}
}
}

    //[session commitConfiguration];
    if(m_torchOn) {
        setTorch(m_torchOn);
    }
}

三.就是直播端自己的预览画面了,自己的画面根据设置的镜像做相应的翻转,让自己看自己一直处于正面
if([weakself.publisher cameraStateIsFront]){
weakself.publisher.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
}else{
weakself.publisher.view.transform = CGAffineTransformMakeScale(-1.0, 1.0);
}

显示全文